axiom-types 0.0.1 → 0.0.2

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.
Files changed (41) hide show
  1. checksums.yaml +6 -14
  2. data/.gitignore +1 -1
  3. data/.ruby-gemset +1 -0
  4. data/.travis.yml +2 -6
  5. data/CONTRIBUTING.md +11 -0
  6. data/Gemfile +1 -3
  7. data/Gemfile.devtools +17 -19
  8. data/README.md +1 -8
  9. data/Rakefile +0 -1
  10. data/TODO +0 -6
  11. data/axiom-types.gemspec +12 -13
  12. data/config/devtools.yml +2 -0
  13. data/config/flay.yml +1 -1
  14. data/config/flog.yml +1 -1
  15. data/config/reek.yml +67 -60
  16. data/lib/axiom/types.rb +26 -1
  17. data/lib/axiom/types/array.rb +12 -1
  18. data/lib/axiom/types/boolean.rb +17 -0
  19. data/lib/axiom/types/collection.rb +133 -0
  20. data/lib/axiom/types/hash.rb +80 -2
  21. data/lib/axiom/types/object.rb +34 -2
  22. data/lib/axiom/types/set.rb +12 -1
  23. data/lib/axiom/types/support/options.rb +13 -1
  24. data/lib/axiom/types/type.rb +17 -2
  25. data/lib/axiom/types/version.rb +1 -1
  26. data/spec/spec_helper.rb +14 -5
  27. data/spec/unit/axiom/types/array/class_methods/infer_spec.rb +99 -0
  28. data/spec/unit/axiom/types/boolean/class_methods/infer_spec.rb +33 -0
  29. data/spec/unit/axiom/types/class_methods/finalize_spec.rb +2 -7
  30. data/spec/unit/axiom/types/class_methods/infer_spec.rb +54 -0
  31. data/spec/unit/axiom/types/collection/class_methods/finalize_spec.rb +49 -0
  32. data/spec/unit/axiom/types/collection/class_methods/infer_spec.rb +111 -0
  33. data/spec/unit/axiom/types/hash/class_methods/infer_spec.rb +175 -0
  34. data/spec/unit/axiom/types/object/class_methods/infer_spec.rb +52 -0
  35. data/spec/unit/axiom/types/options/inherited_spec.rb +36 -10
  36. data/spec/unit/axiom/types/set/class_methods/infer_spec.rb +99 -0
  37. data/spec/unit/axiom/types/type/class_methods/constraint_spec.rb +66 -4
  38. data/spec/unit/axiom/types/type/class_methods/infer_spec.rb +25 -0
  39. data/spec/unit/axiom/types/type/class_methods/new_spec.rb +4 -0
  40. metadata +44 -44
  41. data/.rvmrc +0 -1
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'devtools'
4
-
5
- Devtools.init_spec_helper
3
+ require 'devtools/spec_helper'
6
4
 
7
5
  if ENV['COVERAGE'] == 'true'
8
6
  require 'simplecov'
@@ -25,13 +23,24 @@ require 'axiom-types'
25
23
 
26
24
  include Axiom::Types
27
25
 
28
- # require spec support files and shared behavior
26
+ # Require spec support files and shared behavior
29
27
  Dir[File.expand_path('../{support,shared}/**/*.rb', __FILE__)].each do |file|
30
- require file
28
+ require file.chomp('.rb')
31
29
  end
32
30
 
33
31
  RSpec.configure do |config|
34
32
  config.expect_with :rspec do |expect_with|
35
33
  expect_with.syntax = :expect
36
34
  end
35
+
36
+ # Record the original Type descendants
37
+ config.before do
38
+ @original_descendants = Axiom::Types::Type.descendants.dup
39
+ end
40
+
41
+ # Reset the Type descendants
42
+ config.after do
43
+ Axiom::Types::Type.descendants.replace(@original_descendants)
44
+ Axiom::Types.instance_variable_get(:@inference_cache).clear
45
+ end
37
46
  end
@@ -0,0 +1,99 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Axiom::Types::Array, '.infer' do
6
+ subject { object.infer(arg) }
7
+
8
+ before do
9
+ object.finalize
10
+ end
11
+
12
+ context 'with Axiom::Types::Array' do
13
+ let(:object) { described_class }
14
+
15
+ context 'when the argument is the type object' do
16
+ let(:arg) { object }
17
+
18
+ it { should be(object) }
19
+ end
20
+
21
+ context 'when the argument is ::Array' do
22
+ let(:arg) { ::Array }
23
+
24
+ it { should be(object) }
25
+ end
26
+
27
+ context 'when the argument is an empty Array' do
28
+ let(:arg) { ::Array[] }
29
+
30
+ it { should be(object) }
31
+ end
32
+
33
+ context 'when the argument is an Array with a type' do
34
+ let(:arg) { ::Array[object] }
35
+
36
+ its(:ancestors) { should include(object) }
37
+
38
+ its(:primitive) { should be(object.primitive) }
39
+
40
+ its(:member_type) { should be(object) }
41
+ end
42
+
43
+ context 'when the argument is an Array with a primitive' do
44
+ let(:arg) { ::Array[::Array] }
45
+
46
+ its(:ancestors) { should include(object) }
47
+
48
+ its(:primitive) { should be(object.primitive) }
49
+
50
+ its(:member_type) { should be(object) }
51
+ end
52
+
53
+ context 'when the argument is nil' do
54
+ let(:arg) { nil }
55
+
56
+ it { should be_nil }
57
+ end
58
+ end
59
+
60
+ context 'with Axiom::Types::Array subclass' do
61
+ let(:object) { Class.new(described_class) }
62
+
63
+ context 'when the argument is the type object' do
64
+ let(:arg) { object }
65
+
66
+ it { should be(object) }
67
+ end
68
+
69
+ context 'when the argument is ::Array' do
70
+ let(:arg) { ::Array }
71
+
72
+ it { should be(object) }
73
+ end
74
+
75
+ context 'when the argument is an empty Array' do
76
+ let(:arg) { ::Array[] }
77
+
78
+ it { should be(object) }
79
+ end
80
+
81
+ context 'when the argument is an Array with a type' do
82
+ let(:arg) { ::Array[object] }
83
+
84
+ it { should be_nil }
85
+ end
86
+
87
+ context 'when the argument is an Array with a primitive' do
88
+ let(:arg) { ::Array[::Array] }
89
+
90
+ it { should be_nil }
91
+ end
92
+
93
+ context 'when the argument is nil' do
94
+ let(:arg) { nil }
95
+
96
+ it { should be_nil }
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Axiom::Types::Boolean, '.infer' do
6
+ subject { object.infer(arg) }
7
+
8
+ let(:object) { described_class }
9
+
10
+ context 'when the argument is the type object' do
11
+ let(:arg) { object }
12
+
13
+ it { should be(object) }
14
+ end
15
+
16
+ context 'when the argument is ::TrueClass' do
17
+ let(:arg) { ::TrueClass }
18
+
19
+ it { should be(object) }
20
+ end
21
+
22
+ context 'when the argument is ::FalseClass' do
23
+ let(:arg) { ::FalseClass }
24
+
25
+ it { should be(object) }
26
+ end
27
+
28
+ context 'when the argument is nil' do
29
+ let(:arg) { nil }
30
+
31
+ it { should be_nil }
32
+ end
33
+ end
@@ -5,13 +5,8 @@ require 'spec_helper'
5
5
  describe Axiom::Types, '.finalize' do
6
6
  subject { object.finalize }
7
7
 
8
- let(:object) { described_class }
9
- let(:descendants) { [ descendant ] }
10
- let(:descendant) { mock('descendant').as_null_object }
11
-
12
- before do
13
- object::Type.should_receive(:descendants).and_return(descendants)
14
- end
8
+ let(:object) { described_class }
9
+ let(:descendant) { Class.new(Axiom::Types::Type) }
15
10
 
16
11
  it_should_behave_like 'a command method'
