├── README
├── Rakefile
├── generators
└── deploy_configs
│ ├── deploy_configs_generator.rb
│ └── templates
│ ├── httpd.conf
│ └── logrotate
├── init.rb
├── install.rb
├── lib
├── awesomeness.rb
└── awesomeness
│ ├── core_ext
│ ├── array.rb
│ ├── enumerable.rb
│ ├── float.rb
│ ├── hash.rb
│ ├── object.rb
│ ├── range.rb
│ └── string.rb
│ ├── text_helper.rb
│ └── trailing_slash.rb
├── recipes
├── awesomeness.rb
└── awesomeness
│ ├── apache.rb
│ ├── assets.rb
│ ├── ferret.rb
│ ├── logs.rb
│ └── mongrel.rb
├── tasks
└── awesomeness.rake
└── test
├── core_ext
├── array_test.rb
└── enumerable_test.rb
├── test_helper.rb
├── text_helper_test.rb
└── trailing_slash_test.rb
/README:
--------------------------------------------------------------------------------
1 | Collective Idea's Awesomeness
2 | =============================
3 |
4 | A collection of stuff that we use often, but not generic enough to go in another plugin.
5 |
6 | If you've stumbled across this and love/hate it, let us know!
7 |
8 | == Compatability
9 |
10 | This plugin is compatible with edge-rails that is slated to be Rails 2.2. For a version compatible with 2.1, check out the "rails-2.1" tag from git.
11 |
12 | == Core Extensions
13 |
14 | * Object#tap (http://moonbase.rydia.net/mental/blog/programming/eavesdropping-on-expressions)
15 |
16 | * String#widont to make typography nicer (http://shauninman.com/archive/2006/08/22/widont_wordpress_plugin)
17 |
18 | * Array#uniq with a block
19 |
20 | >> %w(the cow jumped over the moon).uniq {|s| s.length }
21 | => ["the", "jumped", "over"]
22 |
23 | * Round floats to the nearest x
24 |
25 | >> 5.38475.round(0.5)
26 | => 5.5
27 |
28 | * Hash goodies
29 |
30 | >> {:a => [1,3,4], :b => [2,5]}.without(:a => 1)
31 | => {:a => [3,4], :b => [2,5]}
32 |
33 | >> {:a => "", :b => nil, :c => 1}.compact
34 | => {:c => 1}
35 |
36 | * And more…
37 |
38 | == Rails Helpers
39 |
40 | * Unicode TextHelper additions that change the default truncate & excerpt string to an elipsis (…) instead of just three periods (...)
41 |
42 | * Add widont to textilize methods
43 |
44 | * Transparent removal of trailing slashes in URLs
45 |
46 | == Rake Tasks
47 |
48 | == Capistrano Recipes
49 |
50 | * Use :remote_cache by default
51 |
52 | * Disable and enable web during restarts
53 |
54 | * Run deploy:cleanup after deploys
55 |
56 | * Backups
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rake'
2 | require 'rake/testtask'
3 | require 'rake/rdoctask'
4 |
5 | desc 'Default: run unit tests.'
6 | task :default => :test
7 |
8 | desc 'Test the awesomeness plugin.'
9 | Rake::TestTask.new(:test) do |t|
10 | t.libs << 'lib'
11 | t.pattern = 'test/**/*_test.rb'
12 | t.verbose = true
13 | end
14 |
15 | desc 'Generate documentation for the awesomeness plugin.'
16 | Rake::RDocTask.new(:rdoc) do |rdoc|
17 | rdoc.rdoc_dir = 'rdoc'
18 | rdoc.title = 'Awesomeness'
19 | rdoc.options << '--line-numbers' << '--inline-source'
20 | rdoc.rdoc_files.include('README')
21 | rdoc.rdoc_files.include('lib/**/*.rb')
22 | end
--------------------------------------------------------------------------------
/generators/deploy_configs/deploy_configs_generator.rb:
--------------------------------------------------------------------------------
1 | require 'capistrano'
2 | require 'capistrano/cli'
3 |
4 | # TODO: error handling. Check if Cap config doesn't exist
5 | class DeployConfigsGenerator < Rails::Generator::Base
6 | default_options :ports => "8000,8001,8002"
7 | attr_reader :config
8 |
9 | def initialize(runtime_args, runtime_options = {})
10 | super
11 | options[:ports] = options[:ports].split(',')
12 | assign_capistrano_config!
13 | end
14 |
15 | def manifest
16 | record do |m|
17 | m.directory "config"
18 | m.template "logrotate", File.join("config", "logrotate")
19 | m.template "httpd.conf", File.join("config", "httpd.conf")
20 | end
21 | end
22 |
23 | private
24 |
25 | def assign_capistrano_config!
26 | @config = Capistrano::Configuration.new
27 | @config.load Capistrano::CLI::DEFAULT_RECIPES.select {|file| File.exist?(File.join(RAILS_ROOT, file)) }
28 | end
29 |
30 | def add_options!(opt)
31 | opt.separator ''
32 | opt.separator 'Options:'
33 | opt.on("--ports ports", "Ports to run mongrel on") do |v|
34 | options[:ports] = v
35 | end
36 | end
37 |
38 | end
39 |
--------------------------------------------------------------------------------
/generators/deploy_configs/templates/httpd.conf:
--------------------------------------------------------------------------------
1 | >
2 | <% options[:ports].each do |port| -%>
3 | BalancerMember http://127.0.0.1:<%= port %>
4 | <% end -%>
5 |
6 |
7 | RewriteEngine On
8 |
9 | # Uncomment for rewrite debugging
10 | #RewriteLog logs/your_app_rewrite_log
11 | #RewriteLogLevel 9
12 |
13 | # Check for maintenance file and redirect all requests
14 | RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
15 | RewriteCond %{SCRIPT_FILENAME} !maintenance.html
16 | RewriteRule ^.*$ /system/maintenance.html [L]
17 |
18 | # Rewrite index to check for static
19 | RewriteRule ^/$ /index.html [QSA]
20 |
21 | # Rewrite to check for Rails cached page
22 | RewriteRule ^([^.]+)$ $1.html [QSA]
23 |
24 | # Redirect all non-static requests to cluster
25 | RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
26 | RewriteRule ^/(.*)$ balancer://<%= config.application %>%{REQUEST_URI} [P,QSA,L]
27 |
28 | # Deflate
29 | AddOutputFilterByType DEFLATE text/html text/plain text/xml
30 | BrowserMatch ^Mozilla/4 gzip-only-text/html
31 | BrowserMatch ^Mozilla/4\.0[678] no-gzip
32 | BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
33 |
34 | # Uncomment for deflate debugging
35 | #DeflateFilterNote Input input_info
36 | #DeflateFilterNote Output output_info
37 | #DeflateFilterNote Ratio ratio_info
38 | #LogFormat '"%r" %{output_info}n/%{input_info}n (%{ratio_info}n%%)' deflate
39 | #CustomLog logs/your_app_deflate_log deflate
40 |
41 | #ErrorLog logs/your_app_error_log
42 | #CustomLog logs/your_access_log combined
--------------------------------------------------------------------------------
/generators/deploy_configs/templates/logrotate:
--------------------------------------------------------------------------------
1 | <%= config.shared_path %>/log/*log {
2 | daily
3 | rotate 7
4 | compress
5 | missingok
6 | notifempty
7 | sharedscripts
8 | postrotate
9 | for i in `ls <%= config.shared_path %>/log/*.pid`; do
10 | kill -USR2 `cat $i`
11 | done
12 | endscript
13 | }
--------------------------------------------------------------------------------
/init.rb:
--------------------------------------------------------------------------------
1 | require 'awesomeness'
2 |
--------------------------------------------------------------------------------
/install.rb:
--------------------------------------------------------------------------------
1 | puts IO.read(File.join(File.dirname(__FILE__), 'README'))
2 |
--------------------------------------------------------------------------------
/lib/awesomeness.rb:
--------------------------------------------------------------------------------
1 | Dir[File.dirname(__FILE__) + "/awesomeness/**/*.rb"].each {|f| require f }
2 |
3 | # From: http://weblog.jamisbuck.org/2007/1/31/more-on-watching-activerecord
4 | # Easy way to view logs in script/console.
5 | # simply type: log_to(STDOUT)
6 | # and all of your active record queries will show up inline.
7 | def log_to(stream = STDOUT)
8 | ActiveRecord::Base.logger = Logger.new(stream)
9 | ActiveRecord::Base.clear_active_connections!
10 | end
--------------------------------------------------------------------------------
/lib/awesomeness/core_ext/array.rb:
--------------------------------------------------------------------------------
1 | class Array
2 |
3 | def randomize(limit = length)
4 | choices = dup
5 | returning([]) do |result|
6 | [limit, length].min.times do
7 | result << choices.delete_at(Kernel.rand(choices.length))
8 | end
9 | end.compact
10 | end
11 |
12 | def uniq_with_block!(&block)
13 | uniq_without_block!
14 | if block_given?
15 | grouped = group_by(&block)
16 | grouped.each do |key,duplicates|
17 | delete_at(index(duplicates.pop)) while duplicates.size > 1
18 | end
19 | end
20 | self
21 | end
22 | alias_method_chain :uniq!, :block
23 |
24 | def uniq_with_block(&block)
25 | dup.uniq!(&block)
26 | end
27 | alias_method_chain :uniq, :block
28 |
29 | def pad(pad_to_length, padding = nil)
30 | dup.pad! pad_to_length, padding
31 | end
32 |
33 | def pad!(pad_to_length, padding = nil)
34 | self << padding while pad_to_length > length
35 | self
36 | end
37 |
38 | end
39 |
--------------------------------------------------------------------------------
/lib/awesomeness/core_ext/enumerable.rb:
--------------------------------------------------------------------------------
1 | module Enumerable
2 |
3 | # Divide into groups
4 | def chunk(number_of_chunks, padding = false)
5 | chunk_size = (size.to_f / number_of_chunks).ceil
6 | chunk_size = 1 if chunk_size < 1
7 | returning enum_for(:each_slice, chunk_size).to_a do |result|
8 | result << [] while result.length < number_of_chunks
9 | result.last.pad!(result.first.length, padding) unless padding == false
10 | end
11 | end
12 | alias / chunk
13 |
14 | end
--------------------------------------------------------------------------------
/lib/awesomeness/core_ext/float.rb:
--------------------------------------------------------------------------------
1 | class Float
2 | def round(round_to = 1.0)
3 | mod = self % round_to
4 | rounded = self - mod + (mod >= round_to/2.0 ? round_to : 0)
5 | rounded % 1 == 0 ? rounded.to_i : rounded
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/lib/awesomeness/core_ext/hash.rb:
--------------------------------------------------------------------------------
1 | class Hash
2 | # Usage {:a => [1,3,4], :b => [2,5]}.without(:a => 1)
3 | # returns {:a => [3,4], :b => [2,5]}
4 | def without(hash)
5 | hash = hash.with_indifferent_access if self.instance_of?(HashWithIndifferentAccess)
6 | # create a new hash using this class, so we get a new HashWithIndifferentAccess if this is one
7 | inject(self.class.new) do |result,(k,v)|
8 | result[k] = (hash[k] && v.respond_to?(:reject) ? v.reject {|v,_| v == hash[k] } : v)
9 | result
10 | end
11 | end
12 |
13 | def compact!
14 | delete_if { |k,v| v.blank? }
15 | end
16 |
17 | def compact
18 | dup.compact!
19 | end
20 | end
--------------------------------------------------------------------------------
/lib/awesomeness/core_ext/object.rb:
--------------------------------------------------------------------------------
1 | class Object
2 | # See http://moonbase.rydia.net/mental/blog/programming/eavesdropping-on-expressions
3 | # Will be added in Ruby 1.9
4 | def tap
5 | yield self
6 | self
7 | end if RUBY_VERSION < '1.9'
8 | end
--------------------------------------------------------------------------------
/lib/awesomeness/core_ext/range.rb:
--------------------------------------------------------------------------------
1 | class Range
2 |
3 | def include_with_range?(value)
4 | if value.is_a?(Range)
5 | self.first <= value.first &&
6 | (self.exclude_end? && !value.exclude_end? ?
7 | self.last > value.last :
8 | self.last >= value.last)
9 | else
10 | include_without_range?(value)
11 | end
12 | end unless defined?(ActiveSupport::CoreExtensions::Range::IncludeRange)
13 | alias_method_chain(:include?, :range) unless defined?(ActiveSupport::CoreExtensions::Range::IncludeRange)
14 |
15 | def overlap?(range)
16 | self.include?(range.first) ||
17 | self.include?(range.exclude_end? ? range.last - 1 : range.last)
18 | end
19 |
20 | alias_method :original_step, :step
21 | def step(value = 1, &block)
22 | if block_given?
23 | original_step(value, &block)
24 | else
25 | returning [] do |array|
26 | original_step(value) {|step| array << step }
27 | end
28 | end
29 | end
30 |
31 | end
--------------------------------------------------------------------------------
/lib/awesomeness/core_ext/string.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | class String
3 | # Widon't
4 | # Based on the original by Shaun Inman: http://shauninman.com/archive/2006/08/22/widont_wordpress_plugin
5 | # And the Ruby versions here: http://mucur.name/posts/widon-t-helper-for-rails-2
6 | # This version replaces with a unicode non-breaking space (option-space on a Mac)
7 | def widont
8 | self.gsub(/([^\s])\s+([^\s]+)(\s*)$/, '\1 \2\3')
9 | end
10 |
11 | def mb_chars
12 | chars
13 | end unless ''.respond_to?(:mb_chars)
14 | end
--------------------------------------------------------------------------------
/lib/awesomeness/text_helper.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | module ActionView
3 | module Helpers
4 | module TextHelper
5 | # Awesome truncate
6 | # First regex truncates to the length, plus the rest of that word, if any.
7 | # Second regex removes any trailing whitespace or punctuation (except ;).
8 | # Unlike the regular truncate method, this avoids the problem with cutting
9 | # in the middle of an entity ex.: truncate("this & that",9) => "this &am..."
10 | # though it will not be the exact length.
11 | def awesome_truncate(text, length = 30, truncate_string = "…")
12 | return if text.nil?
13 | l = length - truncate_string.mb_chars.length
14 | text.mb_chars.length > length ? text[/\A.{#{l}}\w*\;?/m][/.*[\w\;]/m] + truncate_string : text
15 | end
16 |
17 | def truncate_with_title(text, length = 30, truncate_string = "…")
18 | if text.mb_chars.length > length
19 | content_tag :span, truncate(text), :title => text
20 | else
21 | text
22 | end
23 | end
24 |
25 | # Better versions of standard truncate and excerpt
26 | def truncate_with_better_default(text, options)
27 | options = {:length => 30, :truncate_string => "…"}.merge(options)
28 | truncate_without_better_default(text, options)
29 | end
30 | alias_method_chain :truncate, :better_default
31 |
32 | def excerpt_with_better_default(text, phrase, options)
33 | options = {radius => 100, excerpt_string => "…"}.merge(options)
34 | excerpt_without_better_default(text, phrase, options)
35 | end
36 | alias_method_chain :excerpt, :better_default
37 |
38 | # Widon't
39 | # We use this method instead of String#widont directly because textilize is often called with nil.
40 | # This duplicates textilize's solution of returning the empty string if blank.
41 | def widont(text)
42 | text.blank? ? '' : text.widont
43 | end
44 |
45 | def textilize_with_widont(text)
46 | textilize_without_widont widont(text)
47 | end
48 | alias_method_chain :textilize, :widont
49 |
50 | def textilize_without_paragraph_with_widont(text)
51 | textilize_without_paragraph_without_widont widont(text)
52 | end
53 | alias_method_chain :textilize_without_paragraph, :widont
54 |
55 | # Inserts a unicode non-breaking space character ' '
56 | # since shouldn't be used in proper XHTML
57 | def nbsp
58 | ' '
59 | end
60 | end
61 | end
62 | end
--------------------------------------------------------------------------------
/lib/awesomeness/trailing_slash.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Disambiguate URLs by removing trailing slashes
3 | # Idea from http://fleetingideas.com/post/6539239
4 | # This version works with query strings.
5 | module CollectiveIdea #:nodoc:
6 | module ActionController
7 | module TrailingSlash #:nodoc:
8 | def self.included(base) #:nodoc:
9 | base.before_filter :remove_trailing_slash
10 | base.send :include, InstanceMethods
11 | end
12 |
13 | module InstanceMethods
14 | private
15 | def remove_trailing_slash
16 | request_uri = remove_trailing_slash_from(request.request_uri)
17 | if request.request_uri.length > 1 && request.request_uri != request_uri
18 | headers['Status'] = '301 Moved Permanently'
19 | redirect_to request.protocol + request.host_with_port + request_uri and return false
20 | end
21 | end
22 |
23 | def remove_trailing_slash_from(uri)
24 | uri.split('?').each{|s| s.sub!(/\/$/, '')}.join('?').sub!(/\A^\/?/, '/\1')
25 | #uri.sub(/\/(^\?*)?(\?.+)?\/?$/, '/\1\2')#.sub(/\/+/, '/')
26 | end
27 | end
28 | end
29 | end
30 | end
31 |
32 | ActionController::Base.send :include, CollectiveIdea::ActionController::TrailingSlash
33 |
--------------------------------------------------------------------------------
/recipes/awesomeness.rb:
--------------------------------------------------------------------------------
1 | # load 'awesomeness'
2 | #
3 | # A collection of commonly-used (yet, non-intrusive) Capistrano tasks at Collective Idea.
4 | #
5 |
6 | load_paths.unshift File.expand_path(File.dirname(__FILE__))
7 |
8 | # don't do a fresh checkout, just svn update
9 | set :deploy_via, :remote_cache
10 |
11 | after "deploy:update_code", "deploy:web:disable"
12 | before "deploy:stop", "deploy:web:disable"
13 | before "deploy:restart", "deploy:web:disable"
14 | after "deploy:restart", "deploy:web:enable"
15 | after "deploy:start", "deploy:web:enable"
16 |
17 | after "deploy", "deploy:cleanup"
18 | after "deploy:migrations", "deploy:cleanup"
19 |
--------------------------------------------------------------------------------
/recipes/awesomeness/apache.rb:
--------------------------------------------------------------------------------
1 | namespace :deploy do
2 | namespace :apache do
3 | desc "Start Apache"
4 | task :start, :roles => :web do
5 | sudo "/etc/init.d/httpd start > /dev/null"
6 | end
7 |
8 | desc "Stop Apache"
9 | task :stop, :roles => :web do
10 | sudo "/etc/init.d/httpd stop > /dev/null"
11 | end
12 |
13 | desc "Restart Apache"
14 | task :restart, :roles => :web do
15 | sudo "/etc/init.d/httpd restart > /dev/null"
16 | end
17 |
18 | desc "Reload Apache"
19 | task :reload, :roles => :web do
20 | sudo "/etc/init.d/httpd reload > /dev/null"
21 | end
22 | end
23 | end
--------------------------------------------------------------------------------
/recipes/awesomeness/assets.rb:
--------------------------------------------------------------------------------
1 | _cset(:assets) { abort "Please specify assets, set :assets, %w(foo bar)" }
2 |
3 | after "deploy:setup", "assets:setup"
4 | after "deploy:update_code", "assets:symlink"
5 |
6 | namespace :assets do
7 | def asset_dirs
8 | fetch(:assets).map {|dir| File.join(shared_path, 'assets', dir) }
9 | end
10 |
11 | task :setup, :role => :app do
12 | run "umask 02 && mkdir -p #{asset_dirs.join(' ')}"
13 | end
14 |
15 | task :symlink, :role => :app do
16 | setup
17 | fetch(:assets).each do |asset|
18 | run "rm -f #{release_path}/public/#{asset}"
19 | run "ln -s #{shared_path}/assets/#{asset} #{release_path}/public/#{asset}"
20 | end
21 | end
22 |
23 | # FIXME: this is brittle
24 | task :backup, :role => :app do
25 | backup_dir = File.expand_path(File.dirname(__FILE__) + '/../../../../public/')
26 | puts "backing up remote assets to #{backup_dir}"
27 | puts `rsync -e ssh -qr --delete #{user}@#{roles[:app][0].host}:#{shared_path}/assets/* #{backup_dir}`
28 | end
29 |
30 | end
--------------------------------------------------------------------------------
/recipes/awesomeness/ferret.rb:
--------------------------------------------------------------------------------
1 |
2 | before 'deploy:start', 'deploy:ferret:start'
3 | before 'deploy:stop', 'deploy:ferret:stop'
4 | before 'deploy:restart', 'deploy:ferret:restart'
5 | namespace :deploy do
6 | namespace :ferret do
7 | desc "Start the ferret server"
8 | task :start do
9 | run "cd #{current_path}; script/ferret_server -e #{fetch(:rails_env, 'production')} start"
10 | end
11 |
12 | desc "Stop the ferret server"
13 | task :stop do
14 | run "cd #{current_path}; script/ferret_server -e #{fetch(:rails_env, 'production')} stop"
15 | end
16 |
17 | desc "Restart the ferret server"
18 | task :restart do
19 | stop
20 | start
21 | end
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/recipes/awesomeness/logs.rb:
--------------------------------------------------------------------------------
1 | namespace :logs do
2 | desc "tail production log files"
3 | task :tail, :roles => :app do
4 | run "tail -f #{shared_path}/log/production.log" do |channel, stream, data|
5 | puts # for an extra line break before the host name
6 | puts "#{channel[:host]}: #{data}"
7 | break if stream == :err
8 | end
9 | end
10 |
11 | desc "Backup the remote production log"
12 | task :backup, :roles => :app do
13 | dir = File.expand_path(File.dirname(__FILE__) + '/../../../../backups')
14 | filename = "#{application}.#{Time.now.to_i}.production.log"
15 | `mkdir -p #{dir}`
16 | get "#{shared_path}/log/production.log", "#{dir}/#{filename}"
17 | end
18 |
19 |
20 | desc "check production log files in textmate(tm)"
21 | task :mate, :roles => :app do
22 | require 'tempfile'
23 | tmp = Tempfile.open('w')
24 | logs = Hash.new { |h,k| h[k] = '' }
25 |
26 | run "tail -n500 #{shared_path}/log/production.log" do |channel, stream, data|
27 | logs[channel[:host]] << data
28 | break if stream == :err
29 | end
30 |
31 | logs.each do |host, log|
32 | tmp.write("--- #{host} ---\n\n")
33 | tmp.write(log + "\n")
34 | end
35 |
36 | exec "mate -w #{tmp.path}"
37 | tmp.close
38 | end
39 | end
--------------------------------------------------------------------------------
/recipes/awesomeness/mongrel.rb:
--------------------------------------------------------------------------------
1 | # Deprecated. The functionality is now in mongrel_cluster for Cap 2
2 | require 'mongrel_cluster/recipes'
--------------------------------------------------------------------------------
/tasks/awesomeness.rake:
--------------------------------------------------------------------------------
1 | desc "Run migrations and prepare the test database"
2 | task :db => ['db:migrate', 'db:test:prepare']
--------------------------------------------------------------------------------
/test/core_ext/array_test.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + '/../test_helper'
2 | require 'awesomeness/core_ext/array'
3 |
4 | class ArrayTest < Test::Unit::TestCase
5 |
6 | def test_pad
7 | a = [1,2,3]
8 | assert_equal [1,2,3,nil,nil], a.pad(5)
9 | end
10 |
11 | def test_pad_does_not_exceed_length
12 | a = [1,2,3]
13 | assert_equal a, a.pad(2)
14 | assert_equal a, a.pad(3)
15 | end
16 |
17 | def test_pad_with_custom_padding
18 | a = [1,2,3]
19 | assert_equal [1,2,3,'foo'], a.pad(4, 'foo')
20 | end
21 |
22 | def test_pad_does_not_modify_original
23 | a = [1,2,3]
24 | a.pad(4)
25 | assert_equal 3, a.length
26 | end
27 |
28 | def test_pad_does_not_modify_original
29 | a = [1,2,3]
30 | a.pad(4)
31 | assert_equal 3, a.length
32 | end
33 |
34 | def test_pad!
35 | a = [1,2,3]
36 | a.pad!(4, 'x')
37 | assert_equal [1,2,3,'x'], a
38 | end
39 |
40 | def test_randomize_length
41 | assert_equal 4, (1..10).to_a.randomize(4).length
42 | end
43 |
44 | def test_randomize_with_fewer_options
45 | a = [1,2,3]
46 | assert_equal 3, a.randomize(10).length
47 | end
48 | end
--------------------------------------------------------------------------------
/test/core_ext/enumerable_test.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + '/../test_helper'
2 | require 'awesomeness/core_ext/array'
3 | require 'awesomeness/core_ext/enumerable'
4 |
5 | class EnumerableTest < Test::Unit::TestCase
6 |
7 | def test_chunk_evenly
8 | assert_equal [[1], [2], [3]], [1, 2, 3].chunk(3)
9 | end
10 |
11 | def test_divide_evenly
12 | assert_equal [[1], [2], [3]], [1, 2, 3] / 3
13 | assert_equal [[1, 2], [3, 4], [5, 6]], [1, 2, 3, 4, 5, 6].chunk(3)
14 | assert_equal [[1,2,3,4,5],[6,7,8,9,10]], ((1..10).to_a / 2)
15 | end
16 |
17 | def test_chunk_unevenly
18 | assert_equal [[1, 2], [3]], [1, 2, 3].chunk(2)
19 | assert_equal [[1,2,3,4,5,6,7],[8,9,10,11,12,13]], ((1..13).to_a / 2)
20 | assert_equal [[1,2,3,4],[5,6,7,8],[9,10]], ((1..10).to_a / 3)
21 | end
22 |
23 | def test_chunk_fills_with_empty_arrays
24 | assert_equal [[1], [], []], [1].chunk(3)
25 | end
26 |
27 | def test_chunking_does_not_modify_original
28 | array = [1, 2, 3]
29 | assert_equal 3, array.length
30 | assert_equal [[1], [2], [3]], array.chunk(3)
31 | assert_equal 3, array.length
32 | end
33 |
34 | def test_chunk_unevenly_with_padding
35 | assert_equal [[1, 2], [3, nil]], [1, 2, 3].chunk(2, nil)
36 | assert_equal [[1,2,3,4,5,6,7],[8,9,10,11,12,13, 'foo']], ((1..13).to_a.chunk(2, 'foo'))
37 | end
38 |
39 | def test_divide_by_zero
40 | assert_equal [[],[]], [].chunk(2)
41 | end
42 |
43 | end
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | $: << File.expand_path(File.dirname(__FILE__) + '/../lib')
2 |
3 | require 'rubygems'
4 | require 'test/unit'
5 | require 'active_support'
--------------------------------------------------------------------------------
/test/text_helper_test.rb:
--------------------------------------------------------------------------------
1 | require 'test/unit'
2 | require 'rubygems'
3 | require 'action_view'
4 | require File.join(File.dirname(__FILE__), '..', 'lib', 'awesomeness', 'text_helper')
5 |
6 |
7 | class TextHelperTest < Test::Unit::TestCase
8 | include ActionView::Helpers::TextHelper
9 |
10 | def test_awesome_truncate_with_nil
11 | assert_nil awesome_truncate(nil)
12 | end
13 |
14 | def test_awesome_truncate_with_blank
15 | assert_equal '', awesome_truncate('')
16 | end
17 |
18 | def test_awesome_truncate
19 | assert_equal 'foo...', awesome_truncate('foo bar baz', 5, '...')
20 | end
21 |
22 | def test_awesome_truncate_with_sentence
23 | assert_equal 'foo bar...', awesome_truncate('foo bar. baz', 8, '...')
24 | end
25 |
26 | # TODO: this would be sweet
27 | # def test_awesome_truncate_with_html
28 | # assert_equal 'foo...', awesome_truncate('foo
', 8, '...')
29 | # end
30 | end
--------------------------------------------------------------------------------
/test/trailing_slash_test.rb:
--------------------------------------------------------------------------------
1 | require 'test/unit'
2 | module ActionController
3 | class AbstractRequest
4 | end
5 | end
6 | require File.join(File.dirname(__FILE__), '..', 'lib', 'awesomeness', 'trailing_slash')
7 |
8 |
9 | class TrailingSlashTest < Test::Unit::TestCase
10 | include CollectiveIdea::ActionController::TrailingSlash::InstanceMethods
11 |
12 | def test_remove_without_querystring_1
13 | assert_equal '/foo', remove_trailing_slash_from('/foo/')
14 | end
15 | def test_remove_without_querystring_2
16 | assert_equal '/foo/bar', remove_trailing_slash_from('/foo/bar/')
17 | end
18 | def test_remove_without_querystring_3
19 | assert_equal '/foo/bar/baz', remove_trailing_slash_from('/foo/bar/baz/')
20 | end
21 | def test_remove_without_querystring_4
22 | assert_equal '/foo/bar/baz.html', remove_trailing_slash_from('/foo/bar/baz.html/')
23 | end
24 |
25 | def test_no_remove_needed_without_querystring_1
26 | assert_equal '/foo', remove_trailing_slash_from('/foo')
27 | end
28 | def test_no_remove_needed_without_querystring_2
29 | assert_equal '/foo/bar', remove_trailing_slash_from('/foo/bar')
30 | end
31 | def test_no_remove_needed_without_querystring_3
32 | assert_equal '/foo/bar/baz', remove_trailing_slash_from('/foo/bar/baz')
33 | end
34 | def test_no_remove_needed_without_querystring_4
35 | assert_equal '/foo/bar/baz.html', remove_trailing_slash_from('/foo/bar/baz.html')
36 | end
37 |
38 | def test_remove_with_querystring_1
39 | assert_equal '/foo?bar=baz', remove_trailing_slash_from('/foo/?bar=baz')
40 | end
41 | def test_remove_with_querystring_2
42 | assert_equal '/foo/foo?bar=baz', remove_trailing_slash_from('/foo/foo/?bar=baz')
43 | end
44 | def test_remove_with_querystring_3
45 | assert_equal '/foo/foo?bar=baz', remove_trailing_slash_from('/foo/foo/?bar=baz/')
46 | end
47 |
48 | def test_no_remove_needed_with_querystring_1
49 | assert_equal '/foo?bar=baz', remove_trailing_slash_from('/foo?bar=baz')
50 | end
51 | def test_no_remove_needed_with_querystring_2
52 | assert_equal '/foo/foo?bar=baz', remove_trailing_slash_from('/foo/foo?bar=baz')
53 | end
54 |
55 | def test_no_remove_needed_with_querystring_without_path
56 | assert_equal '/?bar=baz', remove_trailing_slash_from('/?bar=baz')
57 | end
58 |
59 | def test_slash_only
60 | assert_equal '/', remove_trailing_slash_from('/')
61 | end
62 |
63 | def test_double_slash
64 | assert_equal '/', remove_trailing_slash_from('//')
65 | end
66 | end
67 |
--------------------------------------------------------------------------------