functional-ruby 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/README.md +37 -17
- data/doc/record.txt +63 -0
- data/doc/thread_safety.txt +9 -0
- data/lib/functional.rb +4 -0
- data/lib/functional/abstract_struct.rb +4 -2
- data/lib/functional/delay.rb +2 -0
- data/lib/functional/either.rb +2 -0
- data/lib/functional/final_struct.rb +231 -0
- data/lib/functional/final_var.rb +163 -0
- data/lib/functional/memo.rb +4 -0
- data/lib/functional/method_signature.rb +2 -0
- data/lib/functional/option.rb +2 -0
- data/lib/functional/pattern_matching.rb +1 -0
- data/lib/functional/protocol.rb +2 -0
- data/lib/functional/protocol_info.rb +3 -0
- data/lib/functional/record.rb +4 -2
- data/lib/functional/tuple.rb +247 -0
- data/lib/functional/type_check.rb +2 -0
- data/lib/functional/union.rb +2 -0
- data/lib/functional/value_struct.rb +144 -0
- data/lib/functional/version.rb +1 -1
- data/spec/functional/final_struct_spec.rb +266 -0
- data/spec/functional/final_var_spec.rb +169 -0
- data/spec/functional/record_spec.rb +30 -1
- data/spec/functional/tuple_spec.rb +679 -0
- data/spec/functional/value_struct_spec.rb +199 -0
- metadata +19 -4
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module Functional
|
5
|
+
|
6
|
+
describe ValueStruct do
|
7
|
+
|
8
|
+
context 'instanciation' do
|
9
|
+
|
10
|
+
specify 'raises an exception when no arguments given' do
|
11
|
+
expect {
|
12
|
+
ValueStruct.new
|
13
|
+
}.to raise_error(ArgumentError)
|
14
|
+
end
|
15
|
+
|
16
|
+
specify 'with a hash sets fields using has values' do
|
17
|
+
subject = ValueStruct.new(foo: 1, 'bar' => :two, baz: 'three')
|
18
|
+
expect(subject.foo).to eq 1
|
19
|
+
expect(subject.bar).to eq :two
|
20
|
+
expect(subject.baz).to eq 'three'
|
21
|
+
end
|
22
|
+
|
23
|
+
specify 'with a hash creates true predicates for has keys' do
|
24
|
+
subject = ValueStruct.new(foo: 1, 'bar' => :two, baz: 'three')
|
25
|
+
expect(subject.foo?).to be true
|
26
|
+
expect(subject.bar?).to be true
|
27
|
+
expect(subject.baz?).to be true
|
28
|
+
end
|
29
|
+
|
30
|
+
specify 'can be created from any object that responds to #each_pair' do
|
31
|
+
clazz = Class.new do
|
32
|
+
def each_pair(&block)
|
33
|
+
{answer: 42, harmless: 'mostly'}.each_pair(&block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
struct = clazz.new
|
37
|
+
subject = ValueStruct.new(struct)
|
38
|
+
expect(subject.answer).to eq 42
|
39
|
+
expect(subject.harmless).to eq 'mostly'
|
40
|
+
end
|
41
|
+
|
42
|
+
specify 'raises an exception if given a non-hash argument' do
|
43
|
+
expect {
|
44
|
+
ValueStruct.new(:bogus)
|
45
|
+
}.to raise_error(ArgumentError)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'set fields' do
|
50
|
+
|
51
|
+
subject { ValueStruct.new(foo: 42, bar: "Don't Panic") }
|
52
|
+
|
53
|
+
specify 'have a reader which returns the value' do
|
54
|
+
expect(subject.foo).to eq 42
|
55
|
+
expect(subject.bar).to eq "Don't Panic"
|
56
|
+
end
|
57
|
+
|
58
|
+
specify 'have a predicate which returns true' do
|
59
|
+
expect(subject.foo?).to be true
|
60
|
+
expect(subject.bar?).to be true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'unset fields' do
|
65
|
+
|
66
|
+
subject { ValueStruct.new(foo: 42, bar: "Don't Panic") }
|
67
|
+
|
68
|
+
specify 'have a magic predicate that always returns false' do
|
69
|
+
expect(subject.baz?).to be false
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'accessors' do
|
74
|
+
|
75
|
+
let!(:field_value_pairs) { {foo: 1, bar: :two, baz: 'three'} }
|
76
|
+
|
77
|
+
subject { ValueStruct.new(field_value_pairs) }
|
78
|
+
|
79
|
+
specify '#get returns the value of a set field' do
|
80
|
+
expect(subject.get(:foo)).to eq 1
|
81
|
+
end
|
82
|
+
|
83
|
+
specify '#get returns nil for an unset field' do
|
84
|
+
expect(subject.get(:bogus)).to be nil
|
85
|
+
end
|
86
|
+
|
87
|
+
specify '#[] is an alias for #get' do
|
88
|
+
expect(subject[:foo]).to eq 1
|
89
|
+
expect(subject[:bogus]).to be nil
|
90
|
+
end
|
91
|
+
|
92
|
+
specify '#set? returns false for an unset field' do
|
93
|
+
expect(subject.set?(:harmless)).to be false
|
94
|
+
end
|
95
|
+
|
96
|
+
specify '#set? returns true for a field that has been set' do
|
97
|
+
subject = ValueStruct.new(harmless: 'mostly')
|
98
|
+
expect(subject.set?(:harmless)).to be true
|
99
|
+
end
|
100
|
+
|
101
|
+
specify '#fetch gets the value of a set field' do
|
102
|
+
subject = ValueStruct.new(harmless: 'mostly')
|
103
|
+
expect(subject.fetch(:harmless, 'extremely')).to eq 'mostly'
|
104
|
+
end
|
105
|
+
|
106
|
+
specify '#fetch returns the given value when the field is unset' do
|
107
|
+
expect(subject.fetch(:harmless, 'extremely')).to eq 'extremely'
|
108
|
+
end
|
109
|
+
|
110
|
+
specify '#fetch does not set an unset field' do
|
111
|
+
subject.fetch(:answer, 42)
|
112
|
+
expect {
|
113
|
+
subject.answer
|
114
|
+
}.to raise_error(NoMethodError)
|
115
|
+
end
|
116
|
+
|
117
|
+
specify '#to_h returns the key/value pairs for all set values' do
|
118
|
+
subject = ValueStruct.new(field_value_pairs)
|
119
|
+
expect(subject.to_h).to eq field_value_pairs
|
120
|
+
expect(subject.to_h).to_not be_frozen
|
121
|
+
end
|
122
|
+
|
123
|
+
specify '#each_pair returns an Enumerable when no block given' do
|
124
|
+
subject = ValueStruct.new(field_value_pairs)
|
125
|
+
expect(subject.each_pair).to be_a Enumerable
|
126
|
+
end
|
127
|
+
|
128
|
+
specify '#each_pair enumerates over each field/value pair' do
|
129
|
+
subject = ValueStruct.new(field_value_pairs)
|
130
|
+
result = {}
|
131
|
+
|
132
|
+
subject.each_pair do |field, value|
|
133
|
+
result[field] = value
|
134
|
+
end
|
135
|
+
|
136
|
+
expect(result).to eq field_value_pairs
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'reflection' do
|
141
|
+
|
142
|
+
specify '#eql? returns true when both define the same fields with the same values' do
|
143
|
+
first = ValueStruct.new(foo: 1, 'bar' => :two, baz: 'three')
|
144
|
+
second = ValueStruct.new(foo: 1, 'bar' => :two, baz: 'three')
|
145
|
+
|
146
|
+
expect(first.eql?(second)).to be true
|
147
|
+
expect(first == second).to be true
|
148
|
+
end
|
149
|
+
|
150
|
+
specify '#eql? returns false when other has different fields defined' do
|
151
|
+
first = ValueStruct.new(foo: 1, 'bar' => :two, baz: 'three')
|
152
|
+
second = ValueStruct.new(foo: 1, 'bar' => :two)
|
153
|
+
|
154
|
+
expect(first.eql?(second)).to be false
|
155
|
+
expect(first == second).to be false
|
156
|
+
end
|
157
|
+
|
158
|
+
specify '#eql? returns false when other has different field values' do
|
159
|
+
first = ValueStruct.new(foo: 1, 'bar' => :two, baz: 'three')
|
160
|
+
second = ValueStruct.new(foo: 1, 'bar' => :two, baz: 3)
|
161
|
+
|
162
|
+
expect(first.eql?(second)).to be false
|
163
|
+
expect(first == second).to be false
|
164
|
+
end
|
165
|
+
|
166
|
+
specify '#eql? returns false when other is not a ValueStruct' do
|
167
|
+
attributes = {answer: 42, harmless: 'mostly'}
|
168
|
+
clazz = Class.new do
|
169
|
+
def to_h; {answer: 42, harmless: 'mostly'}; end
|
170
|
+
end
|
171
|
+
|
172
|
+
other = clazz.new
|
173
|
+
subject = ValueStruct.new(attributes)
|
174
|
+
|
175
|
+
expect(subject.eql?(other)).to be false
|
176
|
+
expect(subject == other).to be false
|
177
|
+
end
|
178
|
+
|
179
|
+
specify '#inspect begins with the class name' do
|
180
|
+
subject = ValueStruct.new(foo: 1, 'bar' => :two, baz: 'three')
|
181
|
+
expect(subject.inspect).to match(/^#<#{described_class}\s+/)
|
182
|
+
end
|
183
|
+
|
184
|
+
specify '#inspect includes all field/value pairs' do
|
185
|
+
field_value_pairs = {foo: 1, 'bar' => :two, baz: 'three'}
|
186
|
+
subject = ValueStruct.new(field_value_pairs)
|
187
|
+
|
188
|
+
field_value_pairs.each do |field, value|
|
189
|
+
expect(subject.inspect).to match(/:#{field}=>"?:?#{value}"?/)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
specify '#to_s returns the same value as #inspect' do
|
194
|
+
subject = ValueStruct.new(foo: 1, 'bar' => :two, baz: 'three')
|
195
|
+
expect(subject.to_s).to eq subject.inspect
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
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: 1.
|
4
|
+
version: 1.1.0
|
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: 2014-
|
11
|
+
date: 2014-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -25,19 +25,21 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
description: |2
|
28
|
-
A gem for adding
|
28
|
+
A gem for adding functional programming tools to Ruby. Inspired by Erlang, Clojure, Haskell, and Functional Java.
|
29
29
|
email: jerry.dantonio@gmail.com
|
30
30
|
executables: []
|
31
31
|
extensions: []
|
32
32
|
extra_rdoc_files:
|
33
33
|
- README.md
|
34
34
|
- LICENSE
|
35
|
+
- CHANGELOG.md
|
35
36
|
- doc/memo.txt
|
36
37
|
- doc/pattern_matching.txt
|
37
38
|
- doc/protocol.txt
|
38
39
|
- doc/record.txt
|
39
40
|
- doc/thread_safety.txt
|
40
41
|
files:
|
42
|
+
- CHANGELOG.md
|
41
43
|
- LICENSE
|
42
44
|
- README.md
|
43
45
|
- doc/memo.txt
|
@@ -49,6 +51,8 @@ files:
|
|
49
51
|
- lib/functional/abstract_struct.rb
|
50
52
|
- lib/functional/delay.rb
|
51
53
|
- lib/functional/either.rb
|
54
|
+
- lib/functional/final_struct.rb
|
55
|
+
- lib/functional/final_var.rb
|
52
56
|
- lib/functional/memo.rb
|
53
57
|
- lib/functional/method_signature.rb
|
54
58
|
- lib/functional/option.rb
|
@@ -56,8 +60,10 @@ files:
|
|
56
60
|
- lib/functional/protocol.rb
|
57
61
|
- lib/functional/protocol_info.rb
|
58
62
|
- lib/functional/record.rb
|
63
|
+
- lib/functional/tuple.rb
|
59
64
|
- lib/functional/type_check.rb
|
60
65
|
- lib/functional/union.rb
|
66
|
+
- lib/functional/value_struct.rb
|
61
67
|
- lib/functional/version.rb
|
62
68
|
- lib/functional_ruby.rb
|
63
69
|
- spec/functional/abstract_struct_shared.rb
|
@@ -65,14 +71,18 @@ files:
|
|
65
71
|
- spec/functional/configuration_spec.rb
|
66
72
|
- spec/functional/delay_spec.rb
|
67
73
|
- spec/functional/either_spec.rb
|
74
|
+
- spec/functional/final_struct_spec.rb
|
75
|
+
- spec/functional/final_var_spec.rb
|
68
76
|
- spec/functional/memo_spec.rb
|
69
77
|
- spec/functional/option_spec.rb
|
70
78
|
- spec/functional/pattern_matching_spec.rb
|
71
79
|
- spec/functional/protocol_info_spec.rb
|
72
80
|
- spec/functional/protocol_spec.rb
|
73
81
|
- spec/functional/record_spec.rb
|
82
|
+
- spec/functional/tuple_spec.rb
|
74
83
|
- spec/functional/type_check_spec.rb
|
75
84
|
- spec/functional/union_spec.rb
|
85
|
+
- spec/functional/value_struct_spec.rb
|
76
86
|
- spec/spec_helper.rb
|
77
87
|
homepage: https://github.com/jdantonio/functional-ruby/
|
78
88
|
licenses:
|
@@ -97,20 +107,25 @@ rubyforge_project:
|
|
97
107
|
rubygems_version: 2.2.2
|
98
108
|
signing_key:
|
99
109
|
specification_version: 4
|
100
|
-
summary: Erlang, Clojure, and
|
110
|
+
summary: Erlang, Clojure, Haskell, and Functional Java inspired functional programming
|
111
|
+
tools for Ruby.
|
101
112
|
test_files:
|
102
113
|
- spec/functional/abstract_struct_shared.rb
|
103
114
|
- spec/functional/complex_pattern_matching_spec.rb
|
104
115
|
- spec/functional/configuration_spec.rb
|
105
116
|
- spec/functional/delay_spec.rb
|
106
117
|
- spec/functional/either_spec.rb
|
118
|
+
- spec/functional/final_struct_spec.rb
|
119
|
+
- spec/functional/final_var_spec.rb
|
107
120
|
- spec/functional/memo_spec.rb
|
108
121
|
- spec/functional/option_spec.rb
|
109
122
|
- spec/functional/pattern_matching_spec.rb
|
110
123
|
- spec/functional/protocol_info_spec.rb
|
111
124
|
- spec/functional/protocol_spec.rb
|
112
125
|
- spec/functional/record_spec.rb
|
126
|
+
- spec/functional/tuple_spec.rb
|
113
127
|
- spec/functional/type_check_spec.rb
|
114
128
|
- spec/functional/union_spec.rb
|
129
|
+
- spec/functional/value_struct_spec.rb
|
115
130
|
- spec/spec_helper.rb
|
116
131
|
has_rdoc:
|