17
12
 
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Axiom::Types, '.infer' do
6
+ subject { object.infer(type) }
7
+
8
+ let(:object) { described_class }
9
+
10
+ before do
11
+ object.finalize
12
+ end
13
+
14
+ Axiom::Types::Type.descendants.each do |descendant|
15
+ context "when the type is #{descendant}" do
16
+ let(:type) { descendant }
17
+
18
+ it { should be(descendant) }
19
+ end
20
+
21
+ if descendant.equal?(Axiom::Types::Boolean)
22
+ context 'when the type is TrueClass' do
23
+ let(:type) { ::TrueClass }
24
+
25
+ it { should be(descendant) }
26
+ end
27
+
28
+ context 'when the type is FalseClass' do
29
+ let(:type) { ::FalseClass }
30
+
31
+ it { should be(descendant) }
32
+ end
33
+ else
34
+ primitive = descendant.primitive
35
+
36
+ context "when the type is #{primitive}" do
37
+ let(:type) { primitive }
38
+
39
+ it { should be(descendant) }
40
+ end
41
+ end
42
+ end
43
+
44
+ context 'with a custom type' do
45
+ let(:type) do
46
+ Axiom::Types::String.new do
47
+ minimum_length 1
48
+ maximum_length 100
49
+ end
50
+ end
51
+
52
+ it { should be(type) }
53
+ end
54
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Axiom::Types::Collection, '.finalize' do
6
+ subject { object.finalize }
7
+
8
+ let(:object) { Class.new(Axiom::Types::Collection) }
9
+
10
+ context 'with the default member constraints' do
11
+ it_should_behave_like 'a command method'
12
+ it_should_behave_like 'an idempotent method'
13
+
14
+ it { should be_frozen }
15
+
16
+ its(:constraint) { should be_frozen }
17
+
18
+ it 'adds a constraint that returns true for a collection' do
19
+ should include([ Object.new ])
20
+ end
21
+
22
+ it 'adds a constraint that returns false for a non-collection' do
23
+ should_not include(Object.new)
24
+ end
25
+ end
26
+
27
+ context 'with custom member constraints' do
28
+ let(:member) { :name }
29
+
30
+ before do
31
+ object.member_type Axiom::Types::Symbol
32
+ end
33
+
34
+ it_should_behave_like 'a command method'
35
+ it_should_behave_like 'an idempotent method'
36
+
37
+ it { should be_frozen }
38
+
39
+ its(:constraint) { should be_frozen }
40
+
41
+ it 'adds a constraint that returns true for a valid member' do
42
+ should include([ member ])
43
+ end
44
+
45
+ it 'adds a constraint that returns false for an invalid member' do
46
+ should_not include([ member.to_s ])
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,111 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Axiom::Types::Collection, '.infer' do
6
+ subject { object.infer(arg) }
7
+
8
+ before do
9
+ object.finalize
10
+ end
11
+
12
+ context 'with a base class' do
13
+ let(:object) do
14
+ Class.new(described_class) do
15
+ primitive ::SortedSet
16
+
17
+ def self.base?
18
+ true
19
+ end
20
+ end
21
+ end
22
+
23
+ context 'when the argument is the type object' do
24
+ let(:arg) { object }
25
+
26
+ it { should be(object) }
27
+ end
28
+
29
+ context 'when the argument is ::SortedSet' do
30
+ let(:arg) { ::SortedSet }
31
+
32
+ it { should be(object) }
33
+ end
34
+
35
+ context 'when the argument is an empty SortedSet' do
36
+ let(:arg) { ::SortedSet[] }
37
+
38
+ it { should be(object) }
39
+ end
40
+
41
+ context 'when the argument is an SortedSet with a type' do
42
+ let(:arg) { ::SortedSet[object] }
43
+
44
+ its(:ancestors) { should include(object) }
45
+
46
+ its(:primitive) { should be(object.primitive) }
47
+
48
+ its(:member_type) { should be(object) }
49
+ end
50
+
51
+ context 'when the argument is an SortedSet with a primitive' do
52
+ let(:arg) { ::SortedSet[::SortedSet] }
53
+
54
+ its(:ancestors) { should include(object) }
55
+
56
+ its(:primitive) { should be(object.primitive) }
57
+
58
+ its(:member_type) { should be(object) }
59
+ end
60
+
61
+ context 'when the argument is nil' do
62
+ let(:arg) { nil }
63
+
64
+ it { should be_nil }
65
+ end
66
+ end
67
+
68
+ context 'with a a non-base class' do
69
+ let(:object) do
70
+ Class.new(described_class) do
71
+ primitive ::SortedSet
72
+ end
73
+ end
74
+
75
+ context 'when the argument is the type object' do
76
+ let(:arg) { object }
77
+
78
+ it { should be(object) }
79
+ end
80
+
81
+ context 'when the argument is ::SortedSet' do
82
+ let(:arg) { ::SortedSet }
83
+
84
+ it { should be(object) }
85
+ end
86
+
87
+ context 'when the argument is an empty SortedSet' do
88
+ let(:arg) { ::SortedSet[] }
89
+
90
+ it { should be(object) }
91
+ end
92
+
93
+ context 'when the argument is an SortedSet with a type' do
94
+ let(:arg) { ::SortedSet[object] }
95
+
96
+ it { should be_nil }
97
+ end
98
+
99
+ context 'when the argument is an SortedSet with a primitive' do
100
+ let(:arg) { ::SortedSet[::SortedSet] }
101
+
102
+ it { should be_nil }
103
+ end
104
+
105
+ context 'when the argument is nil' do
106
+ let(:arg) { nil }
107
+
108
+ it { should be_nil }
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,175 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Axiom::Types::Hash, '.infer' do
6
+ subject { object.infer(arg) }
7
+
8
+ before do
9
+ object.finalize
10
+ end
11
+
12
+ context 'with Axiom::Types::Hash' do
13
+ let(:object) { described_class }
14
+
15
+ context 'when the argument is the type object' do
16
+ let(:arg) { object }
17
+
18
+ it { should be(object) }
19
+ end
20
+
21
+ context 'when the argument is ::Hash' do
22
+ let(:arg) { ::Hash }
23
+
24
+ it { should be(object) }
25
+ end
26
+
27
+ context 'when the argument is an empty Hash' do
28
+ let(:arg) { ::Hash[] }
29
+
30
+ it { should be(object) }
31
+ end
32
+
33
+ context 'when the argument is an Hash with a key type and nil value' do
34
+ let(:arg) { ::Hash[object => nil] }
35
+
36
+ its(:ancestors) { should include(object) }
37
+
38
+ its(:primitive) { should be(object.primitive) }
39
+
40
+ its(:key_type) { should be(object) }
41
+
42
+ its(:value_type) { should be(Axiom::Types::Object) }
43
+ end
44
+
45
+ context 'when the argument is an Hash with a nil key and value type' do
46
+ let(:arg) { ::Hash[nil => object] }
47
+
48
+ its(:ancestors) { should include(object) }
49
+
50
+ its(:primitive) { should be(object.primitive) }
51
+
52
+ its(:key_type) { should be(Axiom::Types::Object) }
53
+
54
+ its(:value_type) { should be(object) }
55
+ end
56
+
57
+ context 'when the argument is an Hash with key and value types' do
58
+ let(:arg) { ::Hash[object => object] }
59
+
60
+ its(:ancestors) { should include(object) }
61
+
62
+ its(:primitive) { should be(object.primitive) }
63
+
64
+ its(:key_type) { should be(object) }
65
+
66
+ its(:value_type) { should be(object) }
67
+ end
68
+
69
+ context 'when the argument is an Hash with a key primitive and nil value' do
70
+ let(:arg) { ::Hash[::Hash => nil] }
71
+
72
+ its(:ancestors) { should include(object) }
73
+
74
+ its(:primitive) { should be(object.primitive) }
75
+
76
+ its(:key_type) { should be(object) }
77
+
78
+ its(:value_type) { should be(Axiom::Types::Object) }
79
+ end
80
+
81
+ context 'when the argument is an Hash with a nil key and value primitive' do
82
+ let(:arg) { ::Hash[nil => ::Hash] }
83
+
84
+ its(:ancestors) { should include(object) }
85
+
86
+ its(:primitive) { should be(object.primitive) }
87
+
88
+ its(:key_type) { should be(Axiom::Types::Object) }
89
+
90
+ its(:value_type) { should be(object) }
91
+ end
92
+
93
+ context 'when the argument is an Hash with key and value primitives' do
94
+ let(:arg) { ::Hash[::Hash => ::Hash] }
95
+
96
+ its(:ancestors) { should include(object) }
97
+
98
+ its(:primitive) { should be(object.primitive) }
99
+
100
+ its(:key_type) { should be(object) }
101
+
102
+ its(:value_type) { should be(object) }
103
+ end
104
+
105
+ context 'when the argument is nil' do
106
+ let(:arg) { nil }
107
+
108
+ it { should be_nil }
109
+ end
110
+ end
111
+
112
+ context 'with Axiom::Types::Hash subclass' do
113
+ let(:object) { Class.new(described_class) }
114
+
115
+ context 'when the argument is the type object' do
116
+ let(:arg) { object }
117
+
118
+ it { should be(object) }
119
+ end
120
+
121
+ context 'when the argument is ::Hash' do
122
+ let(:arg) { ::Hash }
123
+
124
+ it { should be(object) }
125
+ end
126
+
127
+ context 'when the argument is an empty Hash' do
128
+ let(:arg) { ::Hash[] }
129
+
130
+ it { should be(object) }
131
+ end
132
+
133
+ context 'when the argument is an Hash with a key type and nil value' do
134
+ let(:arg) { ::Hash[object => nil] }
135
+
136
+ it { should be_nil }
137
+ end
138
+
139
+ context 'when the argument is an Hash with a nil key and value type' do
140
+ let(:arg) { ::Hash[nil => object] }
141
+
142
+ it { should be_nil }
143
+ end
144
+
145
+ context 'when the argument is an Hash with key and value types' do
146
+ let(:arg) { ::Hash[object => object] }
147
+
148
+ it { should be_nil }
149
+ end
150
+
151
+ context 'when the argument is an Hash with a key primitive and nil value' do
152
+ let(:arg) { ::Hash[::Hash => nil] }
153
+
154
+ it { should be_nil }
155
+ end
156
+
157
+ context 'when the argument is an Hash with a nil key and value primitive' do
158
+ let(:arg) { ::Hash[nil => ::Hash] }
159
+
160
+ it { should be_nil }
161
+ end
162
+
163
+ context 'when the argument is an Hash with key and value primitives' do
164
+ let(:arg) { ::Hash[::Hash => ::Hash] }
165
+
166
+ it { should be_nil }
167
+ end
168
+
169
+ context 'when the argument is nil' do
170
+ let(:arg) { nil }
171
+
172
+ it { should be_nil }
173
+ end
174
+ end
175
+ end