functional-ruby 0.7.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +92 -152
  3. data/doc/memo.txt +192 -0
  4. data/doc/pattern_matching.txt +485 -0
  5. data/doc/protocol.txt +221 -0
  6. data/doc/record.txt +144 -0
  7. data/doc/thread_safety.txt +8 -0
  8. data/lib/functional.rb +48 -18
  9. data/lib/functional/abstract_struct.rb +161 -0
  10. data/lib/functional/delay.rb +117 -0
  11. data/lib/functional/either.rb +222 -0
  12. data/lib/functional/memo.rb +93 -0
  13. data/lib/functional/method_signature.rb +72 -0
  14. data/lib/functional/option.rb +209 -0
  15. data/lib/functional/pattern_matching.rb +117 -100
  16. data/lib/functional/protocol.rb +157 -0
  17. data/lib/functional/protocol_info.rb +193 -0
  18. data/lib/functional/record.rb +155 -0
  19. data/lib/functional/type_check.rb +112 -0
  20. data/lib/functional/union.rb +152 -0
  21. data/lib/functional/version.rb +3 -1
  22. data/spec/functional/abstract_struct_shared.rb +154 -0
  23. data/spec/functional/complex_pattern_matching_spec.rb +205 -0
  24. data/spec/functional/configuration_spec.rb +17 -0
  25. data/spec/functional/delay_spec.rb +147 -0
  26. data/spec/functional/either_spec.rb +237 -0
  27. data/spec/functional/memo_spec.rb +207 -0
  28. data/spec/functional/option_spec.rb +292 -0
  29. data/spec/functional/pattern_matching_spec.rb +279 -276
  30. data/spec/functional/protocol_info_spec.rb +444 -0
  31. data/spec/functional/protocol_spec.rb +274 -0
  32. data/spec/functional/record_spec.rb +175 -0
  33. data/spec/functional/type_check_spec.rb +103 -0
  34. data/spec/functional/union_spec.rb +110 -0
  35. data/spec/spec_helper.rb +6 -4
  36. metadata +55 -45
  37. data/lib/functional/behavior.rb +0 -138
  38. data/lib/functional/behaviour.rb +0 -2
  39. data/lib/functional/catalog.rb +0 -487
  40. data/lib/functional/collection.rb +0 -403
  41. data/lib/functional/inflect.rb +0 -127
  42. data/lib/functional/platform.rb +0 -120
  43. data/lib/functional/search.rb +0 -132
  44. data/lib/functional/sort.rb +0 -41
  45. data/lib/functional/utilities.rb +0 -189
  46. data/md/behavior.md +0 -188
  47. data/md/catalog.md +0 -32
  48. data/md/collection.md +0 -32
  49. data/md/inflect.md +0 -32
  50. data/md/pattern_matching.md +0 -512
  51. data/md/platform.md +0 -32
  52. data/md/search.md +0 -32
  53. data/md/sort.md +0 -32
  54. data/md/utilities.md +0 -55
  55. data/spec/functional/behavior_spec.rb +0 -528
  56. data/spec/functional/catalog_spec.rb +0 -1206
  57. data/spec/functional/collection_spec.rb +0 -752
  58. data/spec/functional/inflect_spec.rb +0 -85
  59. data/spec/functional/integration_spec.rb +0 -205
  60. data/spec/functional/platform_spec.rb +0 -501
  61. data/spec/functional/search_spec.rb +0 -187
  62. data/spec/functional/sort_spec.rb +0 -61
  63. data/spec/functional/utilities_spec.rb +0 -277
@@ -0,0 +1,175 @@
1
+ require 'spec_helper'
2
+ require_relative 'abstract_struct_shared'
3
+
4
+ module Functional
5
+
6
+ describe Record do
7
+
8
+ let!(:expected_fields){ [:a, :b, :c] }
9
+ let!(:expected_values){ [42, nil, nil] }
10
+
11
+ let(:struct_class) { Record.new(*expected_fields) }
12
+ let(:struct_object) { struct_class.new(struct_class.fields.first => 42) }
13
+ let(:other_object) { struct_class.new(struct_class.fields.first => Object.new) }
14
+
15
+ it_should_behave_like :abstract_struct
16
+
17
+ context 'definition' do
18
+
19
+ it 'registers the new class with Record when given a string name' do
20
+ Record.new('Foo', :foo, :bar, :baz)
21
+ expect(defined?(Record::Foo)).to eq 'constant'
22
+ end
23
+
24
+ it 'default all fields values to nil' do
25
+ fields = [:foo, :bar, :baz]
26
+ clazz = Record.new(*fields)
27
+
28
+ record = clazz.new
29
+
30
+ fields.each do |field|
31
+ expect(record.send(field)).to be_nil
32
+ end
33
+ end
34
+
35
+ it 'sets initial values based on values given at object construction' do
36
+ clazz = Record.new(:foo, :bar, :baz)
37
+ record = clazz.new(foo: 1, bar: 2, baz: 3)
38
+
39
+ expect(record.foo).to eq 1
40
+ expect(record.bar).to eq 2
41
+ expect(record.baz).to eq 3
42
+ end
43
+
44
+ it 'defaults fields to values given during class creation' do
45
+ clazz = Record.new(:foo, :bar, :baz) do
46
+ default :foo, 42
47
+ default :bar, 'w00t!'
48
+ end
49
+
50
+ record = clazz.new
51
+ expect(record.foo).to eq 42
52
+ expect(record.bar).to eq 'w00t!'
53
+ expect(record.baz).to be_nil
54
+ end
55
+
56
+ it 'overrides default values with values provided at object construction' do
57
+ clazz = Record.new(:foo, :bar, :baz) do
58
+ default :foo, 42
59
+ default :bar, 'w00t!'
60
+ default :baz, :bogus
61
+ end
62
+
63
+ record = clazz.new(foo: 1, bar: 2)
64
+
65
+ expect(record.foo).to eq 1
66
+ expect(record.bar).to eq 2
67
+ expect(record.baz).to eq :bogus
68
+ end
69
+
70
+ it 'duplicates default values when assigning to a new object' do
71
+ original = 'Foo'
72
+ clazz = Record.new(:foo, :bar, :baz) do
73
+ default :foo, original
74
+ end
75
+
76
+ record = clazz.new
77
+ expect(record.foo).to eq original
78
+ expect(record.foo.object_id).to_not eql original.object_id
79
+ end
80
+
81
+ it 'does not conflate defaults across record classes' do
82
+ clazz_foo = Record.new(:foo, :bar, :baz) do
83
+ default :foo, 42
84
+ end
85
+
86
+ clazz_matz = Record.new(:foo, :bar, :baz) do
87
+ default :foo, 'Matsumoto'
88
+ end
89
+
90
+ expect(clazz_foo.new.foo).to eq 42
91
+ expect(clazz_matz.new.foo).to eq 'Matsumoto'
92
+ end
93
+
94
+ it 'raises an exception when values for requred field are not provided' do
95
+ clazz = Record.new(:foo, :bar, :baz) do
96
+ mandatory :foo
97
+ end
98
+
99
+ expect {
100
+ clazz.new(bar: 1)
101
+ }.to raise_exception(ArgumentError)
102
+ end
103
+
104
+ it 'raises an exception when required values are nil' do
105
+ clazz = Record.new(:foo, :bar, :baz) do
106
+ mandatory :foo
107
+ end
108
+
109
+ expect {
110
+ clazz.new(foo: nil, bar: 1)
111
+ }.to raise_exception(ArgumentError)
112
+ end
113
+
114
+ it 'allows a field to be required and have a default value' do
115
+ clazz = Record.new(:foo, :bar, :baz) do
116
+ mandatory :foo
117
+ default :foo, 42
118
+ end
119
+
120
+ expect {
121
+ clazz.new
122
+ }.to_not raise_exception
123
+
124
+ expect(clazz.new.foo).to eq 42
125
+ end
126
+
127
+ it 'allows multiple required fields to be specified together' do
128
+ clazz = Record.new(:foo, :bar, :baz) do
129
+ mandatory :foo, :bar, :baz
130
+ end
131
+
132
+ expect {
133
+ clazz.new(foo: 1, bar: 2)
134
+ }.to raise_exception(ArgumentError)
135
+
136
+ expect {
137
+ clazz.new(bar: 2, baz: 3)
138
+ }.to raise_exception(ArgumentError)
139
+
140
+ expect {
141
+ clazz.new(foo: 1, bar: 2, baz: 3)
142
+ }.to_not raise_exception
143
+ end
144
+
145
+ it 'raises an exception if the default value for a require field is nil' do
146
+ clazz = Record.new(:foo, :bar, :baz) do
147
+ mandatory :foo
148
+ default :foo, nil
149
+ end
150
+
151
+ expect {
152
+ clazz.new
153
+ }.to raise_exception(ArgumentError)
154
+ end
155
+
156
+ it 'does not conflate default values across record classes' do
157
+ clazz_foo = Record.new(:foo, :bar, :baz) do
158
+ mandatory :foo
159
+ end
160
+
161
+ clazz_baz = Record.new(:foo, :bar, :baz) do
162
+ mandatory :baz
163
+ end
164
+
165
+ expect {
166
+ clazz_foo.new(foo: 42)
167
+ }.to_not raise_error
168
+
169
+ expect {
170
+ clazz_baz.new(baz: 42)
171
+ }.to_not raise_error
172
+ end
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,103 @@
1
+ require 'spec_helper'
2
+
3
+ module Functional
4
+
5
+ describe TypeCheck do
6
+
7
+ context 'Type?' do
8
+
9
+ it 'returns true when value is of any of the types' do
10
+ target = 'foo'
11
+ expect(TypeCheck.Type?(target, String, Array, Hash)).to be true
12
+ end
13
+
14
+ it 'returns false when value is not of any of the types' do
15
+ target = 'foo'
16
+ expect(TypeCheck.Type?(target, Fixnum, Array, Hash)).to be false
17
+ end
18
+ end
19
+
20
+ context 'Type!' do
21
+
22
+ it 'returns the value when value is of any of the types' do
23
+ target = 'foo'
24
+ expect(TypeCheck.Type!(target, String, Array, Hash)).to be target
25
+ end
26
+
27
+ it 'raises an exception when value is not of any of the types' do
28
+ target = 'foo'
29
+ expect {
30
+ TypeCheck.Type!(target, Fixnum, Array, Hash)
31
+ }.to raise_error(TypeError)
32
+ end
33
+ end
34
+
35
+ context 'Match?' do
36
+
37
+ it 'returns true when value is an exact match for at least one of the types' do
38
+ target = 'foo'
39
+ expect(TypeCheck.Match?(target, String, Array, Hash)).to be true
40
+ end
41
+
42
+ it 'returns false when value is not an exact match for at least one of the types' do
43
+ target = 'foo'
44
+ expect(TypeCheck.Match?(target, Fixnum, Array, Hash)).to be false
45
+ end
46
+ end
47
+
48
+ context 'Match!' do
49
+
50
+ it 'returns the value when value is an exact match for at least one of the types' do
51
+ target = 'foo'
52
+ expect(TypeCheck.Match!(target, String, Array, Hash)).to eq target
53
+ end
54
+
55
+ it 'raises an exception when value is not an exact match for at least one of the types' do
56
+ target = 'foo'
57
+ expect {
58
+ expect(TypeCheck.Match!(target, Fixnum, Array, Hash)).to eq target
59
+ }.to raise_error(TypeError)
60
+ end
61
+ end
62
+
63
+ context 'Child?' do
64
+
65
+ it 'returns true if value is a class and is also a match or subclass of one of types' do
66
+ target = String
67
+ expect(TypeCheck.Child?(target, Comparable, Array, Hash)).to be true
68
+ end
69
+
70
+ it 'returns false if value is not a class' do
71
+ target = 'foo'
72
+ expect(TypeCheck.Child?(target, Comparable, Array, Hash)).to be false
73
+ end
74
+
75
+ it 'returns false if value is not a subclass/match for any of the types' do
76
+ target = Fixnum
77
+ expect(TypeCheck.Child?(target, Symbol, Array, Hash)).to be false
78
+ end
79
+ end
80
+
81
+ context 'Child!' do
82
+
83
+ it 'returns the value if value is a class and is also a match or subclass of one of types' do
84
+ target = String
85
+ expect(TypeCheck.Child!(target, Comparable, Array, Hash)).to eq target
86
+ end
87
+
88
+ it 'raises an exception if value is not a class' do
89
+ target = 'foo'
90
+ expect {
91
+ TypeCheck.Child!(target, Comparable, Array, Hash)
92
+ }.to raise_error(TypeError)
93
+ end
94
+
95
+ it 'raises an exception if value is not a subclass/match for any of the types' do
96
+ target = Fixnum
97
+ expect {
98
+ TypeCheck.Child!(target, Symbol, Array, Hash)
99
+ }.to raise_error(TypeError)
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,110 @@
1
+ require 'spec_helper'
2
+ require_relative 'abstract_struct_shared'
3
+
4
+ module Functional
5
+
6
+ describe Union do
7
+
8
+ let!(:expected_fields){ [:a, :b, :c] }
9
+ let!(:expected_values){ [42, nil, nil] }
10
+
11
+ let(:struct_class) { Union.new(*expected_fields) }
12
+ let(:struct_object) { struct_class.send(struct_class.fields.first, 42) }
13
+ let(:other_object) { struct_class.send(struct_class.fields.first, Object.new) }
14
+
15
+ it_should_behave_like :abstract_struct
16
+
17
+ context 'definition' do
18
+
19
+ it 'registers the new class with Record when given a string name' do
20
+ Union.new('Foo', :foo, :bar, :baz)
21
+ expect(defined?(Union::Foo)).to eq 'constant'
22
+ end
23
+ end
24
+
25
+ context 'factories' do
26
+
27
+ specify 'exist for each field' do
28
+ expected_fields.each do |field|
29
+ expect(struct_class).to respond_to(field)
30
+ end
31
+ end
32
+
33
+ specify 'require a value' do
34
+ expected_fields.each do |field|
35
+ expect(struct_class.method(field).arity).to eq 1
36
+ end
37
+ end
38
+
39
+ specify 'set the field appropriately' do
40
+ clazz = Union.new(:foo, :bar)
41
+ obj = clazz.foo(10)
42
+ expect(obj.field).to eq :foo
43
+ end
44
+
45
+ specify 'set the value appropriately' do
46
+ clazz = Union.new(:foo, :bar)
47
+ obj = clazz.foo(10)
48
+ expect(obj.value).to eq 10
49
+ end
50
+
51
+ specify 'return a frozen union' do
52
+ clazz = Union.new(:foo, :bar)
53
+ expect(clazz.foo(10)).to be_frozen
54
+ end
55
+
56
+ specify 'force #new to be private' do
57
+ clazz = Union.new(:foo, :bar)
58
+ expect {
59
+ clazz.new
60
+ }.to raise_error(NoMethodError)
61
+ end
62
+ end
63
+
64
+ context 'readers' do
65
+
66
+ specify '#field returns the appropriate field' do
67
+ clazz = Union.new(:foo, :bar)
68
+ expect(clazz.foo(10).field).to eq :foo
69
+ end
70
+
71
+ specify '#value returns the appropriate field' do
72
+ clazz = Union.new(:foo, :bar)
73
+ expect(clazz.foo(10).value).to eq 10
74
+ end
75
+
76
+ specify 'return the appropriate value for the set field' do
77
+ clazz = Union.new(:foo, :bar)
78
+ expect(clazz.foo(10).foo).to eq 10
79
+ end
80
+
81
+ specify 'return nil for the unset field' do
82
+ clazz = Union.new(:foo, :bar, :baz)
83
+ expect(clazz.foo(10).bar).to be_nil
84
+ expect(clazz.foo(10).baz).to be_nil
85
+ end
86
+ end
87
+
88
+ context 'predicates' do
89
+
90
+ specify 'exist for each field' do
91
+ expected_fields.each do |field|
92
+ predicate = "#{field}?".to_sym
93
+ expect(struct_object).to respond_to(predicate)
94
+ expect(struct_object.method(predicate).arity).to eq 0
95
+ end
96
+ end
97
+
98
+ specify 'return true for the set field' do
99
+ clazz = Union.new(:foo, :bar)
100
+ expect(clazz.foo(10).foo?).to be true
101
+ end
102
+
103
+ specify 'return false for the unset fields' do
104
+ clazz = Union.new(:foo, :bar, :baz)
105
+ expect(clazz.foo(10).bar?).to be false
106
+ expect(clazz.foo(10).baz?).to be false
107
+ end
108
+ end
109
+ end
110
+ end
@@ -7,13 +7,15 @@ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
7
7
  ]
8
8
 
9
9
  SimpleCov.start do
10
- project_name 'functional-ruby'
11
- add_filter '/md/'
12
- add_filter '/pkg/'
10
+ project_name 'Functional Ruby'
13
11
  add_filter '/spec/'
14
- add_filter '/tasks/'
15
12
  end
16
13
 
14
+ #require 'coveralls'
15
+ #Coveralls.wear!
16
+ #require 'codeclimate-test-reporter'
17
+ #CodeClimate::TestReporter.start
18
+
17
19
  require 'functional'
18
20
 
19
21
  # import all the support files
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: functional-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.7
4
+ version: 1.0.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-01-27 00:00:00.000000000 Z
11
+ date: 2014-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  description: |2
@@ -32,41 +32,47 @@ extensions: []
32
32
  extra_rdoc_files:
33
33
  - README.md
34
34
  - LICENSE
35
+ - doc/memo.txt
36
+ - doc/pattern_matching.txt
37
+ - doc/protocol.txt
38
+ - doc/record.txt
39
+ - doc/thread_safety.txt
35
40
  files:
36
41
  - LICENSE
37
42
  - README.md
43
+ - doc/memo.txt
44
+ - doc/pattern_matching.txt
45
+ - doc/protocol.txt
46
+ - doc/record.txt
47
+ - doc/thread_safety.txt
38
48
  - lib/functional.rb
39
- - lib/functional/behavior.rb
40
- - lib/functional/behaviour.rb
41
- - lib/functional/catalog.rb
42
- - lib/functional/collection.rb
43
- - lib/functional/inflect.rb
49
+ - lib/functional/abstract_struct.rb
50
+ - lib/functional/delay.rb
51
+ - lib/functional/either.rb
52
+ - lib/functional/memo.rb
53
+ - lib/functional/method_signature.rb
54
+ - lib/functional/option.rb
44
55
  - lib/functional/pattern_matching.rb
45
- - lib/functional/platform.rb
46
- - lib/functional/search.rb
47
- - lib/functional/sort.rb
48
- - lib/functional/utilities.rb
56
+ - lib/functional/protocol.rb
57
+ - lib/functional/protocol_info.rb
58
+ - lib/functional/record.rb
59
+ - lib/functional/type_check.rb
60
+ - lib/functional/union.rb
49
61
  - lib/functional/version.rb
50
62
  - lib/functional_ruby.rb
51
- - md/behavior.md
52
- - md/catalog.md
53
- - md/collection.md
54
- - md/inflect.md
55
- - md/pattern_matching.md
56
- - md/platform.md
57
- - md/search.md
58
- - md/sort.md
59
- - md/utilities.md
60
- - spec/functional/behavior_spec.rb
61
- - spec/functional/catalog_spec.rb
62
- - spec/functional/collection_spec.rb
63
- - spec/functional/inflect_spec.rb
64
- - spec/functional/integration_spec.rb
63
+ - spec/functional/abstract_struct_shared.rb
64
+ - spec/functional/complex_pattern_matching_spec.rb
65
+ - spec/functional/configuration_spec.rb
66
+ - spec/functional/delay_spec.rb
67
+ - spec/functional/either_spec.rb
68
+ - spec/functional/memo_spec.rb
69
+ - spec/functional/option_spec.rb
65
70
  - spec/functional/pattern_matching_spec.rb
66
- - spec/functional/platform_spec.rb
67
- - spec/functional/search_spec.rb
68
- - spec/functional/sort_spec.rb
69
- - spec/functional/utilities_spec.rb
71
+ - spec/functional/protocol_info_spec.rb
72
+ - spec/functional/protocol_spec.rb
73
+ - spec/functional/record_spec.rb
74
+ - spec/functional/type_check_spec.rb
75
+ - spec/functional/union_spec.rb
70
76
  - spec/spec_helper.rb
71
77
  homepage: https://github.com/jdantonio/functional-ruby/
72
78
  licenses:
@@ -78,29 +84,33 @@ require_paths:
78
84
  - lib
79
85
  required_ruby_version: !ruby/object:Gem::Requirement
80
86
  requirements:
81
- - - '>='
87
+ - - ">="
82
88
  - !ruby/object:Gem::Version
83
- version: 1.9.2
89
+ version: 1.9.3
84
90
  required_rubygems_version: !ruby/object:Gem::Requirement
85
91
  requirements:
86
- - - '>='
92
+ - - ">="
87
93
  - !ruby/object:Gem::Version
88
94
  version: '0'
89
95
  requirements: []
90
96
  rubyforge_project:
91
- rubygems_version: 2.2.1
97
+ rubygems_version: 2.2.2
92
98
  signing_key:
93
99
  specification_version: 4
94
- summary: Erlang and Clojure inspired functional programming tools for Ruby.
100
+ summary: Erlang, Clojure, and Haskell inspired functional programming tools to Ruby.
95
101
  test_files:
96
- - spec/functional/behavior_spec.rb
97
- - spec/functional/catalog_spec.rb
98
- - spec/functional/collection_spec.rb
99
- - spec/functional/inflect_spec.rb
100
- - spec/functional/integration_spec.rb
102
+ - spec/functional/abstract_struct_shared.rb
103
+ - spec/functional/complex_pattern_matching_spec.rb
104
+ - spec/functional/configuration_spec.rb
105
+ - spec/functional/delay_spec.rb
106
+ - spec/functional/either_spec.rb
107
+ - spec/functional/memo_spec.rb
108
+ - spec/functional/option_spec.rb
101
109
  - spec/functional/pattern_matching_spec.rb
102
- - spec/functional/platform_spec.rb
103
- - spec/functional/search_spec.rb
104
- - spec/functional/sort_spec.rb
105
- - spec/functional/utilities_spec.rb
110
+ - spec/functional/protocol_info_spec.rb
111
+ - spec/functional/protocol_spec.rb
112
+ - spec/functional/record_spec.rb
113
+ - spec/functional/type_check_spec.rb
114
+ - spec/functional/union_spec.rb
106
115
  - spec/spec_helper.rb
116
+ has_rdoc: