ramda-ruby 0.1.0.alpha → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +23 -8
- data/docs/FUNCTIONS.md +2 -0
- data/lib/ramda.rb +2 -0
- data/lib/ramda/object.rb +23 -4
- data/lib/ramda/version.rb +1 -1
- data/spec/ramda/function_spec.rb +200 -0
- data/spec/ramda/internal/curried_method_spec.rb +16 -0
- data/spec/ramda/list_spec.rb +399 -0
- data/spec/ramda/logic_spec.rb +74 -0
- data/spec/ramda/math_spec.rb +75 -0
- data/spec/ramda/object_spec.rb +117 -0
- data/spec/ramda/relation_spec.rb +174 -0
- data/spec/ramda/string_spec.rb +44 -0
- data/spec/ramda_spec.rb +105 -0
- data/spec/spec_helper.rb +18 -0
- metadata +34 -29
- data/.bashrc.docker +0 -2
- data/.coveralls.yml +0 -1
- data/.gitignore +0 -14
- data/.overcommit.yml +0 -73
- data/.pryrc.docker +0 -1
- data/.rspec +0 -2
- data/.rubocop.yml +0 -42
- data/.travis.yml +0 -35
- data/Dockerfile +0 -24
- data/Gemfile +0 -23
- data/Gemfile.dev +0 -6
- data/Gemfile.dev.lock +0 -38
- data/Rakefile +0 -6
- data/appveyor.yml +0 -26
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/codeclimate.yml +0 -6
- data/docker-compose.override.yml +0 -12
- data/docker-compose.yml +0 -15
- data/ramda-ruby.gemspec +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92c254b35426d8cb7d3e26e8a20a65dd0194a795
|
4
|
+
data.tar.gz: 49381b27473b09231633674595c3893ef9105600
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b3bb80690881e350816705eb9d91b91d507d633ae395ee904f37acbf8e90cbf2c2d8a2575a7805fb0be8009c7fab069e05eb2aa373883a9d6d350c2a6ef3d7b3
|
7
|
+
data.tar.gz: b6c9c51bd4a2ff317673d28ce65f0e1f5e1e3f06d62362a48ae04d429819012a6747ca12f5b2477678b1f7e6ae0d1f5e49e1333a8069ff8373081bd418207091
|
data/README.md
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
Ramda Ruby
|
2
2
|
=============
|
3
3
|
|
4
|
-
This is ruby version of
|
5
|
-
|
4
|
+
This is a ruby version of [Ramda Js](http://ramdajs.com) library.
|
6
5
|
|
7
6
|
[](http://badge.fury.io/rb/ramda-ruby)
|
8
7
|
[](https://travis-ci.org/lazebny/ramda-ruby)
|
@@ -34,18 +33,34 @@ Or install it yourself as:
|
|
34
33
|
And then require:
|
35
34
|
|
36
35
|
```ruby
|
37
|
-
|
36
|
+
require 'ramda'
|
38
37
|
```
|
39
38
|
|
39
|
+
## Philosophy of [Ramda](http://ramdajs.com)
|
40
|
+
|
41
|
+
* Ramda emphasizes a purer functional style.
|
42
|
+
Immutability and side-effect free functions are at the heart of its design philosophy.
|
43
|
+
This can help you get the job done with simple, elegant code.
|
44
|
+
|
45
|
+
* Ramda functions are automatically curried.
|
46
|
+
This allows you to easily build up new functions from old ones simply by not supplying the final parameters.
|
47
|
+
|
48
|
+
* The parameters to Ramda functions are arranged to make it convenient for currying.
|
49
|
+
The data to be operated on is generally supplied last.
|
50
|
+
|
51
|
+
|
40
52
|
## Documentation
|
41
53
|
|
42
|
-
This gem tries to follow the same versions as
|
54
|
+
This gem tries to follow the same versions as Ramda Js.
|
55
|
+
|
56
|
+
Currently the gem doesn't have own documentation but it tries to follow specification from [Ramda Js](http://ramdajs.com/docs/):
|
57
|
+
|
58
|
+
* each release contains [functions](docs/FUNCTIONS.md) from the relevant Ramda Js release
|
59
|
+
* each release includes more functions which i found pretty useful
|
43
60
|
|
44
|
-
[
|
61
|
+
You could use [Ramda Js](http://ramdajs.com/docs/) as a source of documentation.
|
45
62
|
|
46
|
-
|
47
|
-
specification from http://ramdajs.com/docs/. You could use this resource as a
|
48
|
-
source of documentation. Examples exist in spec directory.
|
63
|
+
Ruby scpecific examples can be found in [tests](spec/ramda).
|
49
64
|
|
50
65
|
## Usage
|
51
66
|
|
data/docs/FUNCTIONS.md
CHANGED
data/lib/ramda.rb
CHANGED
data/lib/ramda/object.rb
CHANGED
@@ -5,21 +5,40 @@ module Ramda
|
|
5
5
|
module Object
|
6
6
|
extend ::Ramda::Internal::CurriedMethod
|
7
7
|
|
8
|
+
# Makes a shallow clone of an object, setting or overriding the specified
|
9
|
+
# property with the given value. Note that this copies and flattens
|
10
|
+
# prototype properties onto the new object as well. All non-primitive
|
11
|
+
# properties are copied by reference.
|
12
|
+
#
|
13
|
+
# String -> a -> {k: v} -> {k: v}
|
14
|
+
#
|
15
|
+
curried_method(:assoc) do |key, val, obj|
|
16
|
+
obj.merge(key => val)
|
17
|
+
end
|
18
|
+
|
8
19
|
# Creates a deep copy of the value which may contain (nested)
|
9
20
|
# Arrays and Objects, Numbers, Strings, Booleans and Dates.
|
10
21
|
# Functions are assigned by reference rather than copied
|
11
22
|
#
|
12
23
|
# {*} -> {*}
|
13
24
|
#
|
14
|
-
curried_method(:clone) do |
|
15
|
-
case
|
25
|
+
curried_method(:clone) do |obj|
|
26
|
+
case obj
|
16
27
|
when Array
|
17
|
-
|
28
|
+
obj.dup.map(&method(:clone))
|
18
29
|
else
|
19
|
-
|
30
|
+
obj.dup
|
20
31
|
end
|
21
32
|
end
|
22
33
|
|
34
|
+
# Returns a new object that does not contain a prop property.
|
35
|
+
#
|
36
|
+
# String -> {k: v} -> {k: v}
|
37
|
+
#
|
38
|
+
curried_method(:dissoc) do |prop, obj|
|
39
|
+
clone(obj).tap { |o| o.delete(prop) }
|
40
|
+
end
|
41
|
+
|
23
42
|
# Reports whether two objects have the same value, in R.equals terms,
|
24
43
|
# for the specified property. Useful as a curried predicate.
|
25
44
|
#
|
data/lib/ramda/version.rb
CHANGED
@@ -0,0 +1,200 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ramda::Function do
|
4
|
+
let(:r) { described_class }
|
5
|
+
|
6
|
+
context '#always' do
|
7
|
+
it 'from docs' do
|
8
|
+
str = 'Tee'
|
9
|
+
expect(r.always(str).call).to be(str)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'is curried' do
|
13
|
+
str = 'Tee'
|
14
|
+
expect(r.always.call(str).call).to be(str)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context '#comparator' do
|
19
|
+
it 'from docs' do
|
20
|
+
sort_rule = r.comparator(->(a, b) { a < b })
|
21
|
+
numbers = [30, 25, 21]
|
22
|
+
expect(R.sort(sort_rule, numbers)).to eq([21, 25, 30])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context '#compose' do
|
27
|
+
it 'from docs' do
|
28
|
+
classy_greeting = lambda do |first_name, last_name|
|
29
|
+
"The name's #{last_name}, #{first_name} #{last_name}"
|
30
|
+
end
|
31
|
+
abs = ->(val) { val < 0 ? -1 * val : val }
|
32
|
+
|
33
|
+
expect(r.compose(R.to_upper, classy_greeting).call('James', 'Bond'))
|
34
|
+
.to eq("THE NAME'S BOND, JAMES BOND")
|
35
|
+
|
36
|
+
expect(r.compose(abs, R.add(1), R.multiply(2)).call(-4)).to be(7)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context '#construct' do
|
41
|
+
it 'from docs' do
|
42
|
+
array_builder = r.construct(Array)
|
43
|
+
expect(array_builder.call(2, 10)).to eq([10, 10])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context '#converge' do
|
48
|
+
it 'from docs' do
|
49
|
+
average = r.converge(R.divide, [R.sum, R.length])
|
50
|
+
expect(average.call([1, 2, 3, 4, 5, 6, 7])).to eq(4)
|
51
|
+
|
52
|
+
strange_concat = r.converge(R.concat, [R.to_upper, R.to_lower])
|
53
|
+
expect(strange_concat.call('Yodel')).to eq('YODELyodel')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context '#curry' do
|
58
|
+
it 'from docs' do
|
59
|
+
add_four_numbers = ->(a, b, c, d) { a + b + c + d }
|
60
|
+
|
61
|
+
curried_add_four_numbers = r.curry(add_four_numbers)
|
62
|
+
f = curried_add_four_numbers.call(1, 2)
|
63
|
+
g = f.call(3)
|
64
|
+
expect(g.call(4)).to be(10)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_method(a)
|
68
|
+
a
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'can receive a method' do
|
72
|
+
expect(r.curry(method(:test_method)).call(100)).to eq(100)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context '#flip' do
|
77
|
+
def merge_tree
|
78
|
+
->(a, b, c) { [a, b, c] }
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'from docs' do
|
82
|
+
expect(merge_tree.call(1, 2, 3)).to eq([1, 2, 3])
|
83
|
+
expect(r.flip(merge_tree).call(1, 2, 3)).to eq([2, 1, 3])
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'curried' do
|
87
|
+
expect(r.flip(merge_tree).call(1, 2).call(3)).to eq([2, 1, 3])
|
88
|
+
expect(r.flip(merge_tree).call(1).call(2).call(3)).to eq([2, 1, 3])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context '#identity' do
|
93
|
+
it 'from docs' do
|
94
|
+
expect(r.identity(1)).to be(1)
|
95
|
+
obj = {}
|
96
|
+
expect(r.identity(obj)).to be(obj)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'is curried' do
|
100
|
+
obj = {}
|
101
|
+
expect(r.identity.call(obj)).to be(obj)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context '#invoker' do
|
106
|
+
it 'from docs' do
|
107
|
+
slice_form = r.invoker(1, 'slice')
|
108
|
+
expect(slice_form.call(6, 'abcdefghijklm')).to eq('g')
|
109
|
+
|
110
|
+
slice_form6 = r.invoker(2, 'slice').call(6)
|
111
|
+
expect(slice_form6.call(8, 'abcdefghijklmnop')).to eq('ghijklmn')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context '#memoize' do
|
116
|
+
it 'from docs' do
|
117
|
+
count = 0
|
118
|
+
|
119
|
+
sum = r.memoize(lambda do |a, b, c|
|
120
|
+
count += 1
|
121
|
+
a + b + c
|
122
|
+
end)
|
123
|
+
|
124
|
+
expect(sum.call(10, 20, 30)).to be(60)
|
125
|
+
expect(sum.call(10, 20, 30)).to be(60)
|
126
|
+
expect(sum.call(10, 20, 30)).to be(60)
|
127
|
+
|
128
|
+
expect(count).to be(1)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'is curried' do
|
132
|
+
count = 0
|
133
|
+
|
134
|
+
sum = r.memoize(lambda do |a, b, c|
|
135
|
+
count += 1
|
136
|
+
a + b + c
|
137
|
+
end)
|
138
|
+
|
139
|
+
expect(sum.call(10).call(20).call(30)).to be(60)
|
140
|
+
expect(sum.call(10, 20).call(30)).to be(60)
|
141
|
+
expect(sum.call(10, 20, 30)).to be(60)
|
142
|
+
|
143
|
+
expect(count).to be(1)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context '#n_ary' do
|
148
|
+
it 'from docs' do
|
149
|
+
takes_two_args = ->(a, b) { [a, b] }
|
150
|
+
|
151
|
+
# expect(takes_two_args.arity).to be(2)
|
152
|
+
expect(takes_two_args.call(1, 2)).to eq([1, 2])
|
153
|
+
|
154
|
+
takes_one_arg = r.n_ary(1, takes_two_args)
|
155
|
+
# expect(takes_one_arg.arity).to be(1)
|
156
|
+
expect(takes_one_arg.call(1, 2)).to eq([1, nil])
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context '#once' do
|
161
|
+
it 'from docs' do
|
162
|
+
add_one_once = r.once(->(x) { x + 1 })
|
163
|
+
expect(add_one_once.call(10)).to eq(11)
|
164
|
+
expect(add_one_once.call(add_one_once.call(50))).to eq(11)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context '#pipe' do
|
169
|
+
it 'from docs' do
|
170
|
+
classy_greeting = lambda do |first_name, last_name|
|
171
|
+
"The name's #{last_name}, #{first_name} #{last_name}"
|
172
|
+
end
|
173
|
+
abs = ->(val) { val < 0 ? -1 * val : val }
|
174
|
+
|
175
|
+
expect(r.pipe(classy_greeting, R.to_upper).call('James', 'Bond'))
|
176
|
+
.to eq("THE NAME'S BOND, JAMES BOND")
|
177
|
+
|
178
|
+
expect(r.pipe(R.multiply(2), R.add(1), abs).call(-4)).to be(7)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context '#tap' do
|
183
|
+
it 'from docs' do
|
184
|
+
say_x = instance_double(Proc)
|
185
|
+
expect(say_x).to receive(:call).with(100)
|
186
|
+
expect(r.tap(say_x, 100)).to be(100)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context '#use_with' do
|
191
|
+
it 'from docs' do
|
192
|
+
pow = ->(x, count) { Array.new(count, x).reduce(:*) }
|
193
|
+
|
194
|
+
expect(r.use_with(pow, [R.identity, R.identity]).call(3, 4)).to eq(81)
|
195
|
+
expect(r.use_with(pow, [R.identity, R.identity]).call(3).call(4)).to eq(81)
|
196
|
+
expect(r.use_with(pow, [R.dec, R.inc]).call(3, 4)).to eq(32)
|
197
|
+
expect(r.use_with(pow, [R.dec, R.inc]).call(3).call(4)).to eq(32)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ramda::Internal::CurriedMethod do
|
4
|
+
let(:instance) { Class.new { extend Ramda::Internal::CurriedMethod } }
|
5
|
+
|
6
|
+
it '#curried_method' do
|
7
|
+
instance.curried_method(:sample_method) do |a, b, c|
|
8
|
+
a + b + c
|
9
|
+
end
|
10
|
+
|
11
|
+
expect(instance.sample_method.call(1).call(2).call(3)).to be(6)
|
12
|
+
expect(instance.sample_method(1).call(2).call(3)).to be(6)
|
13
|
+
expect(instance.sample_method(1, 2).call(3)).to be(6)
|
14
|
+
expect(instance.sample_method(1, 2, 3)).to be(6)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,399 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ramda::List do
|
4
|
+
let(:r) { described_class }
|
5
|
+
|
6
|
+
context '#all' do
|
7
|
+
it 'test' do
|
8
|
+
equals3 = R.equals(3)
|
9
|
+
expect(r.all(equals3, [3, 3, 3, 3])).to be_truthy
|
10
|
+
expect(r.all(equals3, [3, 3, 1, 3])).to be_falsey
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'is curried' do
|
14
|
+
equals3 = R.equals(3)
|
15
|
+
expect(r.all(equals3).call([3, 3, 3])).to be_truthy
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context '#any' do
|
20
|
+
it 'test' do
|
21
|
+
greater_than0 = R.lt(1)
|
22
|
+
greater_than2 = R.lt(2)
|
23
|
+
|
24
|
+
expect(r.any(greater_than0, [0, 1])).to be_falsey
|
25
|
+
expect(r.any(greater_than2, [2, 3])).to be_truthy
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'is curried' do
|
29
|
+
greater_than0 = R.lt(1)
|
30
|
+
|
31
|
+
expect(r.any(greater_than0)[[0, 1]]).to be_falsey
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context '#append' do
|
36
|
+
it 'from docs' do
|
37
|
+
expect(r.append('tests', ['write', 'more'])).to eq(['write', 'more', 'tests'])
|
38
|
+
expect(r.append('tests', [])).to eq(['tests'])
|
39
|
+
expect(r.append(['tests'], ['write', 'more'])).to eq(['write', 'more', ['tests']])
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'is curried' do
|
43
|
+
expect(R.append(1).call([4, 3, 2])).to eq([4, 3, 2, 1])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context '#concat' do
|
48
|
+
it 'from docs' do
|
49
|
+
expect(r.concat('ABC', 'DEF')).to eq('ABCDEF')
|
50
|
+
expect(r.concat([4, 5, 6], [1, 2, 3])).to eql([4, 5, 6, 1, 2, 3])
|
51
|
+
expect(r.concat([], [])).to eql([])
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'is curried' do
|
55
|
+
expect(r.concat('ABC').call('DEF')).to eq('ABCDEF')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context '#contains' do
|
60
|
+
it 'from docs' do
|
61
|
+
expect(r.contains(3, [1, 2, 3])).to be_truthy
|
62
|
+
expect(r.contains(4, [1, 2, 3])).to be_falsey
|
63
|
+
expect(r.contains({ name: 'Fred' }, [{ name: 'Fred' }])).to be_truthy
|
64
|
+
expect(r.contains([42], [[42]])).to be_truthy
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'is curried' do
|
68
|
+
expect(r.contains(3).call([1, 2, 3]))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context '#drop' do
|
73
|
+
it 'from docs' do
|
74
|
+
expect(r.drop(1, ['foo', 'bar', 'baz'])).to eq(['bar', 'baz'])
|
75
|
+
expect(r.drop(2, ['foo', 'bar', 'baz'])).to eq(['baz'])
|
76
|
+
expect(r.drop(3, ['foo', 'bar', 'baz'])).to eq([])
|
77
|
+
expect(r.drop(4, ['foo', 'bar', 'baz'])).to eq([])
|
78
|
+
expect(r.drop(3, 'ramda')).to eq('da')
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'is curried' do
|
82
|
+
expect(r.drop(3).call('ramda')).to eq('da')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context '#filter' do
|
87
|
+
def is_even
|
88
|
+
->(n) { n.even? }
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'from docs' do
|
92
|
+
expect(r.filter(is_even, [1, 2, 3, 4])).to eq([2, 4])
|
93
|
+
expect(r.filter(is_even, a: 1, b: 2, c: 3, d: 4)).to eq(b: 2, d: 4)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'is curried' do
|
97
|
+
expect(r.filter(is_even).call([1, 2, 3, 4])).to eq([2, 4])
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context '#find' do
|
102
|
+
it 'from docs' do
|
103
|
+
list = [{ a: 1 }, { a: 2 }, { a: 3 }]
|
104
|
+
|
105
|
+
expect(r.find(R.prop_eq(:a, 2), list)).to eq(a: 2)
|
106
|
+
expect(r.find(R.prop_eq(:a, 4), list)).to be_nil
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'is curried' do
|
110
|
+
list = [{ a: 1 }, { a: 2 }, { a: 3 }]
|
111
|
+
|
112
|
+
expect(r.find(R.prop_eq(:a, 2)).call(list)).to eq(a: 2)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context '#flatten' do
|
117
|
+
it 'from docs' do
|
118
|
+
expect(r.flatten([1, 2, [3, 4], 5, [6, [7, 8, [9, [10, 11], 12]]]]))
|
119
|
+
.to eq([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context '#group_by' do
|
124
|
+
it 'from docs' do
|
125
|
+
by_grade = lambda do |student|
|
126
|
+
case student.fetch(:score)
|
127
|
+
when 0...65 then 'F'
|
128
|
+
when 0...70 then 'D'
|
129
|
+
when 0...80 then 'C'
|
130
|
+
when 0...90 then 'B'
|
131
|
+
else
|
132
|
+
'A'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
students = [
|
136
|
+
{ name: 'Abby', score: 84 },
|
137
|
+
{ name: 'Eddy', score: 58 },
|
138
|
+
{ name: 'Jack', score: 69 }
|
139
|
+
]
|
140
|
+
expect(r.group_by(by_grade, students)).to eq(
|
141
|
+
'D' => [{ name: 'Jack', score: 69 }],
|
142
|
+
'F' => [{ name: 'Eddy', score: 58 }],
|
143
|
+
'B' => [{ name: 'Abby', score: 84 }]
|
144
|
+
)
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'is curried' do
|
148
|
+
students = [
|
149
|
+
{ name: 'Mike', age: 30 },
|
150
|
+
{ name: 'Tom', age: 25 },
|
151
|
+
{ name: 'Tom', age: 20 }
|
152
|
+
]
|
153
|
+
|
154
|
+
group_by_name = r.group_by(->(a) { a.fetch(:name) })
|
155
|
+
expect(group_by_name.call(students)).to eq(
|
156
|
+
'Tom' => [{ name: 'Tom', age: 25 }, { name: 'Tom', age: 20 }],
|
157
|
+
'Mike' => [{ name: 'Mike', age: 30 }]
|
158
|
+
)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context '#head' do
|
163
|
+
it 'from docs' do
|
164
|
+
expect(r.head(['fi', 'fo', 'fum'])).to eq('fi')
|
165
|
+
expect(r.head([])).to be_nil
|
166
|
+
expect(r.head('abc')).to eq('a')
|
167
|
+
expect(r.head('')).to eq('')
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context '#index_of' do
|
172
|
+
it 'from docs' do
|
173
|
+
expect(r.index_of(3, [1, 2, 3, 4])).to be(2)
|
174
|
+
expect(r.index_of(1, [1, 2, 3, 4])).to be(0)
|
175
|
+
expect(r.index_of(10, [1, 2, 3, 4])).to be(-1)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context '#join' do
|
180
|
+
it 'from docs' do
|
181
|
+
expect(r.join('|', [1, 2, 3])).to eq('1|2|3')
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'is curried' do
|
185
|
+
spacer = r.join(' ')
|
186
|
+
expect(spacer.call(['a', 2, 3.4])).to eq('a 2 3.4')
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context '#last_index_of' do
|
191
|
+
it 'from docs' do
|
192
|
+
expect(r.last_index_of(3, [-1, 3, 3, 0, 1, 2, 3, 4])).to be(6)
|
193
|
+
expect(r.last_index_of(10, [1, 2, 3, 4])).to be(-1)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context '#length' do
|
198
|
+
it 'from docs' do
|
199
|
+
expect(r.length([])).to eq(0)
|
200
|
+
expect(r.length([1, 2, 3])).to eq(3)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context '#map' do
|
205
|
+
it 'from docs' do
|
206
|
+
double_fn = ->(x) { x * 2 }
|
207
|
+
|
208
|
+
expect(r.map(double_fn, [1, 2, 3])).to eq([2, 4, 6])
|
209
|
+
expect(r.map(double_fn, x: 1, y: 2, z: 3)).to eq(x: 2, y: 4, z: 6)
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'is curried' do
|
213
|
+
double_fn = ->(x) { x * 2 }
|
214
|
+
|
215
|
+
expect(r.map(double_fn).call([1, 2, 3])).to eq([2, 4, 6])
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
context '#nth' do
|
220
|
+
it 'from docs' do
|
221
|
+
list = ['foo', 'bar', 'baz', 'quux']
|
222
|
+
expect(r.nth(1, list)).to eq('bar')
|
223
|
+
expect(r.nth(-1, list)).to eq('quux')
|
224
|
+
expect(r.nth(-99, list)).to be_nil
|
225
|
+
|
226
|
+
expect(r.nth(2, 'abc')).to eq('c')
|
227
|
+
expect(r.nth(3, 'abc')).to eq('')
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context '#pluck' do
|
232
|
+
it 'from docs' do
|
233
|
+
expect(r.pluck(:a).call([{ a: 1 }, { a: 2 }])).to eq([1, 2])
|
234
|
+
expect(r.pluck(0).call([[1, 2], [3, 4]])).to eq([1, 3])
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context '#prepend' do
|
239
|
+
it 'from docs' do
|
240
|
+
expect(r.prepend('fee').call(['fi', 'fo', 'fum'])).to eq(['fee', 'fi', 'fo', 'fum'])
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context '#range' do
|
245
|
+
it 'from docs' do
|
246
|
+
expect(r.range(1, 5)).to eq([1, 2, 3, 4])
|
247
|
+
expect(r.range(50, 53)).to eq([50, 51, 52])
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
context '#reduce' do
|
252
|
+
it 'from docs' do
|
253
|
+
# ((((0 - 1) - 2) - 3) - 4) = -10
|
254
|
+
expect(r.reduce(R.subtract, 0, [1, 2, 3, 4])).to be(-10)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
context '#reduce_right' do
|
259
|
+
def avg
|
260
|
+
->(a, b) { (a + b) / 2 }
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'from docs' do
|
264
|
+
# (1 - (2 - (3 - (4 - 0)))))
|
265
|
+
expect(r.reduce_right(R.subtract, 0, [1, 2, 3, 4])).to be(-2)
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'returns the accumulator for an empty array' do
|
269
|
+
expect(r.reduce_right(avg, 0, [])).to eq(0)
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'is curried' do
|
273
|
+
something = r.reduce_right(avg, 54)
|
274
|
+
rcat = r.reduce_right(R.concat, '')
|
275
|
+
expect(something.call([12, 4, 10, 6])).to eq(12)
|
276
|
+
expect(rcat.call(['1', '2', '3', '4'])).to eq('1234')
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
context '#reverse' do
|
281
|
+
it 'from docs' do
|
282
|
+
expect(r.reverse([1, 2, 3])).to eq([3, 2, 1])
|
283
|
+
expect(r.reverse([1, 2])).to eq([2, 1])
|
284
|
+
expect(r.reverse([1])).to eq([1])
|
285
|
+
expect(r.reverse([])).to eq([])
|
286
|
+
|
287
|
+
expect(r.reverse('abc')).to eq('cba')
|
288
|
+
expect(r.reverse('ab')).to eq('ba')
|
289
|
+
expect(r.reverse('a')).to eq('a')
|
290
|
+
expect(r.reverse('')).to eq('')
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
context '#reject' do
|
295
|
+
it 'from docs' do
|
296
|
+
is_odd = ->(n) { n.odd? }
|
297
|
+
|
298
|
+
expect(r.reject(is_odd, [1, 2, 3, 4])).to eq([2, 4])
|
299
|
+
expect(r.reject(is_odd, a: 1, b: 2, c: 3, d: 4)).to eq(b: 2, d: 4)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
context '#sort' do
|
304
|
+
it 'from docs' do
|
305
|
+
diff = ->(a, b) { a - b }
|
306
|
+
expect(r.sort(diff, [4, 2, 7, 5])).to eq([2, 4, 5, 7])
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
context '#tail' do
|
311
|
+
it 'from docs' do
|
312
|
+
expect(r.tail([1, 2, 3])).to eq([2, 3])
|
313
|
+
expect(r.tail([1, 2])).to eq([2])
|
314
|
+
expect(r.tail([1])).to eq([])
|
315
|
+
expect(r.tail([])).to eq([])
|
316
|
+
|
317
|
+
expect(r.tail('abc')).to eq('bc')
|
318
|
+
expect(r.tail('ab')).to eq('b')
|
319
|
+
expect(r.tail('a')).to eq('')
|
320
|
+
expect(r.tail('')).to eq('')
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
context '#take' do
|
325
|
+
it 'is curried' do
|
326
|
+
personnel = [
|
327
|
+
'Dave Brubeck',
|
328
|
+
'Paul Desmond',
|
329
|
+
'Eugene Wright',
|
330
|
+
'Joe Morello',
|
331
|
+
'Gerry Mulligan',
|
332
|
+
'Bob Bates',
|
333
|
+
'Joe Dodge',
|
334
|
+
'Ron Crotty'
|
335
|
+
]
|
336
|
+
|
337
|
+
take_five = r.take(5)
|
338
|
+
expect(take_five.call(personnel)).to eq(
|
339
|
+
['Dave Brubeck', 'Paul Desmond', 'Eugene Wright', 'Joe Morello', 'Gerry Mulligan']
|
340
|
+
)
|
341
|
+
end
|
342
|
+
|
343
|
+
it 'can operate on arrays' do
|
344
|
+
expect(r.take(10, [])).to eq([])
|
345
|
+
expect(r.take(4, ['foo', 'bar', 'baz'])).to eq(['foo', 'bar', 'baz'])
|
346
|
+
expect(r.take(3, ['foo', 'bar', 'baz'])).to eq(['foo', 'bar', 'baz'])
|
347
|
+
expect(r.take(2, ['foo', 'bar', 'baz'])).to eq(['foo', 'bar'])
|
348
|
+
expect(r.take(1, ['foo', 'bar', 'baz'])).to eq(['foo'])
|
349
|
+
expect(r.take(0, ['foo', 'bar', 'baz'])).to eq([])
|
350
|
+
end
|
351
|
+
|
352
|
+
it 'can operate on strings' do
|
353
|
+
expect(r.take(10, 'Ramda')).to eq('Ramda')
|
354
|
+
expect(r.take(3, 'Ramda')).to eq('Ram')
|
355
|
+
expect(r.take(2, 'Ramda')).to eq('Ra')
|
356
|
+
expect(r.take(1, 'Ramda')).to eq('R')
|
357
|
+
expect(r.take(0, 'Ramda')).to eq('')
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
context '#take_while' do
|
362
|
+
it 'from docs' do
|
363
|
+
is_not_four = ->(x) { x != 4 }
|
364
|
+
|
365
|
+
expect(r.take_while(is_not_four, [1, 2, 3, 4, 3, 2, 1])).to eq([1, 2, 3])
|
366
|
+
expect(r.take_while(is_not_four, [1, 2, 3])).to eq([1, 2, 3])
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
context '#uniq' do
|
371
|
+
it 'from docs' do
|
372
|
+
expect(r.uniq([1, 1, 2, 1])).to eq([1, 2])
|
373
|
+
expect(r.uniq([1, '1'])).to eq([1, '1'])
|
374
|
+
expect(r.uniq([[42], [42]])).to eq([[42]])
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
context '#xprod' do
|
379
|
+
it 'from docs' do
|
380
|
+
expect(r.xprod([1, 2], ['a', 'b']))
|
381
|
+
.to eq([[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']])
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
context '#zip' do
|
386
|
+
it 'from docs' do
|
387
|
+
expect(r.zip([1, 2, 3], ['a', 'b', 'c'])).to eq([[1, 'a'], [2, 'b'], [3, 'c']])
|
388
|
+
expect(r.zip([1, 2, 3], ['a', 'b', 'c', 'd'])).to eq([[1, 'a'], [2, 'b'], [3, 'c']])
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
context '#zip_with' do
|
393
|
+
it 'from docs' do
|
394
|
+
f = ->(x, y) { Ramda.join('', [x, y]) }
|
395
|
+
|
396
|
+
expect(r.zip_with(f, [1, 2, 3], ['a', 'b', 'c'])).to eq(['1a', '2b', '3c'])
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|