attributor 5.0.2 → 5.1.0

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