assertion 0.0.1

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 (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: