assertion 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +2 -0
  3. data/.gitignore +9 -0
  4. data/.metrics +9 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +2 -0
  7. data/.travis.yml +19 -0
  8. data/.yardopts +3 -0
  9. data/Gemfile +9 -0
  10. data/Guardfile +18 -0
  11. data/LICENSE +21 -0
  12. data/README.md +222 -0
  13. data/Rakefile +29 -0
  14. data/assertion.gemspec +27 -0
  15. data/config/metrics/STYLEGUIDE +230 -0
  16. data/config/metrics/cane.yml +5 -0
  17. data/config/metrics/churn.yml +6 -0
  18. data/config/metrics/flay.yml +2 -0
  19. data/config/metrics/metric_fu.yml +15 -0
  20. data/config/metrics/reek.yml +1 -0
  21. data/config/metrics/roodi.yml +24 -0
  22. data/config/metrics/rubocop.yml +72 -0
  23. data/config/metrics/saikuro.yml +3 -0
  24. data/config/metrics/simplecov.yml +6 -0
  25. data/config/metrics/yardstick.yml +37 -0
  26. data/lib/assertion.rb +79 -0
  27. data/lib/assertion/base.rb +186 -0
  28. data/lib/assertion/exceptions/invalid_error.rb +36 -0
  29. data/lib/assertion/exceptions/name_error.rb +29 -0
  30. data/lib/assertion/exceptions/not_implemented_error.rb +29 -0
  31. data/lib/assertion/inversion.rb +64 -0
  32. data/lib/assertion/inverter.rb +62 -0
  33. data/lib/assertion/state.rb +79 -0
  34. data/lib/assertion/transprocs/i18n.rb +55 -0
  35. data/lib/assertion/transprocs/inflector.rb +39 -0
  36. data/lib/assertion/transprocs/list.rb +30 -0
  37. data/lib/assertion/version.rb +9 -0
  38. data/spec/integration/assertion_spec.rb +50 -0
  39. data/spec/integration/en.yml +10 -0
  40. data/spec/spec_helper.rb +12 -0
  41. data/spec/unit/assertion/base_spec.rb +221 -0
  42. data/spec/unit/assertion/exceptions/invalid_error_spec.rb +40 -0
  43. data/spec/unit/assertion/exceptions/name_error_spec.rb +26 -0
  44. data/spec/unit/assertion/exceptions/not_implemented_error_spec.rb +26 -0
  45. data/spec/unit/assertion/inversion_spec.rb +89 -0
  46. data/spec/unit/assertion/inverter_spec.rb +80 -0
  47. data/spec/unit/assertion/state_spec.rb +224 -0
  48. data/spec/unit/assertion/transprocs/i18n/to_scope_spec.rb +19 -0
  49. data/spec/unit/assertion/transprocs/i18n/translate_spec.rb +28 -0
  50. data/spec/unit/assertion/transprocs/inflector/to_path_spec.rb +19 -0
  51. data/spec/unit/assertion/transprocs/inflector/to_snake_path_spec.rb +19 -0
  52. data/spec/unit/assertion/transprocs/inflector/to_snake_spec.rb +19 -0
  53. data/spec/unit/assertion/transprocs/list/symbolize_spec.rb +19 -0
  54. data/spec/unit/assertion_spec.rb +65 -0
  55. metadata +171 -0
@@ -0,0 +1,224 @@
1
+ # encoding: utf-8
2
+
3
+ require "equalizer"
4
+
5
+ describe Assertion::State do
6
+
7
+ subject(:state) { described_class.new result, messages }
8
+ let(:result) { false }
9
+ let(:messages) { %w(foo bar) }
10
+
11
+ describe ".new" do
12
+
13
+ it { is_expected.to be_frozen }
14
+
15
+ end # describe .new
16
+
17
+ describe "#valid?" do
18
+
19
+ subject { state.valid? }
20
+
21
+ context "for truthy state" do
22
+
23
+ let(:result) { 1 }
24
+ it { is_expected.to eql true }
25
+
26
+ end # context
27
+
28
+ context "for falsey state" do
29
+
30
+ let(:result) { nil }
31
+ it { is_expected.to eql false }
32
+
33
+ end # context
34
+
35
+ end # describe #valid?
36
+
37
+ describe "#invalid?" do
38
+
39
+ let(:result) { 1 }
40
+ subject { state.invalid? }
41
+
42
+ context "for truthy state" do
43
+
44
+ it { is_expected.to eql false }
45
+
46
+ end # context
47
+
48
+ context "for falsey state" do
49
+
50
+ let(:result) { nil }
51
+ it { is_expected.to eql true }
52
+
53
+ end # context
54
+
55
+ end # describe #valid?
56
+
57
+ describe "#messages" do
58
+
59
+ subject { state.messages }
60
+
61
+ it { is_expected.to be_frozen }
62
+
63
+ it "doesn't freeze the source messages" do
64
+ expect(messages).not_to be_frozen
65
+ end
66
+
67
+ context "for a valid state" do
68
+
69
+ let(:result) { true }
70
+ it { is_expected.to eql [] }
71
+
72
+ end # context
73
+
74
+ context "from a single item" do
75
+
76
+ let(:messages) { "foo" }
77
+ it { is_expected.to eql %w(foo) }
78
+
79
+ end # context
80
+
81
+ context "from array of items" do
82
+
83
+ let(:messages) { %w(foo bar foo) }
84
+ it { is_expected.to eql %w(foo bar) }
85
+
86
+ end # context
87
+
88
+ end # describe #messages
89
+
90
+ describe "#validate!" do
91
+
92
+ subject { state.validate! }
93
+
94
+ context "valid state" do
95
+
96
+ let(:result) { true }
97
+
98
+ it "doesn't raise an error" do
99
+ expect { subject }.not_to raise_error
100
+ end
101
+
102
+ it "returns true" do
103
+ expect(subject).to eql true
104
+ end
105
+
106
+ end # context
107
+
108
+ context "invalid state" do
109
+
110
+ let(:result) { false }
111
+
112
+ it "raises an error" do
113
+ expect { subject }.to raise_error do |error|
114
+ expect(error).to be_kind_of Assertion::InvalidError
115
+ expect(error.messages).to eql messages
116
+ end
117
+ end
118
+
119
+ end # context
120
+
121
+ end # describe #validate!
122
+
123
+ describe "#&" do
124
+
125
+ subject { state & described_class.new(other_result, other_messages) }
126
+ let(:other_messages) { %w(baz qux) }
127
+
128
+ context "valid + valid" do
129
+
130
+ let(:result) { true }
131
+ let(:other_result) { true }
132
+
133
+ it "creates a valid state" do
134
+ expect(subject).to be_kind_of described_class
135
+ expect(subject).to be_valid
136
+ end
137
+
138
+ it "carries no messages" do
139
+ expect(subject.messages).to eql []
140
+ end
141
+
142
+ end # context
143
+
144
+ context "valid + invalid" do
145
+
146
+ let(:result) { true }
147
+ let(:other_result) { false }
148
+
149
+ it "creates invalid state" do
150
+ expect(subject).to be_kind_of described_class
151
+ expect(subject).to be_invalid
152
+ end
153
+
154
+ it "carries messages from the invalid state" do
155
+ expect(subject.messages).to eql other_messages
156
+ end
157
+
158
+ end # context
159
+
160
+ context "invalid + valid" do
161
+
162
+ let(:result) { false }
163
+ let(:other_result) { true }
164
+
165
+ it "creates invalid state" do
166
+ expect(subject).to be_kind_of described_class
167
+ expect(subject).to be_invalid
168
+ end
169
+
170
+ it "carries messages from the invalid state" do
171
+ expect(subject.messages).to eql messages
172
+ end
173
+
174
+ end # context
175
+
176
+ context "invalid + invalid" do
177
+
178
+ let(:result) { false }
179
+ let(:other_result) { false }
180
+
181
+ it "creates invalid state" do
182
+ expect(subject).to be_kind_of described_class
183
+ expect(subject).to be_invalid
184
+ end
185
+
186
+ it "carries messages from the both states" do
187
+ expect(subject.messages).to eql(messages + other_messages)
188
+ end
189
+
190
+ end # context
191
+
192
+ end # describe #validate!
193
+
194
+ describe "#>>" do
195
+
196
+ before do
197
+ described_class.instance_eval { include Equalizer.new(:messages) }
198
+ end
199
+
200
+ subject { state >> described_class.new(false, "quxx") }
201
+ let(:compare) { state & described_class.new(false, "quxx") }
202
+
203
+ it "is an alias for #&" do
204
+ expect(subject).to eq compare
205
+ end
206
+
207
+ end # describe #+
208
+
209
+ describe "#+" do
210
+
211
+ before do
212
+ described_class.instance_eval { include Equalizer.new(:messages) }
213
+ end
214
+
215
+ subject { state + described_class.new(false, "quxx") }
216
+ let(:compare) { state & described_class.new(false, "quxx") }
217
+
218
+ it "is an alias for #&" do
219
+ expect(subject).to eq compare
220
+ end
221
+
222
+ end # describe #+
223
+
224
+ end # describe Assertion::State
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ describe Assertion::I18n, "#scope" do
4
+
5
+ subject { fn[input] }
6
+
7
+ let(:fn) { described_class[:scope] }
8
+ let(:input) { "Foo::BarBaz" }
9
+ let(:output) { [:assertion, :"foo/bar_baz"] }
10
+
11
+ it "doesn't mutate the input" do
12
+ expect { subject }.not_to change { input }
13
+ end
14
+
15
+ it "returns the class scope" do
16
+ expect(subject).to eql output
17
+ end
18
+
19
+ end # describe Assertion::I18n#scope
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ describe Assertion::I18n, "#translate" do
4
+
5
+ subject { fn[input] }
6
+
7
+ let(:fn) { described_class[:translate, scope, args] }
8
+ let(:args) { { foo: :FOO } }
9
+ let(:scope) { double }
10
+ let(:input) { double }
11
+ let(:output) { double }
12
+
13
+ before do
14
+ allow(::I18n)
15
+ .to receive(:t)
16
+ .with(input, foo: :FOO, scope: scope)
17
+ .and_return output
18
+ end
19
+
20
+ it "doesn't mutate the input" do
21
+ expect { subject }.not_to change { input }
22
+ end
23
+
24
+ it "returns the string converted to snake case" do
25
+ expect(subject).to eql output
26
+ end
27
+
28
+ end # describe Assertion::I18n#translate
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ describe Assertion::Inflector, "#to_path" do
4
+
5
+ subject { fn[input] }
6
+
7
+ let(:fn) { described_class[:to_path] }
8
+ let(:input) { "::/Foo-bar::baz/qux" }
9
+ let(:output) { "Foo/bar/baz/qux" }
10
+
11
+ it "doesn't mutate the input" do
12
+ expect { subject }.not_to change { input }
13
+ end
14
+
15
+ it "returns the string converted to snake case" do
16
+ expect(subject).to eql output
17
+ end
18
+
19
+ end # describe Assertion::Inflector#to_path
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ describe Assertion::Inflector, "#to_snake_path" do
4
+
5
+ subject { fn[input] }
6
+
7
+ let(:fn) { described_class[:to_snake_path] }
8
+ let(:input) { "::Foo::BarBAZ::Qux" }
9
+ let(:output) { "foo/bar_baz/qux" }
10
+
11
+ it "doesn't mutate the input" do
12
+ expect { subject }.not_to change { input }
13
+ end
14
+
15
+ it "returns the string converted to snake case" do
16
+ expect(subject).to eql output
17
+ end
18
+
19
+ end # describe Assertion::Inflector#to_snake_path
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ describe Assertion::Inflector, "#to_snake" do
4
+
5
+ subject { fn[input] }
6
+
7
+ let(:fn) { described_class[:to_snake] }
8
+ let(:input) { "FooBarBAz___qux" }
9
+ let(:output) { "foo_bar_baz_qux" }
10
+
11
+ it "doesn't mutate the input" do
12
+ expect { subject }.not_to change { input }
13
+ end
14
+
15
+ it "returns the string converted to snake case" do
16
+ expect(subject).to eql output
17
+ end
18
+
19
+ end # describe Assertion::Inflector#to_snake
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ describe Assertion::List, "#symbolize" do
4
+
5
+ subject { fn[input] }
6
+
7
+ let(:fn) { described_class[:symbolize] }
8
+ let(:input) { [[:foo, "bar"], "foo"] }
9
+ let(:output) { [:foo, :bar] }
10
+
11
+ it "doesn't mutate the input" do
12
+ expect { subject }.not_to change { input }
13
+ end
14
+
15
+ it "returns the string converted to snake case" do
16
+ expect(subject).to eql output
17
+ end
18
+
19
+ end # describe Assertion::List#symbolize
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+
3
+ describe Assertion do
4
+
5
+ describe ".about" do
6
+
7
+ let(:john) { { age: 17, gender: :male } }
8
+ let(:jack) { { age: 18, gender: :male } }
9
+
10
+ context "with attributes and a block" do
11
+
12
+ subject do
13
+ Man = Assertion.about(:age, :gender) { age >= 18 && gender == :male }
14
+ end
15
+
16
+ it "provides the assertion class" do
17
+ expect(subject.superclass).to eql Assertion::Base
18
+ end
19
+
20
+ it "implements the #check method" do
21
+ expect(subject[john]).to be_invalid
22
+ expect(subject[jack]).to be_valid
23
+ end
24
+
25
+ end # context
26
+
27
+ context "without attributes" do
28
+
29
+ subject do
30
+ Man = Assertion.about { true }
31
+ end
32
+
33
+ it "provides the assertion class" do
34
+ expect(subject.superclass).to eql Assertion::Base
35
+ end
36
+
37
+ it "implements the #check method" do
38
+ expect(subject[john]).to be_valid
39
+ expect(subject[jack]).to be_valid
40
+ end
41
+
42
+ end # context
43
+
44
+ context "without a block" do
45
+
46
+ subject do
47
+ Man = Assertion.about(:age, :gender)
48
+ end
49
+
50
+ it "provides the assertion class" do
51
+ expect(subject.superclass).to eql Assertion::Base
52
+ end
53
+
54
+ it "doesn't implement the #check method" do
55
+ expect { subject[jack] }
56
+ .to raise_error Assertion::NotImplementedError
57
+ end
58
+
59
+ end # context
60
+
61
+ after { Object.send :remove_const, :Man }
62
+
63
+ end # describe .about
64
+
65
+ end # describe Assertion
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: assertion
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Kozin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: transproc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: i18n
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.7'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: hexx-rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: equalizer
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.0'
69
+ description:
70
+ email: andrew.kozin@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files:
74
+ - README.md
75
+ - LICENSE
76
+ files:
77
+ - ".coveralls.yml"
78
+ - ".gitignore"
79
+ - ".metrics"
80
+ - ".rspec"
81
+ - ".rubocop.yml"
82
+ - ".travis.yml"
83
+ - ".yardopts"
84
+ - Gemfile
85
+ - Guardfile
86
+ - LICENSE
87
+ - README.md
88
+ - Rakefile
89
+ - assertion.gemspec
90
+ - config/metrics/STYLEGUIDE
91
+ - config/metrics/cane.yml
92
+ - config/metrics/churn.yml
93
+ - config/metrics/flay.yml
94
+ - config/metrics/metric_fu.yml
95
+ - config/metrics/reek.yml
96
+ - config/metrics/roodi.yml
97
+ - config/metrics/rubocop.yml
98
+ - config/metrics/saikuro.yml
99
+ - config/metrics/simplecov.yml
100
+ - config/metrics/yardstick.yml
101
+ - lib/assertion.rb
102
+ - lib/assertion/base.rb
103
+ - lib/assertion/exceptions/invalid_error.rb
104
+ - lib/assertion/exceptions/name_error.rb
105
+ - lib/assertion/exceptions/not_implemented_error.rb
106
+ - lib/assertion/inversion.rb
107
+ - lib/assertion/inverter.rb
108
+ - lib/assertion/state.rb
109
+ - lib/assertion/transprocs/i18n.rb
110
+ - lib/assertion/transprocs/inflector.rb
111
+ - lib/assertion/transprocs/list.rb
112
+ - lib/assertion/version.rb
113
+ - spec/integration/assertion_spec.rb
114
+ - spec/integration/en.yml
115
+ - spec/spec_helper.rb
116
+ - spec/unit/assertion/base_spec.rb
117
+ - spec/unit/assertion/exceptions/invalid_error_spec.rb
118
+ - spec/unit/assertion/exceptions/name_error_spec.rb
119
+ - spec/unit/assertion/exceptions/not_implemented_error_spec.rb
120
+ - spec/unit/assertion/inversion_spec.rb
121
+ - spec/unit/assertion/inverter_spec.rb
122
+ - spec/unit/assertion/state_spec.rb
123
+ - spec/unit/assertion/transprocs/i18n/to_scope_spec.rb
124
+ - spec/unit/assertion/transprocs/i18n/translate_spec.rb
125
+ - spec/unit/assertion/transprocs/inflector/to_path_spec.rb
126
+ - spec/unit/assertion/transprocs/inflector/to_snake_path_spec.rb
127
+ - spec/unit/assertion/transprocs/inflector/to_snake_spec.rb
128
+ - spec/unit/assertion/transprocs/list/symbolize_spec.rb
129
+ - spec/unit/assertion_spec.rb
130
+ homepage: https://github.com/nepalez/assertion
131
+ licenses:
132
+ - MIT
133
+ metadata: {}
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - "~>"
141
+ - !ruby/object:Gem::Version
142
+ version: '1.9'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ requirements: []
149
+ rubyforge_project:
150
+ rubygems_version: 2.4.6
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: PORO assertions and validation
154
+ test_files:
155
+ - spec/spec_helper.rb
156
+ - spec/integration/assertion_spec.rb
157
+ - spec/unit/assertion_spec.rb
158
+ - spec/unit/assertion/state_spec.rb
159
+ - spec/unit/assertion/transprocs/inflector/to_snake_path_spec.rb
160
+ - spec/unit/assertion/transprocs/inflector/to_snake_spec.rb
161
+ - spec/unit/assertion/transprocs/inflector/to_path_spec.rb
162
+ - spec/unit/assertion/transprocs/i18n/to_scope_spec.rb
163
+ - spec/unit/assertion/transprocs/i18n/translate_spec.rb
164
+ - spec/unit/assertion/transprocs/list/symbolize_spec.rb
165
+ - spec/unit/assertion/exceptions/invalid_error_spec.rb
166
+ - spec/unit/assertion/exceptions/not_implemented_error_spec.rb
167
+ - spec/unit/assertion/exceptions/name_error_spec.rb
168
+ - spec/unit/assertion/inverter_spec.rb
169
+ - spec/unit/assertion/inversion_spec.rb
170
+ - spec/unit/assertion/base_spec.rb
171
+ has_rdoc: