functional-ruby 0.7.4 → 0.7.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +46 -12
- data/lib/functional.rb +19 -0
- data/lib/functional/catalog.rb +487 -0
- data/lib/functional/collection.rb +403 -0
- data/lib/functional/inflect.rb +127 -0
- data/lib/functional/search.rb +132 -0
- data/lib/functional/sort.rb +41 -0
- data/lib/functional/utilities.rb +0 -3
- data/lib/functional/version.rb +1 -1
- data/md/catalog.md +32 -0
- data/md/collection.md +32 -0
- data/md/inflect.md +32 -0
- data/md/pattern_matching.md +2 -2
- data/md/platform.md +32 -0
- data/md/search.md +32 -0
- data/md/sort.md +32 -0
- data/md/utilities.md +2 -2
- data/spec/functional/catalog_spec.rb +1206 -0
- data/spec/functional/collection_spec.rb +752 -0
- data/spec/functional/inflect_spec.rb +85 -0
- data/spec/functional/pattern_matching_spec.rb +0 -2
- data/spec/functional/search_spec.rb +187 -0
- data/spec/functional/sort_spec.rb +61 -0
- data/spec/spec_helper.rb +9 -0
- metadata +23 -2
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Functional
|
4
|
+
|
5
|
+
describe Inflect do
|
6
|
+
|
7
|
+
context '#camelize' do
|
8
|
+
|
9
|
+
specify { Inflect.camelize('active_model').should eq 'ActiveModel' }
|
10
|
+
specify { Inflect.camelize('active_model', :lower).should eq 'activeModel' }
|
11
|
+
specify { Inflect.camelize(:active_model).should eq 'ActiveModel' }
|
12
|
+
specify { Inflect.camelize(:active_model, :lower).should eq 'activeModel' }
|
13
|
+
|
14
|
+
specify { Inflect.camelize('active_model/errors').should eq 'ActiveModel::Errors' }
|
15
|
+
specify { Inflect.camelize('active_model/errors', :lower).should eq 'activeModel::Errors' }
|
16
|
+
specify { Inflect.camelize(:'active_model/errors').should eq 'ActiveModel::Errors' }
|
17
|
+
specify { Inflect.camelize(:'active_model/errors', :lower).should eq 'activeModel::Errors' }
|
18
|
+
end
|
19
|
+
|
20
|
+
context '#underscore' do
|
21
|
+
|
22
|
+
specify { Inflect.underscore('ActiveModel').should eq 'active_model' }
|
23
|
+
specify { Inflect.underscore(:'ActiveModel').should eq 'active_model' }
|
24
|
+
|
25
|
+
specify { Inflect.underscore('ActiveModel::Errors').should eq 'active_model/errors' }
|
26
|
+
specify { Inflect.underscore(:'ActiveModel::Errors').should eq 'active_model/errors' }
|
27
|
+
end
|
28
|
+
|
29
|
+
context '#humanize' do
|
30
|
+
|
31
|
+
specify { Inflect.humanize('employee_salary').should eq 'Employee salary' }
|
32
|
+
specify { Inflect.humanize('author_id').should eq 'Author' }
|
33
|
+
|
34
|
+
specify { Inflect.humanize(:employee_salary).should eq 'Employee salary' }
|
35
|
+
specify { Inflect.humanize(:author_id).should eq 'Author' }
|
36
|
+
end
|
37
|
+
|
38
|
+
context '#titleize' do
|
39
|
+
|
40
|
+
specify { Inflect.titleize('man from the boondocks').should eq 'Man From The Boondocks' }
|
41
|
+
specify { Inflect.titleize('x-men: the last stand').should eq 'X Men: The Last Stand' }
|
42
|
+
specify { Inflect.titleize('TheManWithoutAPast').should eq 'The Man Without A Past' }
|
43
|
+
specify { Inflect.titleize('raiders_of_the_lost_ark').should eq 'Raiders Of The Lost Ark' }
|
44
|
+
|
45
|
+
specify { Inflect.titleize(:'man from the boondocks').should eq 'Man From The Boondocks' }
|
46
|
+
specify { Inflect.titleize(:'x-men: the last stand').should eq 'X Men: The Last Stand' }
|
47
|
+
specify { Inflect.titleize(:'TheManWithoutAPast').should eq 'The Man Without A Past' }
|
48
|
+
specify { Inflect.titleize(:'raiders_of_the_lost_ark').should eq 'Raiders Of The Lost Ark' }
|
49
|
+
end
|
50
|
+
|
51
|
+
context '#dasherize' do
|
52
|
+
|
53
|
+
specify { Inflect.dasherize('puni_puni').should eq 'puni-puni' }
|
54
|
+
specify { Inflect.dasherize(:'puni_puni').should eq 'puni-puni' }
|
55
|
+
end
|
56
|
+
|
57
|
+
context '#extensionize' do
|
58
|
+
|
59
|
+
specify { Inflect.extensionize('my_file.png', :png).should eq 'my_file.png' }
|
60
|
+
specify { Inflect.extensionize('my_file.png', 'png').should eq 'my_file.png' }
|
61
|
+
specify { Inflect.extensionize('my_file.png', '.png').should eq 'my_file.png' }
|
62
|
+
specify { Inflect.extensionize('MY_FILE.PNG', '.png').should eq 'MY_FILE.PNG' }
|
63
|
+
|
64
|
+
specify { Inflect.extensionize('my_file.png', :jpg).should eq 'my_file.png.jpg' }
|
65
|
+
specify { Inflect.extensionize('my_file.png', 'jpg').should eq 'my_file.png.jpg' }
|
66
|
+
specify { Inflect.extensionize('my_file.png', '.jpg').should eq 'my_file.png.jpg' }
|
67
|
+
|
68
|
+
specify { Inflect.extensionize('my_file.png', :jpg, :chomp => true).should eq 'my_file.jpg' }
|
69
|
+
specify { Inflect.extensionize('my_file.png', 'jpg', :chomp => true).should eq 'my_file.jpg' }
|
70
|
+
specify { Inflect.extensionize('my_file.png', '.jpg', :chomp => true).should eq 'my_file.jpg' }
|
71
|
+
|
72
|
+
specify { Inflect.extensionize('my_file', :png).should eq 'my_file.png' }
|
73
|
+
specify { Inflect.extensionize('my_file', 'png').should eq 'my_file.png' }
|
74
|
+
specify { Inflect.extensionize('my_file', '.png').should eq 'my_file.png' }
|
75
|
+
|
76
|
+
specify { Inflect.extensionize('My File', :png).should eq 'My File.png' }
|
77
|
+
specify { Inflect.extensionize('My File', 'png').should eq 'My File.png' }
|
78
|
+
specify { Inflect.extensionize('My File', '.png').should eq 'My File.png' }
|
79
|
+
|
80
|
+
specify { Inflect.extensionize('My File ', :png).should eq 'My File.png' }
|
81
|
+
specify { Inflect.extensionize('My File ', 'png').should eq 'My File.png' }
|
82
|
+
specify { Inflect.extensionize('My File ', '.png').should eq 'My File.png' }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Functional
|
4
|
+
|
5
|
+
describe Search do
|
6
|
+
|
7
|
+
context '#linear_search' do
|
8
|
+
|
9
|
+
let(:sample) do
|
10
|
+
[3, 5, 6, 7, 8, 11, 15, 21, 22, 28, 30, 32, 33, 34, 40].freeze
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'returns nil for a nil sample' do
|
14
|
+
Search.linear_search(nil, 1).should be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns nil for an empty sample' do
|
18
|
+
Search.linear_search([].freeze, 1).should be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns the index of the item when found' do
|
22
|
+
index = Search.linear_search(sample, 11)
|
23
|
+
index.should eq 5
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'returns the index of the item when using a block' do
|
27
|
+
sample = [
|
28
|
+
{:count => 11},
|
29
|
+
{:count => 12},
|
30
|
+
{:count => 13},
|
31
|
+
{:count => 14},
|
32
|
+
{:count => 16},
|
33
|
+
{:count => 17},
|
34
|
+
{:count => 18},
|
35
|
+
{:count => 19},
|
36
|
+
{:count => 20},
|
37
|
+
{:count => 21}
|
38
|
+
].freeze
|
39
|
+
|
40
|
+
index = Search.linear_search(sample, 14){|item| item[:count]}
|
41
|
+
index.should eq 3
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns nil when not found' do
|
45
|
+
index = Search.linear_search(sample, 13)
|
46
|
+
index.should be_nil
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'supports an :imin option for an alternate low index' do
|
50
|
+
index = Search.linear_search(sample, 11, :imin => 3)
|
51
|
+
index.should eq 5
|
52
|
+
|
53
|
+
index = Search.linear_search(sample, 11, :imin => 10)
|
54
|
+
index.should be_nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'supports an :imax option for an alternate high index' do
|
58
|
+
index = Search.linear_search(sample, 11, :imax => 10)
|
59
|
+
index.should eq 5
|
60
|
+
|
61
|
+
index = Search.linear_search(sample, 11, :imax => 4)
|
62
|
+
index.should be_nil
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'behaves consistently when :imin equals :imax' do
|
66
|
+
index = Search.linear_search(sample, 3, :imin => 5, :imax => 5)
|
67
|
+
index.should be_nil
|
68
|
+
|
69
|
+
index = Search.linear_search(sample, 11, :imin => 5, :imax => 5)
|
70
|
+
index.should eq 5
|
71
|
+
|
72
|
+
index = Search.linear_search(sample, 30, :imin => 5, :imax => 5)
|
73
|
+
index.should be_nil
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'sets :imin to zero (0) when given a negative number' do
|
77
|
+
index = Search.linear_search(sample, 11, :imin => -1)
|
78
|
+
index.should eq 5
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'sets :imax to the uppermost index when :imax is out of range' do
|
82
|
+
index = Search.linear_search(sample, 11, :imax => 100)
|
83
|
+
index.should eq 5
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'returns nil when :imin is greater than :imax' do
|
87
|
+
index = Search.linear_search(sample, 1, :imin => 10, :imax => 5)
|
88
|
+
index.should be_nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context '#binary_search' do
|
93
|
+
|
94
|
+
let(:sample) do
|
95
|
+
[3, 5, 6, 7, 8, 11, 15, 21, 22, 28, 30, 32, 33, 34, 40].freeze
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'returns nil for a nil sample' do
|
99
|
+
Search.binary_search(nil, 1).should be_nil
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'returns nil for an empty sample' do
|
103
|
+
Search.binary_search([].freeze, 1).should be_nil
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'returns the index of the item when found as [index, index]' do
|
107
|
+
index = Search.binary_search(sample, 11)
|
108
|
+
index.should eq [5, 5]
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'returns the index of the item when using a block' do
|
112
|
+
sample = [
|
113
|
+
{:count => 11},
|
114
|
+
{:count => 12},
|
115
|
+
{:count => 13},
|
116
|
+
{:count => 14},
|
117
|
+
{:count => 16},
|
118
|
+
{:count => 17},
|
119
|
+
{:count => 18},
|
120
|
+
{:count => 19},
|
121
|
+
{:count => 20},
|
122
|
+
{:count => 21}
|
123
|
+
].freeze
|
124
|
+
|
125
|
+
index = Search.binary_search(sample, 14){|item| item[:count]}
|
126
|
+
index.should eq [3, 3]
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'returns the indexes above and below when not found - below, above' do
|
130
|
+
index = Search.binary_search(sample, 13)
|
131
|
+
index.should eq [5, 6]
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'returns nil and the low index when the item is out of range on the low end - [nil, low]' do
|
135
|
+
index = Search.binary_search(sample, 1)
|
136
|
+
index.should eq [nil, 0]
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'returns the high index and nil when the item is out of range on the high end - [high, nil]' do
|
140
|
+
index = Search.binary_search(sample, 41)
|
141
|
+
index.should eq [14, nil]
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'supports an :imin option for an alternate low index' do
|
145
|
+
index = Search.binary_search(sample, 11, :imin => 3)
|
146
|
+
index.should eq [5, 5]
|
147
|
+
|
148
|
+
index = Search.binary_search(sample, 11, :imin => 10)
|
149
|
+
index.should eq [nil, 10]
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'supports an :imax option for an alternate high index' do
|
153
|
+
index = Search.binary_search(sample, 11, :imax => 10)
|
154
|
+
index.should eq [5, 5]
|
155
|
+
|
156
|
+
index = Search.binary_search(sample, 11, :imax => 4)
|
157
|
+
index.should eq [4, nil]
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'behaves consistently when :imin equals :imax' do
|
161
|
+
index = Search.binary_search(sample, 3, :imin => 5, :imax => 5)
|
162
|
+
index.should eq [nil, 5]
|
163
|
+
|
164
|
+
index = Search.binary_search(sample, 11, :imin => 5, :imax => 5)
|
165
|
+
index.should eq [5, 5]
|
166
|
+
|
167
|
+
index = Search.binary_search(sample, 30, :imin => 5, :imax => 5)
|
168
|
+
index.should eq [5, nil]
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'sets :imin to zero (0) when given a negative number' do
|
172
|
+
index = Search.binary_search(sample, 1, :imin => -1)
|
173
|
+
index.should eq [nil, 0]
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'sets :imax to the uppermost index when :imax is out of range' do
|
177
|
+
index = Search.binary_search(sample, 41, :imax => 100)
|
178
|
+
index.should eq [14, nil]
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'returns nil when :imin is greater than :imax' do
|
182
|
+
index = Search.binary_search(sample, 1, :imin => 10, :imax => 5)
|
183
|
+
index.should be_nil
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Functional
|
4
|
+
|
5
|
+
describe Sort do
|
6
|
+
|
7
|
+
context '#insertion_sort!' do
|
8
|
+
|
9
|
+
it 'returns nil for a nil sample' do
|
10
|
+
Sort.insertion_sort!(nil).should be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'returns the sample when the sample is empty' do
|
14
|
+
Sort.insertion_sort!([]).should be_empty
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns the sample when the sample has one element' do
|
18
|
+
Sort.insertion_sort!([100]).should eq [100]
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'sorts an unsorted collection' do
|
22
|
+
sample = [31, 37, 26, 30, 2, 30, 1, 33, 5, 14, 11, 13, 17, 35, 4]
|
23
|
+
count = sample.count
|
24
|
+
sorted = Sort.insertion_sort!(sample)
|
25
|
+
Functional.ascending?(sorted).should be_true
|
26
|
+
sorted.count.should eq count
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'does not modify an unsorted collection' do
|
30
|
+
sample = [1, 2, 4, 5, 11, 13, 14, 17, 26, 30, 30, 31, 33, 35, 37]
|
31
|
+
control = sample.dup
|
32
|
+
sorted = Sort.insertion_sort!(sample)
|
33
|
+
sorted.should eq control
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'it sorts a collection with a block' do
|
37
|
+
sample = [
|
38
|
+
{:count => 31},
|
39
|
+
{:count => 37},
|
40
|
+
{:count => 26},
|
41
|
+
{:count => 30},
|
42
|
+
{:count => 2},
|
43
|
+
{:count => 30},
|
44
|
+
{:count => 1}
|
45
|
+
]
|
46
|
+
|
47
|
+
count = sample.count
|
48
|
+
sorted = Sort.insertion_sort!(sample){|item| item[:count]}
|
49
|
+
Functional.ascending?(sorted){|item| item[:count]}.should be_true
|
50
|
+
sorted.count.should eq count
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'performs the sort in place' do
|
54
|
+
lambda {
|
55
|
+
sample = [31, 37, 26, 30, 2, 30, 1, 33, 5, 14, 11, 13, 17, 35, 4].freeze
|
56
|
+
Sort.insertion_sort!(sample)
|
57
|
+
}.should raise_error
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: functional-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jerry D'Antonio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -37,19 +37,35 @@ files:
|
|
37
37
|
- LICENSE
|
38
38
|
- lib/functional/behavior.rb
|
39
39
|
- lib/functional/behaviour.rb
|
40
|
+
- lib/functional/catalog.rb
|
41
|
+
- lib/functional/collection.rb
|
42
|
+
- lib/functional/inflect.rb
|
40
43
|
- lib/functional/pattern_matching.rb
|
41
44
|
- lib/functional/platform.rb
|
45
|
+
- lib/functional/search.rb
|
46
|
+
- lib/functional/sort.rb
|
42
47
|
- lib/functional/utilities.rb
|
43
48
|
- lib/functional/version.rb
|
44
49
|
- lib/functional.rb
|
45
50
|
- lib/functional_ruby.rb
|
46
51
|
- md/behavior.md
|
52
|
+
- md/catalog.md
|
53
|
+
- md/collection.md
|
54
|
+
- md/inflect.md
|
47
55
|
- md/pattern_matching.md
|
56
|
+
- md/platform.md
|
57
|
+
- md/search.md
|
58
|
+
- md/sort.md
|
48
59
|
- md/utilities.md
|
49
60
|
- spec/functional/behavior_spec.rb
|
61
|
+
- spec/functional/catalog_spec.rb
|
62
|
+
- spec/functional/collection_spec.rb
|
63
|
+
- spec/functional/inflect_spec.rb
|
50
64
|
- spec/functional/integration_spec.rb
|
51
65
|
- spec/functional/pattern_matching_spec.rb
|
52
66
|
- spec/functional/platform_spec.rb
|
67
|
+
- spec/functional/search_spec.rb
|
68
|
+
- spec/functional/sort_spec.rb
|
53
69
|
- spec/functional/utilities_spec.rb
|
54
70
|
- spec/spec_helper.rb
|
55
71
|
homepage: https://github.com/jdantonio/functional-ruby/
|
@@ -87,8 +103,13 @@ specification_version: 4
|
|
87
103
|
summary: Erlang and Clojure inspired functional programming tools for Ruby.
|
88
104
|
test_files:
|
89
105
|
- spec/functional/behavior_spec.rb
|
106
|
+
- spec/functional/catalog_spec.rb
|
107
|
+
- spec/functional/collection_spec.rb
|
108
|
+
- spec/functional/inflect_spec.rb
|
90
109
|
- spec/functional/integration_spec.rb
|
91
110
|
- spec/functional/pattern_matching_spec.rb
|
92
111
|
- spec/functional/platform_spec.rb
|
112
|
+
- spec/functional/search_spec.rb
|
113
|
+
- spec/functional/sort_spec.rb
|
93
114
|
- spec/functional/utilities_spec.rb
|
94
115
|
- spec/spec_helper.rb
|