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.
@@ -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.0.0
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-07-30 00:00:00.000000000 Z
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 Erlang, Clojure, and Go inspired functional programming tools to Ruby.
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 Haskell inspired functional programming tools to Ruby.
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: