assertion 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/Gemfile +0 -2
- data/Guardfile +6 -6
- data/README.md +8 -6
- data/assertion.gemspec +1 -1
- data/config/metrics/flay.yml +1 -1
- data/lib/assertion.rb +29 -80
- data/lib/assertion/base.rb +38 -64
- data/lib/assertion/base_dsl.rb +75 -0
- data/lib/assertion/dsl.rb +77 -0
- data/lib/assertion/guard.rb +1 -30
- data/lib/assertion/guard_dsl.rb +39 -0
- data/lib/assertion/{transprocs/inflector.rb → inflector.rb} +0 -0
- data/lib/assertion/inversion.rb +3 -3
- data/lib/assertion/inverter.rb +2 -2
- data/lib/assertion/translator.rb +95 -0
- data/lib/assertion/version.rb +1 -1
- data/spec/integration/guard_spec.rb +1 -1
- data/spec/shared/en.yml +4 -4
- data/spec/unit/assertion/base_spec.rb +124 -14
- data/spec/unit/assertion/guard_spec.rb +37 -13
- data/spec/unit/assertion/{transprocs/inflector → inflector}/to_path_spec.rb +0 -0
- data/spec/unit/assertion/{transprocs/inflector → inflector}/to_snake_path_spec.rb +0 -0
- data/spec/unit/assertion/{transprocs/inflector → inflector}/to_snake_spec.rb +0 -0
- data/spec/unit/assertion/{exceptions/invalid_error_spec.rb → invalid_error_spec.rb} +0 -0
- data/spec/unit/assertion/inversion_spec.rb +5 -5
- data/spec/unit/assertion/inverter_spec.rb +2 -2
- data/spec/unit/assertion/translator_spec.rb +57 -0
- metadata +23 -20
- data/lib/assertion/attributes.rb +0 -54
- data/lib/assertion/messages.rb +0 -65
- data/lib/assertion/transprocs/list.rb +0 -30
- data/spec/unit/assertion/attributes_spec.rb +0 -97
- data/spec/unit/assertion/messages_spec.rb +0 -41
- data/spec/unit/assertion/transprocs/list/symbolize_spec.rb +0 -19
@@ -6,32 +6,56 @@ describe Assertion::Guard do
|
|
6
6
|
|
7
7
|
before do
|
8
8
|
IsAdult = Assertion.about(:age) { age.to_i >= 18 }
|
9
|
-
AdultOnly = Class.new(described_class)
|
9
|
+
AdultOnly = Class.new(described_class) do
|
10
|
+
def state
|
11
|
+
IsAdult[object.to_h]
|
12
|
+
end
|
13
|
+
end
|
10
14
|
end
|
11
15
|
|
12
16
|
let(:valid) { OpenStruct.new(name: "Joe", age: 40) }
|
13
17
|
let(:invalid) { OpenStruct.new(name: "Ian", age: 10) }
|
14
|
-
let(:guard) { AdultOnly.new valid
|
18
|
+
let(:guard) { AdultOnly.new valid }
|
15
19
|
|
16
|
-
|
17
|
-
expect(AdultOnly).to be_kind_of Assertion::Attributes
|
18
|
-
end
|
20
|
+
describe ".attribute" do
|
19
21
|
|
20
|
-
|
22
|
+
shared_examples "adding #object alias" do |name|
|
21
23
|
|
22
|
-
|
24
|
+
subject { AdultOnly.attribute name }
|
23
25
|
|
24
|
-
|
26
|
+
it "adds alias for the #object" do
|
27
|
+
subject
|
28
|
+
expect(guard.send name).to eql guard.object
|
29
|
+
end
|
25
30
|
|
26
|
-
|
31
|
+
end # shared examples
|
27
32
|
|
28
|
-
|
33
|
+
shared_examples "raising NameError" do |with: nil|
|
29
34
|
|
30
|
-
|
31
|
-
|
35
|
+
before { Test = Class.new(described_class) } # #state not implemented yet
|
36
|
+
after { Object.send :remove_const, :Test }
|
37
|
+
subject { Test.attribute with }
|
38
|
+
|
39
|
+
it "fails" do
|
40
|
+
expect { subject }.to raise_error do |error|
|
41
|
+
expect(error).to be_kind_of NameError
|
42
|
+
expect(error.message).to eql "Test##{with} is already defined"
|
43
|
+
end
|
32
44
|
end
|
33
45
|
|
34
|
-
end #
|
46
|
+
end # shared examples
|
47
|
+
|
48
|
+
it_behaves_like "adding #object alias", :foo
|
49
|
+
it_behaves_like "raising NameError", with: "state"
|
50
|
+
it_behaves_like "raising NameError", with: "call"
|
51
|
+
|
52
|
+
end # describe .attribute
|
53
|
+
|
54
|
+
describe ".new" do
|
55
|
+
|
56
|
+
subject { guard }
|
57
|
+
|
58
|
+
it { is_expected.to be_frozen }
|
35
59
|
|
36
60
|
end # describe .new
|
37
61
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
describe Assertion::Inversion do
|
4
4
|
|
5
|
-
before {
|
5
|
+
before { IsAdult = Assertion.about(:age) { age >= 18 } }
|
6
6
|
|
7
|
-
let(:assertion) {
|
7
|
+
let(:assertion) { IsAdult.new age: 21 }
|
8
8
|
subject(:inversion) { described_class.new(assertion) }
|
9
9
|
subject(:double_inversion) { described_class.new(inversion) }
|
10
10
|
|
@@ -40,7 +40,7 @@ describe Assertion::Inversion do
|
|
40
40
|
|
41
41
|
context "for the truthy state" do
|
42
42
|
|
43
|
-
it "is equal to
|
43
|
+
it "is equal to falsey assertion" do
|
44
44
|
expect(inversion.message(true)).to eql assertion.message(false)
|
45
45
|
end
|
46
46
|
|
@@ -52,7 +52,7 @@ describe Assertion::Inversion do
|
|
52
52
|
|
53
53
|
context "for the falsey state" do
|
54
54
|
|
55
|
-
it "is equal to
|
55
|
+
it "is equal to truthy assertion" do
|
56
56
|
expect(inversion.message(false)).to eql assertion.message(true)
|
57
57
|
end
|
58
58
|
|
@@ -84,6 +84,6 @@ describe Assertion::Inversion do
|
|
84
84
|
|
85
85
|
end # describe #call
|
86
86
|
|
87
|
-
after { Object.send :remove_const, :
|
87
|
+
after { Object.send :remove_const, :IsAdult }
|
88
88
|
|
89
89
|
end # describe Assertion::Inversion
|
@@ -3,7 +3,7 @@
|
|
3
3
|
describe Assertion::Inverter do
|
4
4
|
|
5
5
|
let(:source) do
|
6
|
-
|
6
|
+
IsMan = Assertion.about(:age, :gender) { age.to_i >= 18 && gender == :male }
|
7
7
|
end
|
8
8
|
|
9
9
|
subject(:inverter) { described_class.new source }
|
@@ -75,6 +75,6 @@ describe Assertion::Inverter do
|
|
75
75
|
|
76
76
|
end # describe #[]
|
77
77
|
|
78
|
-
after { Object.send :remove_const, :
|
78
|
+
after { Object.send :remove_const, :IsMan }
|
79
79
|
|
80
80
|
end # describe Assertion::Inverter
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe Assertion::Translator do
|
4
|
+
|
5
|
+
before { class IsFoo; end }
|
6
|
+
after { Object.send :remove_const, :IsFoo }
|
7
|
+
|
8
|
+
subject(:translator) { described_class.new(IsFoo) }
|
9
|
+
|
10
|
+
describe ".new" do
|
11
|
+
|
12
|
+
it { is_expected.to be_frozen }
|
13
|
+
|
14
|
+
end # describe .new
|
15
|
+
|
16
|
+
describe "#assertion" do
|
17
|
+
|
18
|
+
subject { translator.assertion }
|
19
|
+
it { is_expected.to eql IsFoo }
|
20
|
+
|
21
|
+
end # describe #assertion
|
22
|
+
|
23
|
+
describe "#scope" do
|
24
|
+
|
25
|
+
subject { translator.scope }
|
26
|
+
it { is_expected.to eql [:assertion, :is_foo] }
|
27
|
+
|
28
|
+
end # describe #scope
|
29
|
+
|
30
|
+
describe "#call" do
|
31
|
+
|
32
|
+
shared_examples "translating" do |input, to: nil|
|
33
|
+
|
34
|
+
subject { translator.call(input) }
|
35
|
+
|
36
|
+
let(:attributes) { { foo: :FOO, bar: :BAR } }
|
37
|
+
let(:output) { "translation missing: en.assertion.is_foo.#{to}" }
|
38
|
+
|
39
|
+
it "provides translation" do
|
40
|
+
expect(translator.call input).to eql output
|
41
|
+
end
|
42
|
+
|
43
|
+
it "makes arguments available" do
|
44
|
+
expect(I18n).to receive(:translate) do |_, args|
|
45
|
+
expect(args.merge(attributes)).to eql args
|
46
|
+
end
|
47
|
+
translator.call input, attributes
|
48
|
+
end
|
49
|
+
|
50
|
+
end # shared examples
|
51
|
+
|
52
|
+
it_behaves_like "translating", true, to: "truthy"
|
53
|
+
it_behaves_like "translating", false, to: "falsey"
|
54
|
+
|
55
|
+
end # describe #call
|
56
|
+
|
57
|
+
end # describe Assertion::Translator
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: assertion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kozin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: transproc
|
@@ -17,6 +17,9 @@ dependencies:
|
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0.2'
|
20
|
+
- - ">"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.2.3
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -24,6 +27,9 @@ dependencies:
|
|
24
27
|
- - "~>"
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '0.2'
|
30
|
+
- - ">"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.2.3
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: i18n
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,34 +106,33 @@ files:
|
|
100
106
|
- config/metrics/simplecov.yml
|
101
107
|
- config/metrics/yardstick.yml
|
102
108
|
- lib/assertion.rb
|
103
|
-
- lib/assertion/attributes.rb
|
104
109
|
- lib/assertion/base.rb
|
110
|
+
- lib/assertion/base_dsl.rb
|
111
|
+
- lib/assertion/dsl.rb
|
105
112
|
- lib/assertion/guard.rb
|
113
|
+
- lib/assertion/guard_dsl.rb
|
114
|
+
- lib/assertion/inflector.rb
|
106
115
|
- lib/assertion/invalid_error.rb
|
107
116
|
- lib/assertion/inversion.rb
|
108
117
|
- lib/assertion/inverter.rb
|
109
|
-
- lib/assertion/messages.rb
|
110
118
|
- lib/assertion/state.rb
|
111
|
-
- lib/assertion/
|
112
|
-
- lib/assertion/transprocs/list.rb
|
119
|
+
- lib/assertion/translator.rb
|
113
120
|
- lib/assertion/version.rb
|
114
121
|
- spec/integration/assertion_spec.rb
|
115
122
|
- spec/integration/guard_spec.rb
|
116
123
|
- spec/shared/en.yml
|
117
124
|
- spec/shared/i18n.rb
|
118
125
|
- spec/spec_helper.rb
|
119
|
-
- spec/unit/assertion/attributes_spec.rb
|
120
126
|
- spec/unit/assertion/base_spec.rb
|
121
|
-
- spec/unit/assertion/exceptions/invalid_error_spec.rb
|
122
127
|
- spec/unit/assertion/guard_spec.rb
|
128
|
+
- spec/unit/assertion/inflector/to_path_spec.rb
|
129
|
+
- spec/unit/assertion/inflector/to_snake_path_spec.rb
|
130
|
+
- spec/unit/assertion/inflector/to_snake_spec.rb
|
131
|
+
- spec/unit/assertion/invalid_error_spec.rb
|
123
132
|
- spec/unit/assertion/inversion_spec.rb
|
124
133
|
- spec/unit/assertion/inverter_spec.rb
|
125
|
-
- spec/unit/assertion/messages_spec.rb
|
126
134
|
- spec/unit/assertion/state_spec.rb
|
127
|
-
- spec/unit/assertion/
|
128
|
-
- spec/unit/assertion/transprocs/inflector/to_snake_path_spec.rb
|
129
|
-
- spec/unit/assertion/transprocs/inflector/to_snake_spec.rb
|
130
|
-
- spec/unit/assertion/transprocs/list/symbolize_spec.rb
|
135
|
+
- spec/unit/assertion/translator_spec.rb
|
131
136
|
- spec/unit/assertion_spec.rb
|
132
137
|
homepage: https://github.com/nepalez/assertion
|
133
138
|
licenses:
|
@@ -158,17 +163,15 @@ test_files:
|
|
158
163
|
- spec/integration/assertion_spec.rb
|
159
164
|
- spec/integration/guard_spec.rb
|
160
165
|
- spec/unit/assertion_spec.rb
|
166
|
+
- spec/unit/assertion/invalid_error_spec.rb
|
161
167
|
- spec/unit/assertion/state_spec.rb
|
162
|
-
- spec/unit/assertion/
|
163
|
-
- spec/unit/assertion/
|
164
|
-
- spec/unit/assertion/
|
165
|
-
- spec/unit/assertion/
|
166
|
-
- spec/unit/assertion/exceptions/invalid_error_spec.rb
|
167
|
-
- spec/unit/assertion/messages_spec.rb
|
168
|
+
- spec/unit/assertion/inflector/to_snake_path_spec.rb
|
169
|
+
- spec/unit/assertion/inflector/to_snake_spec.rb
|
170
|
+
- spec/unit/assertion/inflector/to_path_spec.rb
|
171
|
+
- spec/unit/assertion/translator_spec.rb
|
168
172
|
- spec/unit/assertion/inverter_spec.rb
|
169
173
|
- spec/unit/assertion/inversion_spec.rb
|
170
174
|
- spec/unit/assertion/guard_spec.rb
|
171
|
-
- spec/unit/assertion/attributes_spec.rb
|
172
175
|
- spec/unit/assertion/base_spec.rb
|
173
176
|
- spec/shared/i18n.rb
|
174
177
|
has_rdoc:
|
data/lib/assertion/attributes.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Assertion
|
4
|
-
|
5
|
-
# Module Attributes provides features to define and store a list of attributes
|
6
|
-
# shared by the [Assertion::Base] and [Assertion::Guard] classes
|
7
|
-
#
|
8
|
-
module Attributes
|
9
|
-
|
10
|
-
# List of attributes, defined for the class
|
11
|
-
#
|
12
|
-
# @return [Array<Symbol>]
|
13
|
-
#
|
14
|
-
def attributes
|
15
|
-
@attributes ||= []
|
16
|
-
end
|
17
|
-
|
18
|
-
# Adds a new attribute or a list of attributes to the class
|
19
|
-
#
|
20
|
-
# @param [Symbol, Array<Symbol>] names
|
21
|
-
#
|
22
|
-
# @return [undefined]
|
23
|
-
#
|
24
|
-
# @raise [NameError]
|
25
|
-
# When the name is either used by instance attribute,
|
26
|
-
# or forbidden as a name of the method to be implemented later
|
27
|
-
# (not as an attribute)
|
28
|
-
#
|
29
|
-
def attribute(*names)
|
30
|
-
@attributes = List[:symbolize][attributes + names]
|
31
|
-
__check_attributes__
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
# Names of the methods that should be reserved to be used later
|
37
|
-
#
|
38
|
-
# @return [Array<Symbol>]
|
39
|
-
#
|
40
|
-
# @abstract
|
41
|
-
#
|
42
|
-
def __forbidden_attributes__
|
43
|
-
[]
|
44
|
-
end
|
45
|
-
|
46
|
-
def __check_attributes__
|
47
|
-
names = attributes & (instance_methods + __forbidden_attributes__)
|
48
|
-
return if names.empty?
|
49
|
-
fail NameError.new "Wrong name(s) for attribute(s): #{names.join(", ")}"
|
50
|
-
end
|
51
|
-
|
52
|
-
end # module Attributes
|
53
|
-
|
54
|
-
end # module Assertion
|
data/lib/assertion/messages.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require "i18n"
|
4
|
-
|
5
|
-
module Assertion
|
6
|
-
|
7
|
-
# Module Messages provides a feature for gem-specific translation of messages
|
8
|
-
# describing the desired state of the assertion
|
9
|
-
#
|
10
|
-
# You need to declare a hash of attributes to be added to the translation.
|
11
|
-
#
|
12
|
-
# @example
|
13
|
-
# class MyClass
|
14
|
-
# include Assertion::Messages
|
15
|
-
# def attributes
|
16
|
-
# {}
|
17
|
-
# end
|
18
|
-
# end
|
19
|
-
#
|
20
|
-
# item = MyClass.new
|
21
|
-
# item.message(true)
|
22
|
-
# # => "translation missing: en.assertion.my_class.right"
|
23
|
-
# item.message(false)
|
24
|
-
# # => "translation missing: en.assertion.my_class.wrong"
|
25
|
-
#
|
26
|
-
# @author Andrew Kozin <Andrew.Kozin@gmail.com>
|
27
|
-
#
|
28
|
-
module Messages
|
29
|
-
|
30
|
-
# The gem-specific root scope for translations
|
31
|
-
#
|
32
|
-
# @return [Symbol]
|
33
|
-
#
|
34
|
-
ROOT = :assertion
|
35
|
-
|
36
|
-
# The states to be translated with their dictionary names
|
37
|
-
#
|
38
|
-
# @return [Hash<Object => Symbol>]
|
39
|
-
#
|
40
|
-
DICTIONARY = { true => :right, false => :wrong }
|
41
|
-
|
42
|
-
# Returns the message describing the desired state of assertion
|
43
|
-
#
|
44
|
-
# The translation is provided for the gem-specific scope for the
|
45
|
-
# current class
|
46
|
-
#
|
47
|
-
# @param [Boolean] state <description>
|
48
|
-
#
|
49
|
-
# @return [String] The translation
|
50
|
-
#
|
51
|
-
def message(state)
|
52
|
-
key = DICTIONARY[state]
|
53
|
-
scope = [ROOT, Inflector[:to_snake_path][self.class.name]]
|
54
|
-
|
55
|
-
I18n.translate key, attributes.merge(scope: scope)
|
56
|
-
end
|
57
|
-
|
58
|
-
# @private
|
59
|
-
def attributes
|
60
|
-
{}
|
61
|
-
end
|
62
|
-
|
63
|
-
end # module Messages
|
64
|
-
|
65
|
-
end # module Assertion
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module Assertion
|
2
|
-
|
3
|
-
# The collection of pure functions for converting arrays
|
4
|
-
#
|
5
|
-
# @api private
|
6
|
-
#
|
7
|
-
module List
|
8
|
-
|
9
|
-
extend ::Transproc::Registry
|
10
|
-
|
11
|
-
# Converts the nested array of strings and symbols into the flat
|
12
|
-
# array of unique symbols
|
13
|
-
#
|
14
|
-
# @example
|
15
|
-
# fn = List[:symbolize]
|
16
|
-
# source = [:foo, ["foo", "bar"], :bar, "baz"]
|
17
|
-
# fn[source]
|
18
|
-
# # => [:foo, :bar, :baz]
|
19
|
-
#
|
20
|
-
# @param [Array<String, Symbol, Array>] array
|
21
|
-
#
|
22
|
-
# @return [Array<Symbol>]
|
23
|
-
#
|
24
|
-
def symbolize(array)
|
25
|
-
array.flatten.map(&:to_sym).uniq
|
26
|
-
end
|
27
|
-
|
28
|
-
end # module List
|
29
|
-
|
30
|
-
end # module Assertion
|
@@ -1,97 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
describe Assertion::Attributes do
|
4
|
-
|
5
|
-
subject(:klass) do
|
6
|
-
class Test
|
7
|
-
extend Assertion::Attributes
|
8
|
-
attr_reader :baz, :qux
|
9
|
-
end
|
10
|
-
|
11
|
-
Test
|
12
|
-
end
|
13
|
-
|
14
|
-
describe "#attributes" do
|
15
|
-
|
16
|
-
subject { klass.attributes }
|
17
|
-
|
18
|
-
it { is_expected.to eql [] }
|
19
|
-
|
20
|
-
end # describe #attributes
|
21
|
-
|
22
|
-
describe "#attribute" do
|
23
|
-
|
24
|
-
context "single attribute" do
|
25
|
-
|
26
|
-
subject do
|
27
|
-
klass.attribute "foo"
|
28
|
-
klass.attribute "bar"
|
29
|
-
end
|
30
|
-
|
31
|
-
it "register the attribute" do
|
32
|
-
expect { subject }.to change { klass.attributes }.to [:foo, :bar]
|
33
|
-
end
|
34
|
-
|
35
|
-
end # context
|
36
|
-
|
37
|
-
context "list of attributes" do
|
38
|
-
|
39
|
-
subject { klass.attribute :foo, :bar }
|
40
|
-
|
41
|
-
it "register the attributes" do
|
42
|
-
expect { subject }.to change { klass.attributes }.to [:foo, :bar]
|
43
|
-
end
|
44
|
-
|
45
|
-
end # context
|
46
|
-
|
47
|
-
context "array of attributes" do
|
48
|
-
|
49
|
-
subject { klass.attribute %w(foo bar) }
|
50
|
-
|
51
|
-
it "register the attributes" do
|
52
|
-
expect { subject }.to change { klass.attributes }.to [:foo, :bar]
|
53
|
-
end
|
54
|
-
|
55
|
-
end # context
|
56
|
-
|
57
|
-
context "name of instance method" do
|
58
|
-
|
59
|
-
subject { klass.attribute :baz, :qux }
|
60
|
-
|
61
|
-
it "raises NameError" do
|
62
|
-
expect { subject }.to raise_error do |error|
|
63
|
-
expect(error).to be_kind_of NameError
|
64
|
-
expect(error.message)
|
65
|
-
.to eql "Wrong name(s) for attribute(s): baz, qux"
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
end # context
|
70
|
-
|
71
|
-
context "forbidden attribute" do
|
72
|
-
|
73
|
-
before do
|
74
|
-
class Test
|
75
|
-
def self.__forbidden_attributes__
|
76
|
-
[:foo, :bar]
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
subject { klass.attribute :foo, :bar }
|
82
|
-
|
83
|
-
it "raises NameError" do
|
84
|
-
expect { subject }.to raise_error do |error|
|
85
|
-
expect(error).to be_kind_of NameError
|
86
|
-
expect(error.message)
|
87
|
-
.to eql "Wrong name(s) for attribute(s): foo, bar"
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
end # context
|
92
|
-
|
93
|
-
end # describe #attributes
|
94
|
-
|
95
|
-
after { Object.send :remove_const, :Test }
|
96
|
-
|
97
|
-
end # describe Assertion::Attributes
|