rext 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/History.rdoc +97 -0
  2. data/Manifest +54 -0
  3. data/README.rdoc +136 -0
  4. data/Rakefile +16 -0
  5. data/benchmarks/enumerable.rb +14 -0
  6. data/benchmarks/proc.rb +24 -0
  7. data/lib/rext.rb +24 -0
  8. data/lib/rext/all.rb +18 -0
  9. data/lib/rext/array.rb +6 -0
  10. data/lib/rext/array/helpers.rb +64 -0
  11. data/lib/rext/date.rb +6 -0
  12. data/lib/rext/date/helpers.rb +11 -0
  13. data/lib/rext/enumerable.rb +6 -0
  14. data/lib/rext/enumerable/helpers.rb +88 -0
  15. data/lib/rext/hash.rb +6 -0
  16. data/lib/rext/hash/helpers.rb +42 -0
  17. data/lib/rext/integer.rb +6 -0
  18. data/lib/rext/integer/helpers.rb +29 -0
  19. data/lib/rext/module.rb +6 -0
  20. data/lib/rext/module/helpers.rb +85 -0
  21. data/lib/rext/numeric.rb +7 -0
  22. data/lib/rext/numeric/bytes.rb +16 -0
  23. data/lib/rext/numeric/time.rb +57 -0
  24. data/lib/rext/object.rb +7 -0
  25. data/lib/rext/object/helpers.rb +62 -0
  26. data/lib/rext/object/metaclass.rb +29 -0
  27. data/lib/rext/proc.rb +7 -0
  28. data/lib/rext/proc/helpers.rb +22 -0
  29. data/lib/rext/string.rb +7 -0
  30. data/lib/rext/string/encode.rb +82 -0
  31. data/lib/rext/string/helpers.rb +246 -0
  32. data/lib/rext/symbol.rb +6 -0
  33. data/lib/rext/symbol/helpers.rb +16 -0
  34. data/lib/rext/time.rb +6 -0
  35. data/lib/rext/time/helpers.rb +43 -0
  36. data/lib/rext/version.rb +4 -0
  37. data/rext.gemspec +30 -0
  38. data/spec/array_spec.rb +61 -0
  39. data/spec/date_spec.rb +14 -0
  40. data/spec/enumerable_spec.rb +55 -0
  41. data/spec/hash_spec.rb +36 -0
  42. data/spec/integer_spec.rb +19 -0
  43. data/spec/module_spec.rb +41 -0
  44. data/spec/numeric_spec.rb +31 -0
  45. data/spec/object_spec.rb +101 -0
  46. data/spec/spec.opts +1 -0
  47. data/spec/spec_helper.rb +5 -0
  48. data/spec/string_spec.rb +194 -0
  49. data/spec/symbol_spec.rb +14 -0
  50. data/spec/time_spec.rb +22 -0
  51. data/tasks/benchmark.rake +13 -0
  52. data/tasks/docs.rake +13 -0
  53. data/tasks/gemspec.rake +3 -0
  54. data/tasks/spec.rake +25 -0
  55. metadata +147 -0
@@ -0,0 +1,4 @@
1
+
2
+ module Rext
3
+ VERSION = '0.3.4'
4
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{rext}
5
+ s.version = "0.3.4"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["TJ Holowaychuk"]
9
+ s.date = %q{2009-10-08}
10
+ s.description = %q{Ruby extensions}
11
+ s.email = %q{tj@vision-media.ca}
12
+ s.extra_rdoc_files = ["README.rdoc", "lib/rext.rb", "lib/rext/all.rb", "lib/rext/array.rb", "lib/rext/array/helpers.rb", "lib/rext/date.rb", "lib/rext/date/helpers.rb", "lib/rext/enumerable.rb", "lib/rext/enumerable/helpers.rb", "lib/rext/hash.rb", "lib/rext/hash/helpers.rb", "lib/rext/integer.rb", "lib/rext/integer/helpers.rb", "lib/rext/module.rb", "lib/rext/module/helpers.rb", "lib/rext/numeric.rb", "lib/rext/numeric/bytes.rb", "lib/rext/numeric/time.rb", "lib/rext/object.rb", "lib/rext/object/helpers.rb", "lib/rext/object/metaclass.rb", "lib/rext/proc.rb", "lib/rext/proc/helpers.rb", "lib/rext/string.rb", "lib/rext/string/encode.rb", "lib/rext/string/helpers.rb", "lib/rext/symbol.rb", "lib/rext/symbol/helpers.rb", "lib/rext/time.rb", "lib/rext/time/helpers.rb", "lib/rext/version.rb", "tasks/benchmark.rake", "tasks/docs.rake", "tasks/gemspec.rake", "tasks/spec.rake"]
13
+ s.files = ["History.rdoc", "Manifest", "README.rdoc", "Rakefile", "benchmarks/enumerable.rb", "benchmarks/proc.rb", "lib/rext.rb", "lib/rext/all.rb", "lib/rext/array.rb", "lib/rext/array/helpers.rb", "lib/rext/date.rb", "lib/rext/date/helpers.rb", "lib/rext/enumerable.rb", "lib/rext/enumerable/helpers.rb", "lib/rext/hash.rb", "lib/rext/hash/helpers.rb", "lib/rext/integer.rb", "lib/rext/integer/helpers.rb", "lib/rext/module.rb", "lib/rext/module/helpers.rb", "lib/rext/numeric.rb", "lib/rext/numeric/bytes.rb", "lib/rext/numeric/time.rb", "lib/rext/object.rb", "lib/rext/object/helpers.rb", "lib/rext/object/metaclass.rb", "lib/rext/proc.rb", "lib/rext/proc/helpers.rb", "lib/rext/string.rb", "lib/rext/string/encode.rb", "lib/rext/string/helpers.rb", "lib/rext/symbol.rb", "lib/rext/symbol/helpers.rb", "lib/rext/time.rb", "lib/rext/time/helpers.rb", "lib/rext/version.rb", "rext.gemspec", "spec/array_spec.rb", "spec/date_spec.rb", "spec/enumerable_spec.rb", "spec/hash_spec.rb", "spec/integer_spec.rb", "spec/module_spec.rb", "spec/numeric_spec.rb", "spec/object_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "spec/string_spec.rb", "spec/symbol_spec.rb", "spec/time_spec.rb", "tasks/benchmark.rake", "tasks/docs.rake", "tasks/gemspec.rake", "tasks/spec.rake"]
14
+ s.homepage = %q{http://github.com/visionmedia/rext}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rext", "--main", "README.rdoc"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{rext}
18
+ s.rubygems_version = %q{1.3.5}
19
+ s.summary = %q{Ruby extensions}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
@@ -0,0 +1,61 @@
1
+
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+ require 'rext/array'
4
+
5
+ describe Array do
6
+ describe "helpers" do
7
+
8
+ before :each do
9
+ @items = %w( some foo bar )
10
+ end
11
+
12
+ describe "#from" do
13
+ it "should return elements after the position specified" do
14
+ @items.from(1).should == %w( foo bar )
15
+ end
16
+ end
17
+
18
+ describe "#to" do
19
+ it "should return elements up to position" do
20
+ @items.to(1).should == %w( some foo )
21
+ end
22
+ end
23
+
24
+ describe "#chunk" do
25
+ it "should split an array into several containing the length of n" do
26
+ (1..9).to_a.chunk(3).should == [[1,2,3], [4,5,6], [7,8,9]]
27
+ end
28
+
29
+ it "should accept a block, yielding each chunk" do
30
+ chunks = []
31
+ (1..9).to_a.in_groups_of(3) do |chunk|
32
+ chunks << chunk
33
+ end
34
+ chunks.should == [[1,2,3], [4,5,6], [7,8,9]]
35
+ end
36
+
37
+ it "should pad with nil by default" do
38
+ (1..5).to_a.in_groups_of(4).should == [[1,2,3,4], [5,nil,nil,nil]]
39
+ end
40
+
41
+ it "should not padd when pad_with is false" do
42
+ (1..6).to_a.in_groups_of(4, false).should == [[1,2,3,4], [5,6]]
43
+ end
44
+ end
45
+
46
+ describe "#pad" do
47
+ it "should pad with nil by default" do
48
+ [1,2].pad(4).should == [1, 2, nil, nil]
49
+ end
50
+
51
+ it "should pad an with an object" do
52
+ [1,2].pad(3 ,'x').should == [1, 2, 'x']
53
+ end
54
+
55
+ it "should do nothing when the array is of expected length" do
56
+ [1,2].pad(2).should == [1,2]
57
+ end
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,14 @@
1
+
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+ require 'rext/date'
4
+
5
+ describe Date do
6
+ describe "helpers" do
7
+ describe "#to_time" do
8
+ it "should convert to a Time instance" do
9
+ event = Date.parse('may 25th 1987')
10
+ event.to_time.should be_an_instance_of(Time)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,55 @@
1
+
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+ require 'rext/enumerable'
4
+
5
+ describe Enumerable do
6
+ describe "helpers" do
7
+ describe "#includes_all?" do
8
+ it "should return true when all arguments are present" do
9
+ [1,2,3].includes_all?(1,2).should be_true
10
+ end
11
+
12
+ it "should return true when not all arguments are present" do
13
+ [1,1,3,3,4].includes_all?(1,3,6).should be_false
14
+ [1,1,3,3,4].includes_all?(6,3,1).should be_false
15
+ end
16
+ end
17
+
18
+ describe "#group_by" do
19
+ before :each do
20
+ @enum = 'foo', :bar, 1, 2, 3
21
+ @results = {
22
+ String => ['foo'],
23
+ Symbol => [:bar],
24
+ Fixnum => [1, 2, 3]
25
+ }
26
+ end
27
+
28
+ it "should group an enum" do
29
+ @enum.group_by { |v| v.class }.should == @results
30
+ end
31
+
32
+ it "should group using instance evaluated block" do
33
+ @enum.group_by { self.class }.should == @results
34
+ end
35
+
36
+ it "should group by method call" do
37
+ @enum.group_by.class.should == @results
38
+ end
39
+ end
40
+
41
+ describe "#every" do
42
+ it "should map a method call" do
43
+ list = %w( cookies icecream sugar )
44
+ list.every.length.should == [7, 8 ,5]
45
+ end
46
+
47
+ it "should allow mapping shortcuts using a block" do
48
+ people = []
49
+ people << mock('Person', :name => 'TJ')
50
+ people << mock('Person', :name => 'Scott')
51
+ people.every { name.length }.should == [2, 5]
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,36 @@
1
+
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+ require 'rext/hash'
4
+
5
+ describe Hash do
6
+ describe "helpers" do
7
+ describe "#delete_at" do
8
+ it "should delete several keys, returning their values when present" do
9
+ options = { :foo => 1, :bar => 2 }
10
+ foo, bar, does_not_exist = options.delete_at :foo, :bar, :does_not_exist
11
+ foo.should == 1
12
+ bar.should == 2
13
+ does_not_exist.should be_nil
14
+ end
15
+ end
16
+
17
+ describe "#switchify" do
18
+ it "should work with bools" do
19
+ { :use_foobar => true }.switchify.should == ['--use-foobar']
20
+ { :use_foobar => false }.switchify.should be_empty
21
+ end
22
+
23
+ it "should stringify numbers and symbols" do
24
+ { :interval => 15, :icon => :jpeg }.switchify.sort.should == ['--icon', '--interval', '15', 'jpeg']
25
+ end
26
+
27
+ it "should work with little switches" do
28
+ { :T => true }.switchify.should == ['-T']
29
+ end
30
+
31
+ it "should add quotes around strings" do
32
+ { :glob => 'lib/**/*.rb' }.switchify.should == ['--glob', '"lib/**/*.rb"']
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,19 @@
1
+
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+ require 'rext/integer'
4
+
5
+ describe Integer do
6
+ describe "helpers" do
7
+ describe "#ordanalize" do
8
+ it "should convert integers to an ordanal string" do
9
+ 1.ordinalize.should == '1st'
10
+ 2.ordinalize.should == '2nd'
11
+ 3.ordinalize.should == '3rd'
12
+ 4.ordinalize.should == '4th'
13
+ 11.ordinalize.should == '11th'
14
+ 12.ordinalize.should == '12th'
15
+ 13.ordinalize.should == '13th'
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+ require 'rext/module'
4
+
5
+ describe Module do
6
+ describe "helpers" do
7
+ describe "#proxy_method" do
8
+ it "should implement method_missing, passing regexp captures and arguments to the handler method" do
9
+ class FooBar
10
+ call_method :find, :if => /^find_by_(\w+)_(\w+)/
11
+ call_method :delete, :if => lambda { |meth, *args| meth.to_s =~ /^delete_by_(\w+)_(\w+)/ }
12
+ def find *args; args end
13
+ def delete *args; args; end
14
+ end
15
+ foo = FooBar.new
16
+ foo.find_by_user_email.should == ['user', 'email']
17
+ foo.find_by_user_name('foo').should == ['user', 'name', 'foo']
18
+ foo.delete_by_user_name('foo', 'bar').should == ['foo', 'bar']
19
+ lambda { foo.does_not_exist }.should raise_error(NoMethodError)
20
+ end
21
+ end
22
+
23
+ describe "#setup" do
24
+ it "should define included instance evaluated in context to the module passed" do
25
+ module BarFoo
26
+ setup do
27
+ include InstanceMethods
28
+ end
29
+
30
+ module InstanceMethods
31
+ def bar_foo
32
+ 'wahoo'
33
+ end
34
+ end
35
+ end
36
+ FooBar.send :include, BarFoo
37
+ FooBar.new.bar_foo.should == 'wahoo'
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+ require 'rext/numeric'
4
+
5
+ describe Numeric do
6
+ describe "time" do
7
+ describe "#ago / #before" do
8
+ it "should return the distance in time before now, or specified time" do
9
+ event = Time.mktime 1987, 5, 25
10
+ 15.days.before(event).should == Time.mktime(1987, 5, 10)
11
+ end
12
+ end
13
+
14
+ describe "#since / #from_now" do
15
+ it "should return the distance in time from now, or specified time" do
16
+ event = Time.mktime 1987, 5, 25
17
+ 5.days.since(event).should == Time.mktime(1987, 5, 30)
18
+ end
19
+ end
20
+ end
21
+
22
+ describe "bytes" do
23
+ it "should return bytes, kilobytes, megabytes, gigabytes, and terabytes" do
24
+ 5.bytes.should == 5
25
+ 5.kilobytes.should == 5120
26
+ 5.megabytes.should == 5242880
27
+ 5.gigabytes.should == 5368709120
28
+ 5.terabytes.should == 5497558138880
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,101 @@
1
+
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+ require 'rext/object'
4
+
5
+ describe Object do
6
+ describe "metaclass" do
7
+ describe "#metaclass" do
8
+ it "should return the anonymous 'virtual' class" do
9
+ 'foo'.metaclass.should be_an_instance_of(Class)
10
+ end
11
+ end
12
+
13
+ describe "#meta_eval" do
14
+ it "should evaluate a block in context to the metaclass" do
15
+ object = 'foo'
16
+ object.meta_eval do
17
+ define_method :foo do
18
+ 'bar'
19
+ end
20
+ end
21
+ object.foo.should == 'bar'
22
+ end
23
+
24
+ it "should accept a string to be evaluated" do
25
+ object = 'foo'
26
+ object.meta_eval <<-EOF
27
+ def foo
28
+ 'bar'
29
+ end
30
+ EOF
31
+ object.foo.should == 'bar'
32
+ end
33
+ end
34
+
35
+ describe "#meta_def" do
36
+ it "should define a method within the metaclass" do
37
+ object = 'foo'
38
+ object.meta_def(:foo) { |*args| "bar #{ args.join(', ') }" }
39
+ object.foo(1,2,3).should == 'bar 1, 2, 3'
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "helpers" do
45
+ describe "#indifferent_hash" do
46
+ it "should return a hash indifferent to symbols or strings for key access" do
47
+ hash = indifferent_hash
48
+ hash['foo'] = 'foo'
49
+ hash[:foo].should == 'foo'
50
+ hash['foo'].should == 'foo'
51
+ end
52
+ end
53
+ end
54
+
55
+ describe "#try" do
56
+ it "should try the block once with no args" do
57
+ times = 0
58
+ try { times += 1 }
59
+ times.should == 1
60
+ end
61
+
62
+ it "should try the block multiple times when failing" do
63
+ times = 0
64
+ try(3) { times += 1; raise 'foo' }
65
+ times.should == 3
66
+ end
67
+
68
+ it "should try the block one time when succesful" do
69
+ times = 0
70
+ try(3) { times += 1 }
71
+ times.should == 1
72
+ end
73
+
74
+ it "should return the value returned by the block" do
75
+ val = try(3) { 'test' }
76
+ val.should == 'test'
77
+ end
78
+
79
+ it "should allow specific exceptions to be rescued" do
80
+ lambda { try(3){ raise ArgumentError, 'foo' } }.should_not raise_error
81
+ lambda { try(3, :on => ArgumentError){ raise ArgumentError, 'foo' } }.should_not raise_error
82
+ lambda { try(3, :on => TypeError){ raise ArgumentError, 'foo' } }.should raise_error(ArgumentError)
83
+ end
84
+ end
85
+
86
+ describe "#returning" do
87
+ it "should return the value given to it" do
88
+ def frequency_of enum
89
+ returning Hash.new(0) do |hash|
90
+ enum.each do |value|
91
+ hash[value] += 1
92
+ end
93
+ end
94
+ end
95
+ frequency_of(%w( foo bar foo foo )).should == {
96
+ 'foo' => 3,
97
+ 'bar' => 1,
98
+ }
99
+ end
100
+ end
101
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,5 @@
1
+
2
+ $:.unshift File.dirname(__FILE__) + '/../lib'
3
+
4
+ require 'rubygems'
5
+ require 'rext/all'
@@ -0,0 +1,194 @@
1
+
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+ require 'rext/string'
4
+
5
+ describe String do
6
+ describe "encode" do
7
+ describe "#to_md5" do
8
+ it "should return an md5 hash" do
9
+ 'test'.to_md5.should == '098f6bcd4621d373cade4e832627b4f6'
10
+ 'test'.to_md5.should == 'test'.to_md5
11
+ 'test'.to_md5.should_not == 'tests'.to_md5
12
+ end
13
+ end
14
+
15
+ describe "#to_sha512" do
16
+ it "should return an md5 hash" do
17
+ 'test'.to_sha512.should == 'ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff'
18
+ 'test'.to_sha512.should == 'test'.to_sha512
19
+ 'test'.to_sha512.should_not == 'tests'.to_sha512
20
+ end
21
+ end
22
+
23
+ describe "#base64_encode" do
24
+ it "should base64 encode a string" do
25
+ 'tj'.base64_encode.should == 'dGo='
26
+ "foo \n bar\n\n".base64_encode.base64_decode.should == "foo \n bar\n\n"
27
+ end
28
+ end
29
+
30
+ describe "#base64_decode" do
31
+ it "should decode a base64 string" do
32
+ 'dGo='.base64_decode.should == 'tj'
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "helpers" do
38
+ describe "#word_frequency" do
39
+ it "should return a hash with word keys and count values" do
40
+ 'mm i love cookies mm'.word_frequency.
41
+ should == {
42
+ 'mm' => 2,
43
+ 'i' => 1,
44
+ 'love' => 1,
45
+ 'cookies' => 1,
46
+ }
47
+ end
48
+ end
49
+
50
+ describe "#frequency_of_word" do
51
+ it "should return the frequency of a word, or 0" do
52
+ 'yum yum ? yes'.frequency_of_word('yum').should == 2
53
+ 'yum yum ? yes'.frequency_of_word('yes').should == 1
54
+ 'yum yum ? yes'.frequency_of_word('no').should == 0
55
+ end
56
+ end
57
+
58
+ describe "#switchify" do
59
+ it "should return a switch version of the string" do
60
+ 'some_foo_bar'.switchify.should == '--some-foo-bar'
61
+ end
62
+
63
+ it "should return small switches when only a single char" do
64
+ 't'.switchify.should == '-t'
65
+ end
66
+
67
+ it "should raise an InvalidSwitchError when length 0" do
68
+ lambda { ''.switchify }.should raise_error(String::InvalidSwitchError)
69
+ end
70
+ end
71
+
72
+ describe "#path" do
73
+ it "should return an instance of a pathname" do
74
+ 'History.rdoc'.path.should be_an_instance_of(Pathname)
75
+ end
76
+ end
77
+
78
+ describe "#files" do
79
+ it "should return result of Dir glob" do
80
+ 'lib/*.*'.files.should be_an_instance_of(Array)
81
+ end
82
+ end
83
+
84
+ describe "#file" do
85
+ it "should return an instance of a file" do
86
+ 'History.rdoc'.file.should be_an_instance_of(File)
87
+ end
88
+ end
89
+
90
+ describe "#add_class" do
91
+ it "should add a word that does not exist" do
92
+ 'foo'.add_class('bar').should == 'foo bar'
93
+ end
94
+
95
+ it "should not add the same word twice" do
96
+ 'foo-bar bar'.add_class('bar').should == 'foo-bar bar'
97
+ end
98
+ end
99
+
100
+ describe "#wrap" do
101
+ it "should wrap a string" do
102
+ 'foo'.wrap('|').should == '|foo|'
103
+ end
104
+
105
+ it "should wrap with optional suffix" do
106
+ 'foo'.wrap('(', ')').should == '(foo)'
107
+ end
108
+ end
109
+
110
+ describe "#starts_with?" do
111
+ it "should check if a string starts with another" do
112
+ 'foo bar'.starts_with?('foo').should be_true
113
+ ' foo bar'.starts_with?('foo').should_not be_true
114
+ 'bar foo'.starts_with?('foo').should_not be_true
115
+ end
116
+ end
117
+
118
+ describe "#ends_with?" do
119
+ it "should check if a string ends with another" do
120
+ 'foo bar'.ends_with?('bar').should be_true
121
+ 'foo bar '.ends_with?('bar').should_not be_true
122
+ 'bar foo foo'.ends_with?('foo').should be_true
123
+ end
124
+ end
125
+
126
+ describe "#plural?" do
127
+ it "should check if a string is plural" do
128
+ 'cookies'.should be_plural
129
+ 'cookie'.should_not be_plural
130
+ end
131
+ end
132
+
133
+ describe "#singular?" do
134
+ it "should check if a string is singular" do
135
+ 'cookie'.should be_singular
136
+ 'cookies'.should_not be_singular
137
+ end
138
+ end
139
+
140
+ describe "#first" do
141
+ it "should return the first character" do
142
+ 'foo'.first.should == 'f'
143
+ end
144
+
145
+ it "should return n number of charcters" do
146
+ 'foo'.first(2).should == 'fo'
147
+ end
148
+ end
149
+
150
+ describe "#last" do
151
+ it "should return the last character" do
152
+ 'bar'.last.should == 'r'
153
+ end
154
+
155
+ it "should return the last n number of characters" do
156
+ 'bar'.last(2).should == 'ar'
157
+ end
158
+ end
159
+
160
+ describe "#from" do
161
+ it "should return all characters from n" do
162
+ 'cookies'.from(3).should == 'kies'
163
+ end
164
+ end
165
+
166
+ describe "#camelize" do
167
+ it "should camel-case a string, leaving the first character lower by default" do
168
+ 'some_foo_bar'.camelize.should == 'someFooBar'
169
+ end
170
+
171
+ it "should camel-case a string, with first character capitalized" do
172
+ 'some_foo_bar'.camelize(true).should == 'SomeFooBar'
173
+ end
174
+ end
175
+
176
+ describe "#constantize" do
177
+ it "should convert a string to a constant" do
178
+ 'Rext::VERSION'.constantize.should == Rext::VERSION
179
+ end
180
+
181
+ it "should raise an error when an invalid constant name is passed" do
182
+ lambda { 'foo bar'.constantize }.should raise_error(NameError)
183
+ end
184
+ end
185
+
186
+ describe "#digitize" do
187
+ it "should leave only numeric characters" do
188
+ '$100,000'.digitize.should == '100000'
189
+ '$100,000'.digitize.to_i.should == 100_000
190
+ end
191
+ end
192
+
193
+ end
194
+ end