attributor 5.0.2 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +30 -0
  3. data/.travis.yml +6 -4
  4. data/CHANGELOG.md +6 -1
  5. data/Gemfile +1 -1
  6. data/Guardfile +14 -8
  7. data/Rakefile +4 -5
  8. data/attributor.gemspec +34 -29
  9. data/lib/attributor.rb +23 -29
  10. data/lib/attributor/attribute.rb +108 -127
  11. data/lib/attributor/attribute_resolver.rb +12 -26
  12. data/lib/attributor/dsl_compiler.rb +17 -21
  13. data/lib/attributor/dumpable.rb +1 -2
  14. data/lib/attributor/example_mixin.rb +5 -8
  15. data/lib/attributor/exceptions.rb +5 -6
  16. data/lib/attributor/extensions/randexp.rb +3 -5
  17. data/lib/attributor/extras/field_selector.rb +4 -4
  18. data/lib/attributor/extras/field_selector/transformer.rb +6 -7
  19. data/lib/attributor/families/numeric.rb +0 -2
  20. data/lib/attributor/families/temporal.rb +1 -4
  21. data/lib/attributor/hash_dsl_compiler.rb +22 -25
  22. data/lib/attributor/type.rb +24 -32
  23. data/lib/attributor/types/bigdecimal.rb +7 -14
  24. data/lib/attributor/types/boolean.rb +5 -8
  25. data/lib/attributor/types/class.rb +9 -10
  26. data/lib/attributor/types/collection.rb +34 -44
  27. data/lib/attributor/types/container.rb +9 -15
  28. data/lib/attributor/types/csv.rb +7 -10
  29. data/lib/attributor/types/date.rb +20 -25
  30. data/lib/attributor/types/date_time.rb +7 -14
  31. data/lib/attributor/types/float.rb +4 -6
  32. data/lib/attributor/types/hash.rb +171 -196
  33. data/lib/attributor/types/ids.rb +2 -6
  34. data/lib/attributor/types/integer.rb +12 -17
  35. data/lib/attributor/types/model.rb +39 -48
  36. data/lib/attributor/types/object.rb +2 -4
  37. data/lib/attributor/types/polymorphic.rb +118 -0
  38. data/lib/attributor/types/regexp.rb +4 -5
  39. data/lib/attributor/types/string.rb +6 -7
  40. data/lib/attributor/types/struct.rb +8 -15
  41. data/lib/attributor/types/symbol.rb +3 -6
  42. data/lib/attributor/types/tempfile.rb +5 -6
  43. data/lib/attributor/types/time.rb +11 -11
  44. data/lib/attributor/types/uri.rb +9 -10
  45. data/lib/attributor/version.rb +1 -1
  46. data/spec/attribute_resolver_spec.rb +57 -78
  47. data/spec/attribute_spec.rb +174 -216
  48. data/spec/attributor_spec.rb +11 -15
  49. data/spec/dsl_compiler_spec.rb +19 -33
  50. data/spec/dumpable_spec.rb +6 -7
  51. data/spec/extras/field_selector/field_selector_spec.rb +1 -1
  52. data/spec/families_spec.rb +1 -3
  53. data/spec/hash_dsl_compiler_spec.rb +65 -74
  54. data/spec/spec_helper.rb +9 -3
  55. data/spec/support/hashes.rb +2 -3
  56. data/spec/support/models.rb +30 -36
  57. data/spec/support/polymorphics.rb +10 -0
  58. data/spec/type_spec.rb +38 -61
  59. data/spec/types/bigdecimal_spec.rb +11 -15
  60. data/spec/types/boolean_spec.rb +12 -39
  61. data/spec/types/class_spec.rb +10 -11
  62. data/spec/types/collection_spec.rb +72 -81
  63. data/spec/types/container_spec.rb +22 -26
  64. data/spec/types/csv_spec.rb +15 -16
  65. data/spec/types/date_spec.rb +16 -33
  66. data/spec/types/date_time_spec.rb +16 -33
  67. data/spec/types/file_upload_spec.rb +1 -2
  68. data/spec/types/float_spec.rb +7 -14
  69. data/spec/types/hash_spec.rb +285 -289
  70. data/spec/types/ids_spec.rb +5 -7
  71. data/spec/types/integer_spec.rb +37 -46
  72. data/spec/types/model_spec.rb +111 -128
  73. data/spec/types/polymorphic_spec.rb +134 -0
  74. data/spec/types/regexp_spec.rb +4 -7
  75. data/spec/types/string_spec.rb +17 -21
  76. data/spec/types/struct_spec.rb +40 -47
  77. data/spec/types/tempfile_spec.rb +1 -2
  78. data/spec/types/temporal_spec.rb +9 -0
  79. data/spec/types/time_spec.rb +16 -32
  80. data/spec/types/type_spec.rb +15 -0
  81. data/spec/types/uri_spec.rb +6 -7
  82. metadata +77 -25
@@ -1,6 +1,5 @@
1
1
  require File.join(File.dirname(__FILE__), 'spec_helper.rb')
2
2
 
3
-
4
3
  describe Attributor do
5
4
  context '.resolve_type' do
6
5
  context 'given valid types' do
@@ -12,12 +11,12 @@ describe Attributor do
12
11
  ::Attributor::DateTime => Attributor::DateTime,
13
12
  # FIXME: Boolean doesn't exist in Ruby, thus this causes and error
14
13
  # https://github.com/rightscale/attributor/issues/25
15
- #Boolean => Attributor::Boolean,
14
+ # Boolean => Attributor::Boolean,
16
15
  Attributor::Boolean => Attributor::Boolean,
17
16
  Attributor::Struct => Attributor::Struct
18
17
  }.each do |type, expected_type|
19
18
  it "resolves #{type} as #{expected_type}" do
20
- Attributor.resolve_type(type).should == expected_type
19
+ expect(Attributor.resolve_type(type)).to eq expected_type
21
20
  end
22
21
  end
23
22
  end
@@ -29,35 +28,32 @@ describe Attributor do
29
28
  subject(:humanized) { Attributor.humanize_context(context) }
30
29
 
31
30
  context 'with string value' do
32
- let(:context) { 'some-context'}
33
- it { should eq('some-context')}
31
+ let(:context) { 'some-context' }
32
+ it { should eq('some-context') }
34
33
  end
35
34
 
36
35
  context 'with array value' do
37
- let(:context) { ['a', 'b'] }
36
+ let(:context) { %w(a b) }
38
37
  it { should eq('a.b') }
39
38
  end
40
-
41
39
  end
42
40
 
43
-
44
41
  context '.type_name' do
45
42
  it 'accepts arbtirary classes' do
46
- Attributor.type_name(File).should eq 'File'
43
+ expect(Attributor.type_name(File)).to eq 'File'
47
44
  end
48
45
 
49
46
  it 'accepts instances' do
50
- Attributor.type_name('a string').should eq 'String'
47
+ expect(Attributor.type_name('a string')).to eq 'String'
51
48
  end
52
49
 
53
50
  it 'accepts instances of anonymous types' do
54
- type = Class.new(Attributor::Struct)
55
- Attributor.type_name(type).should eq 'Attributor::Struct'
51
+ type = Class.new(Attributor::Struct)
52
+ expect(Attributor.type_name(type)).to eq 'Attributor::Struct'
56
53
  end
57
54
 
58
55
  it 'accepts Attributor types' do
59
- Attributor.type_name(Attributor::String).should eq 'Attributor::String'
56
+ expect(Attributor.type_name(Attributor::String)).to eq 'Attributor::String'
60
57
  end
61
-
62
58
  end
63
- end
59
+ end
@@ -1,9 +1,7 @@
1
1
  require File.join(File.dirname(__FILE__), 'spec_helper.rb')
2
2
 
3
-
4
3
  describe Attributor::DSLCompiler do
5
-
6
- let(:target) { double("model", attributes: {}) }
4
+ let(:target) { double('model', attributes: {}) }
7
5
 
8
6
  let(:dsl_compiler_options) { {} }
9
7
  subject(:dsl_compiler) { Attributor::DSLCompiler.new(target, dsl_compiler_options) }
@@ -14,7 +12,7 @@ describe Attributor::DSLCompiler do
14
12
  let!(:reference_attributes) { Turducken.attributes }
15
13
  let(:reference_type) { reference_attribute.type }
16
14
  let(:reference_attribute_options) { reference_attribute.options }
17
- let(:reference_attribute) {reference_attributes[attribute_name] }
15
+ let(:reference_attribute) { reference_attributes[attribute_name] }
18
16
 
19
17
  context '#attribute' do
20
18
  let(:attribute_options) { {} }
@@ -25,44 +23,40 @@ describe Attributor::DSLCompiler do
25
23
  context 'when not not given a block for a sub-definition' do
26
24
  context 'without a reference' do
27
25
  it 'raises an error for a missing type' do
28
- expect {
26
+ expect do
29
27
  dsl_compiler.attribute(attribute_name)
30
- }.to raise_error(/type for attribute/)
31
-
28
+ end.to raise_error(/type for attribute/)
32
29
  end
33
30
 
34
31
  it 'creates an attribute given a name and type' do
35
- Attributor::Attribute.should_receive(:new).with(expected_type, expected_options)
32
+ expect(Attributor::Attribute).to receive(:new).with(expected_type, expected_options)
36
33
  dsl_compiler.attribute(attribute_name, type)
37
34
  end
38
35
 
39
-
40
36
  it 'creates an attribute given a name, type, and options' do
41
- Attributor::Attribute.should_receive(:new).with(expected_type, expected_options)
37
+ expect(Attributor::Attribute).to receive(:new).with(expected_type, expected_options)
42
38
  dsl_compiler.attribute(attribute_name, type, attribute_options)
43
39
  end
44
-
45
40
  end
46
41
 
47
-
48
42
  context 'with a reference' do
49
- let(:dsl_compiler_options) { {:reference => Turducken} }
43
+ let(:dsl_compiler_options) { { reference: Turducken } }
50
44
 
51
45
  context 'with no options' do
52
46
  let(:expected_options) { reference_attribute_options }
53
47
 
54
48
  it 'creates an attribute with the inherited type' do
55
- Attributor::Attribute.should_receive(:new).with(expected_type, expected_options)
49
+ expect(Attributor::Attribute).to receive(:new).with(expected_type, expected_options)
56
50
  dsl_compiler.attribute(attribute_name)
57
51
  end
58
52
  end
59
53
 
60
54
  context 'with options' do
61
- let(:attribute_options) { {:description => "some new description", :required => true} }
55
+ let(:attribute_options) { { description: 'some new description', required: true } }
62
56
  let(:expected_options) { reference_attribute_options.merge(attribute_options) }
63
57
 
64
58
  before do
65
- Attributor::Attribute.should_receive(:new).with(expected_type, expected_options)
59
+ expect(Attributor::Attribute).to receive(:new).with(expected_type, expected_options)
66
60
  end
67
61
 
68
62
  it 'creates an attribute with the inherited type and merged options' do
@@ -72,7 +66,6 @@ describe Attributor::DSLCompiler do
72
66
  it 'accepts explicit nil type' do
73
67
  dsl_compiler.attribute(attribute_name, nil, attribute_options)
74
68
  end
75
-
76
69
  end
77
70
 
78
71
  context 'for a referenced Model attribute' do
@@ -81,50 +74,43 @@ describe Attributor::DSLCompiler do
81
74
  let(:expected_options) { reference_attribute_options.merge(attribute_options) }
82
75
 
83
76
  it 'creates an attribute with the inherited type' do
84
- Attributor::Attribute.should_receive(:new).with(expected_type, expected_options)
77
+ expect(Attributor::Attribute).to receive(:new).with(expected_type, expected_options)
85
78
  dsl_compiler.attribute(attribute_name)
86
79
  end
87
80
  end
88
-
89
81
  end
90
-
91
82
  end
92
83
 
93
-
94
84
  context 'when given a block for sub-attributes' do
95
- let(:attribute_block) { Proc.new { } }
85
+ let(:attribute_block) { proc {} }
96
86
  let(:attribute_name) { :turkey }
97
87
  let(:type) { Attributor::Struct }
98
88
  let(:expected_type) { Attributor::Struct }
99
89
 
100
90
  context 'without a reference' do
101
91
  it 'defaults type to Struct' do
102
- Attributor::Attribute.should_receive(:new).with(expected_type, expected_options)
92
+ expect(Attributor::Attribute).to receive(:new).with(expected_type, expected_options)
103
93
  dsl_compiler.attribute(attribute_name, &attribute_block)
104
94
  end
105
95
  end
106
96
 
107
97
  context 'with a reference' do
108
- let(:dsl_compiler_options) { {:reference => Turducken} }
98
+ let(:dsl_compiler_options) { { reference: Turducken } }
109
99
  let(:expected_options) do
110
- attribute_options.merge(:reference => reference_type)
100
+ attribute_options.merge(reference: reference_type)
111
101
  end
112
102
 
113
103
  it 'sets the type of the attribute to Struct' do
114
- Attributor::Attribute.should_receive(:new).
115
- with(expected_type, {:description=>"The turkey", :reference=>Turkey})
104
+ expect(Attributor::Attribute).to receive(:new)
105
+ .with(expected_type, description: 'The turkey', reference: Turkey)
116
106
  dsl_compiler.attribute(attribute_name, attribute_options, &attribute_block)
117
107
  end
118
108
 
119
109
  it 'passes the correct reference to the created attribute' do
120
- Attributor::Attribute.should_receive(:new).with(expected_type, expected_options)
121
- dsl_compiler.attribute(attribute_name, type, attribute_options, &attribute_block)
110
+ expect(Attributor::Attribute).to receive(:new).with(expected_type, expected_options)
111
+ dsl_compiler.attribute(attribute_name, type, attribute_options, &attribute_block)
122
112
  end
123
-
124
113
  end
125
-
126
114
  end
127
-
128
115
  end
129
-
130
116
  end
@@ -1,30 +1,29 @@
1
1
  require File.join(File.dirname(__FILE__), 'spec_helper.rb')
2
2
 
3
3
  describe 'Dumpable' do
4
-
5
4
  context 'for classes forgetting to implement #dump' do
6
- let(:type) {
5
+ let(:type) do
7
6
  Class.new do
8
7
  include Attributor::Dumpable
9
8
  end
10
- }
9
+ end
11
10
 
12
11
  it 'gets an exception' do
13
- expect{ type.new.dump }.to raise_exception(NotImplementedError)
12
+ expect { type.new.dump }.to raise_exception(NotImplementedError)
14
13
  end
15
14
  end
16
15
 
17
16
  context 'for classes properly implementing #dump' do
18
- let(:type) {
17
+ let(:type) do
19
18
  Class.new do
20
19
  include Attributor::Dumpable
21
20
  def dump
22
21
  end
23
22
  end
24
- }
23
+ end
25
24
 
26
25
  it 'do not get the base exception' do
27
- expect{ type.new.dump }.to_not raise_exception
26
+ expect { type.new.dump }.to_not raise_error
28
27
  end
29
28
  end
30
29
  end
@@ -29,7 +29,7 @@ describe Attributor::FieldSelector do
29
29
  cases.each do |fields, result|
30
30
  it "loads #{fields.inspect}" do
31
31
  loaded = subject.load(fields)
32
- loaded.should eq result
32
+ expect(loaded).to eq result
33
33
  end
34
34
  end
35
35
  end
@@ -1,14 +1,12 @@
1
1
  require File.join(File.dirname(__FILE__), 'spec_helper.rb')
2
2
 
3
3
  describe 'Type families' do
4
-
5
4
  let(:types) { ObjectSpace.each_object(Class).select { |k| k < Attributor::Type } }
6
5
 
7
6
  it 'are set on all types' do
8
7
  types.each do |type|
9
8
  next if type == Attributor::Object # object has no set family
10
- type.should_not be_in_family('attributor')
9
+ expect(type).not_to be_in_family('attributor')
11
10
  end
12
11
  end
13
-
14
12
  end
@@ -1,176 +1,167 @@
1
1
  require File.join(File.dirname(__FILE__), 'spec_helper.rb')
2
2
 
3
-
4
3
  describe Attributor::HashDSLCompiler do
5
-
6
- let(:target) { double("model", attributes: {}) }
4
+ let(:target) { double('model', attributes: {}) }
7
5
 
8
6
  let(:dsl_compiler_options) { {} }
9
7
  subject(:dsl_compiler) { Attributor::HashDSLCompiler.new(target, dsl_compiler_options) }
10
8
 
11
9
  it 'returns the requirements DSL attached to the right target' do
12
10
  req_dsl = dsl_compiler._requirements_dsl
13
- req_dsl.should be_kind_of( Attributor::HashDSLCompiler::RequiresDSL )
14
- req_dsl.target.should be(target)
11
+ expect(req_dsl).to be_kind_of(Attributor::HashDSLCompiler::RequiresDSL)
12
+ expect(req_dsl.target).to be(target)
15
13
  end
16
14
 
17
15
  context 'requires' do
18
-
19
16
  context 'without any arguments' do
20
17
  it 'without params returns the underlying compiler to chain internal methods' do
21
- subject.requires.should be_kind_of( Attributor::HashDSLCompiler::RequiresDSL )
18
+ expect(subject.requires).to be_kind_of(Attributor::HashDSLCompiler::RequiresDSL)
22
19
  end
23
20
  end
24
21
 
25
22
  context 'with params only (and some options)' do
26
23
  it 'takes then array to mean all attributes are required' do
27
- target.should_receive(:add_requirement)
28
- requirement = subject.requires :one, :two , description: "These are very required"
29
- requirement.should be_kind_of( Attributor::HashDSLCompiler::Requirement )
30
- requirement.type.should be(:all)
24
+ expect(target).to receive(:add_requirement)
25
+ requirement = subject.requires :one, :two, description: 'These are very required'
26
+ expect(requirement).to be_kind_of(Attributor::HashDSLCompiler::Requirement)
27
+ expect(requirement.type).to be(:all)
31
28
  end
32
29
  end
33
30
  context 'with a block only (and some options)' do
34
31
  it 'evals it in the context of the Compiler' do
35
- proc = Proc.new {}
32
+ proc = proc {}
36
33
  dsl = dsl_compiler._requirements_dsl
37
- dsl.should_receive(:instance_eval)#.with(&proc) << Does rspec 2.99 support block args?
38
- subject.requires description: "These are very required", &proc
34
+ expect(dsl).to receive(:instance_eval) # .with(&proc) << Does rspec 2.99 support block args?
35
+ subject.requires description: 'These are very required', &proc
39
36
  end
40
37
  end
41
-
42
-
43
38
  end
44
39
 
45
40
  context 'RequiresDSL' do
46
-
47
- subject(:dsl){ Attributor::HashDSLCompiler::RequiresDSL.new(target) }
41
+ subject(:dsl) { Attributor::HashDSLCompiler::RequiresDSL.new(target) }
48
42
  it 'stores the received target' do
49
- subject.target.should be(target)
43
+ expect(subject.target).to be(target)
50
44
  end
51
45
 
52
46
  context 'has DSL methods' do
53
- let(:req){ double("requirement") }
54
- let(:attr_names){ [:one, :two, :tree] }
55
- let(:number){ 2 }
56
- let(:req_class){ Attributor::HashDSLCompiler::Requirement }
47
+ let(:req) { double('requirement') }
48
+ let(:attr_names) { [:one, :two, :tree] }
49
+ let(:number) { 2 }
50
+ let(:req_class) { Attributor::HashDSLCompiler::Requirement }
57
51
  before do
58
- target.should_receive(:add_requirement).with(req)
52
+ expect(target).to receive(:add_requirement).with(req)
59
53
  end
60
54
  it 'responds to .all' do
61
- req_class.should_receive(:new).with( all: attr_names ).and_return(req)
55
+ expect(req_class).to receive(:new).with(all: attr_names).and_return(req)
62
56
  subject.all(*attr_names)
63
57
  end
64
58
  it 'responds to .at_most(n)' do
65
- req_class.should_receive(:new).with( at_most: number ).and_return(req)
59
+ expect(req_class).to receive(:new).with(at_most: number).and_return(req)
66
60
  subject.at_most(number)
67
61
  end
68
62
  it 'responds to .at_least(n)' do
69
- req_class.should_receive(:new).with( at_least: number ).and_return(req)
63
+ expect(req_class).to receive(:new).with(at_least: number).and_return(req)
70
64
  subject.at_least(number)
71
65
  end
72
66
  it 'responds to .exactly(n)' do
73
- req_class.should_receive(:new).with( exactly: number ).and_return(req)
67
+ expect(req_class).to receive(:new).with(exactly: number).and_return(req)
74
68
  subject.exactly(number)
75
69
  end
76
70
  it 'responds to .exclusive' do
77
- req_class.should_receive(:new).with( exclusive: attr_names ).and_return(req)
71
+ expect(req_class).to receive(:new).with(exclusive: attr_names).and_return(req)
78
72
  subject.exclusive(*attr_names)
79
73
  end
80
-
81
74
  end
82
75
  end
83
76
 
84
77
  context 'Requirement' do
85
-
86
- let(:attr_names){ [:one, :two, :tree] }
87
- let(:req_class){ Attributor::HashDSLCompiler::Requirement }
78
+ let(:attr_names) { [:one, :two, :tree] }
79
+ let(:req_class) { Attributor::HashDSLCompiler::Requirement }
88
80
 
89
81
  context 'initialization' do
90
82
  it 'calls .of for exclusive' do
91
- req_class.any_instance.should_receive(:of).with(*attr_names)
83
+ expect_any_instance_of(req_class).to receive(:of).with(*attr_names)
92
84
  req_class.new(exclusive: attr_names)
93
85
  end
94
86
  it 'calls .of for all' do
95
- req_class.any_instance.should_receive(:of).with(*attr_names)
87
+ expect_any_instance_of(req_class).to receive(:of).with(*attr_names)
96
88
  req_class.new(all: attr_names)
97
89
  end
98
90
  it 'saves the number for the rest' do
99
- req_class.new(exactly: 1).number.should be(1)
100
- req_class.new(exactly: 1).type.should be(:exactly)
101
- req_class.new(at_most: 2).number.should be(2)
102
- req_class.new(at_most: 2).type.should be(:at_most)
103
- req_class.new(at_least: 3).number.should be(3)
104
- req_class.new(at_least: 3).type.should be(:at_least)
91
+ expect(req_class.new(exactly: 1).number).to be(1)
92
+ expect(req_class.new(exactly: 1).type).to be(:exactly)
93
+ expect(req_class.new(at_most: 2).number).to be(2)
94
+ expect(req_class.new(at_most: 2).type).to be(:at_most)
95
+ expect(req_class.new(at_least: 3).number).to be(3)
96
+ expect(req_class.new(at_least: 3).type).to be(:at_least)
105
97
  end
106
98
  it 'understands and saves a :description' do
107
- req = req_class.new(exactly: 1, description: "Hello")
108
- req.number.should be(1)
109
- req.description.should eq("Hello")
99
+ req = req_class.new(exactly: 1, description: 'Hello')
100
+ expect(req.number).to be(1)
101
+ expect(req.description).to eq('Hello')
110
102
  end
111
103
  end
112
104
 
113
105
  context 'Requirement#validate' do
114
- let(:requirement){ req_class.new(arguments) }
115
- let(:subject){ requirement.validate(value,["$"],nil)}
106
+ let(:requirement) { req_class.new(arguments) }
107
+ let(:subject) { requirement.validate(value, ['$'], nil) }
116
108
 
117
109
  context 'for :all' do
118
- let(:arguments){ { all: [:one, :two, :three] } }
119
- let(:value){ [:one] }
120
- let(:validation_error){ ["Key two is required for $.", "Key three is required for $."] }
121
- it { subject.should include(*validation_error) }
110
+ let(:arguments) { { all: [:one, :two, :three] } }
111
+ let(:value) { [:one] }
112
+ let(:validation_error) { ['Key two is required for $.', 'Key three is required for $.'] }
113
+ it { expect(subject).to include(*validation_error) }
122
114
  end
123
115
  context 'for :exactly' do
124
- let(:requirement) { req_class.new(exactly: 1).of(:one,:two) }
125
- let(:value){ [:one, :two] }
126
- let(:validation_error){ "Exactly 1 of the following keys [:one, :two] are required for $. Found 2 instead: [:one, :two]" }
127
- it { subject.should include(validation_error) }
116
+ let(:requirement) { req_class.new(exactly: 1).of(:one, :two) }
117
+ let(:value) { [:one, :two] }
118
+ let(:validation_error) { 'Exactly 1 of the following keys [:one, :two] are required for $. Found 2 instead: [:one, :two]' }
119
+ it { expect(subject).to include(validation_error) }
128
120
  end
129
121
  context 'for :at_least' do
130
- let(:requirement) { req_class.new(at_least: 2).of(:one,:two,:three) }
131
- let(:value){ [:one] }
132
- let(:validation_error){ "At least 2 keys out of [:one, :two, :three] are required to be passed in for $. Found [:one]" }
133
- it { subject.should include(validation_error) }
122
+ let(:requirement) { req_class.new(at_least: 2).of(:one, :two, :three) }
123
+ let(:value) { [:one] }
124
+ let(:validation_error) { 'At least 2 keys out of [:one, :two, :three] are required to be passed in for $. Found [:one]' }
125
+ it { expect(subject).to include(validation_error) }
134
126
  end
135
127
  context 'for :at_most' do
136
- let(:requirement) { req_class.new(at_most: 1).of(:one,:two,:three) }
137
- let(:value){ [:one, :two] }
138
- let(:validation_error){ "At most 1 keys out of [:one, :two, :three] can be passed in for $. Found [:one, :two]" }
139
- it { subject.should include(validation_error) }
128
+ let(:requirement) { req_class.new(at_most: 1).of(:one, :two, :three) }
129
+ let(:value) { [:one, :two] }
130
+ let(:validation_error) { 'At most 1 keys out of [:one, :two, :three] can be passed in for $. Found [:one, :two]' }
131
+ it { expect(subject).to include(validation_error) }
140
132
  end
141
133
  context 'for :exclusive' do
142
- let(:arguments){ { exclusive: [:one, :two] } }
143
- let(:value){ [:one, :two] }
144
- let(:validation_error){ "keys [:one, :two] are mutually exclusive for $." }
145
- it { subject.should include(validation_error) }
134
+ let(:arguments) { { exclusive: [:one, :two] } }
135
+ let(:value) { [:one, :two] }
136
+ let(:validation_error) { 'keys [:one, :two] are mutually exclusive for $.' }
137
+ it { expect(subject).to include(validation_error) }
146
138
  end
147
139
  end
148
140
 
149
141
  context 'Requirement#describe' do
150
-
151
142
  it 'should work for :all' do
152
143
  req = req_class.new(all: attr_names).describe
153
- req.should eq( type: :all, attributes: [:one, :two, :tree] )
144
+ expect(req).to eq(type: :all, attributes: [:one, :two, :tree])
154
145
  end
155
146
  it 'should work for :exclusive n' do
156
147
  req = req_class.new(exclusive: attr_names).describe
157
- req.should eq( type: :exclusive, attributes: [:one, :two, :tree] )
148
+ expect(req).to eq(type: :exclusive, attributes: [:one, :two, :tree])
158
149
  end
159
150
  it 'should work for :exactly' do
160
151
  req = req_class.new(exactly: 1).of(*attr_names).describe
161
- req.should include( type: :exactly, count: 1, attributes: [:one, :two, :tree] )
152
+ expect(req).to include(type: :exactly, count: 1, attributes: [:one, :two, :tree])
162
153
  end
163
154
  it 'should work for :at_most n' do
164
155
  req = req_class.new(at_most: 1).of(*attr_names).describe
165
- req.should include( type: :at_most, count: 1, attributes: [:one, :two, :tree] )
156
+ expect(req).to include(type: :at_most, count: 1, attributes: [:one, :two, :tree])
166
157
  end
167
158
  it 'should work for :at_least n' do
168
159
  req = req_class.new(at_least: 1).of(*attr_names).describe
169
- req.should include( type: :at_least, count: 1, attributes: [:one, :two, :tree] )
160
+ expect(req).to include(type: :at_least, count: 1, attributes: [:one, :two, :tree])
170
161
  end
171
162
  it 'should report a description' do
172
- req = req_class.new(at_least: 1, description: "no more than 1").of(*attr_names).describe
173
- req.should include( type: :at_least, count: 1, attributes: [:one, :two, :tree], description: "no more than 1" )
163
+ req = req_class.new(at_least: 1, description: 'no more than 1').of(*attr_names).describe
164
+ expect(req).to include(type: :at_least, count: 1, attributes: [:one, :two, :tree], description: 'no more than 1')
174
165
  end
175
166
  end
176
167
  end