sbf-dm-types 1.3.0.beta

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 (76) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +45 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +468 -0
  5. data/.travis.yml +52 -0
  6. data/Gemfile +67 -0
  7. data/LICENSE +20 -0
  8. data/README.rdoc +3 -0
  9. data/Rakefile +4 -0
  10. data/dm-types.gemspec +26 -0
  11. data/lib/dm-types/api_key.rb +30 -0
  12. data/lib/dm-types/bcrypt_hash.rb +33 -0
  13. data/lib/dm-types/comma_separated_list.rb +28 -0
  14. data/lib/dm-types/csv.rb +34 -0
  15. data/lib/dm-types/enum.rb +55 -0
  16. data/lib/dm-types/epoch_time.rb +35 -0
  17. data/lib/dm-types/file_path.rb +24 -0
  18. data/lib/dm-types/flag.rb +64 -0
  19. data/lib/dm-types/ip_address.rb +34 -0
  20. data/lib/dm-types/json.rb +48 -0
  21. data/lib/dm-types/paranoid/base.rb +56 -0
  22. data/lib/dm-types/paranoid_boolean.rb +23 -0
  23. data/lib/dm-types/paranoid_datetime.rb +22 -0
  24. data/lib/dm-types/regexp.rb +21 -0
  25. data/lib/dm-types/slug.rb +28 -0
  26. data/lib/dm-types/support/dirty_minder.rb +168 -0
  27. data/lib/dm-types/support/flags.rb +41 -0
  28. data/lib/dm-types/uri.rb +27 -0
  29. data/lib/dm-types/uuid.rb +64 -0
  30. data/lib/dm-types/version.rb +5 -0
  31. data/lib/dm-types/yaml.rb +39 -0
  32. data/lib/dm-types.rb +23 -0
  33. data/spec/fixtures/api_user.rb +14 -0
  34. data/spec/fixtures/article.rb +35 -0
  35. data/spec/fixtures/bookmark.rb +23 -0
  36. data/spec/fixtures/invention.rb +7 -0
  37. data/spec/fixtures/network_node.rb +36 -0
  38. data/spec/fixtures/person.rb +25 -0
  39. data/spec/fixtures/software_package.rb +33 -0
  40. data/spec/fixtures/ticket.rb +21 -0
  41. data/spec/fixtures/tshirt.rb +24 -0
  42. data/spec/integration/api_key_spec.rb +27 -0
  43. data/spec/integration/bcrypt_hash_spec.rb +47 -0
  44. data/spec/integration/comma_separated_list_spec.rb +87 -0
  45. data/spec/integration/dirty_minder_spec.rb +197 -0
  46. data/spec/integration/enum_spec.rb +78 -0
  47. data/spec/integration/epoch_time_spec.rb +61 -0
  48. data/spec/integration/file_path_spec.rb +160 -0
  49. data/spec/integration/flag_spec.rb +72 -0
  50. data/spec/integration/ip_address_spec.rb +153 -0
  51. data/spec/integration/json_spec.rb +72 -0
  52. data/spec/integration/slug_spec.rb +67 -0
  53. data/spec/integration/uri_spec.rb +117 -0
  54. data/spec/integration/uuid_spec.rb +102 -0
  55. data/spec/integration/yaml_spec.rb +87 -0
  56. data/spec/shared/flags_shared_spec.rb +37 -0
  57. data/spec/shared/identity_function_group.rb +5 -0
  58. data/spec/spec_helper.rb +30 -0
  59. data/spec/unit/bcrypt_hash_spec.rb +155 -0
  60. data/spec/unit/csv_spec.rb +142 -0
  61. data/spec/unit/dirty_minder_spec.rb +65 -0
  62. data/spec/unit/enum_spec.rb +126 -0
  63. data/spec/unit/epoch_time_spec.rb +74 -0
  64. data/spec/unit/file_path_spec.rb +75 -0
  65. data/spec/unit/flag_spec.rb +114 -0
  66. data/spec/unit/ip_address_spec.rb +109 -0
  67. data/spec/unit/json_spec.rb +126 -0
  68. data/spec/unit/paranoid_boolean_spec.rb +149 -0
  69. data/spec/unit/paranoid_datetime_spec.rb +153 -0
  70. data/spec/unit/regexp_spec.rb +63 -0
  71. data/spec/unit/uri_spec.rb +83 -0
  72. data/spec/unit/yaml_spec.rb +111 -0
  73. data/tasks/spec.rake +21 -0
  74. data/tasks/yard.rake +9 -0
  75. data/tasks/yardstick.rake +19 -0
  76. metadata +229 -0
@@ -0,0 +1,87 @@
1
+ require_relative '../spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require_relative '../fixtures/person'
6
+
7
+ describe DataMapper::TypesFixtures::Person do
8
+ supported_by :all do
9
+ before :all do
10
+ @resource = DataMapper::TypesFixtures::Person.new(:name => '')
11
+ end
12
+
13
+ describe 'with no interests information' do
14
+ before :all do
15
+ @resource.interests = nil
16
+ end
17
+
18
+ describe 'when dumped and loaded again' do
19
+ before :all do
20
+ expect(@resource.save).to be(true)
21
+ @resource.reload
22
+ end
23
+
24
+ it 'has no interests' do
25
+ expect(@resource.interests).to eq nil
26
+ end
27
+ end
28
+ end
29
+
30
+ describe 'with no interests information' do
31
+ before :all do
32
+ @resource.interests = []
33
+ end
34
+
35
+ describe 'when dumped and loaded again' do
36
+ before :all do
37
+ expect(@resource.save).to be(true)
38
+ @resource.reload
39
+ end
40
+
41
+ it 'has empty interests list' do
42
+ expect(@resource.interests).to eq []
43
+ end
44
+ end
45
+ end
46
+
47
+ describe 'with interests information given as a Hash' do
48
+ it 'raises ArgumentError' do
49
+ expect do
50
+ @resource.interests = { :hash => 'value' }
51
+ @resource.save
52
+ end.to raise_error(ArgumentError, /must be a string, an array or nil/)
53
+ end
54
+ end
55
+
56
+ describe 'with a few items on the interests list' do
57
+ before :all do
58
+ @input = 'fire, water, fire, a whole lot of other interesting things, ,,,'
59
+ @resource.interests = @input
60
+ end
61
+
62
+ describe 'when dumped and loaded again' do
63
+ before :all do
64
+ expect(@resource.save).to be(true)
65
+ @resource.reload
66
+ end
67
+
68
+ it 'includes "fire" in interests' do
69
+ expect(@resource.interests).to include('fire')
70
+ end
71
+
72
+ it 'includes "water" in interests' do
73
+ expect(@resource.interests).to include('water')
74
+ end
75
+
76
+ it 'includes "a whole lot of other interesting things" in interests' do
77
+ expect(@resource.interests).to include('a whole lot of other interesting things')
78
+ end
79
+
80
+ it 'has blank entries removed' do
81
+ expect(@resource.interests.any? { |i| DataMapper::Ext.blank?(i) }).to be(false)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,197 @@
1
+ require_relative '../spec_helper'
2
+
3
+ try_spec do
4
+
5
+ # FIXME: DirtyMinder is currently unsupported on RBX, because unlike the other
6
+ # supported Rubies, RBX core class (e.g. Array, Hash) methods use #send(). In
7
+ # other words, the other Rubies don't use #send() (they map directly to their
8
+ # C functions).
9
+ #
10
+ # The current methodology takes advantage of this by using #send() to forward
11
+ # method invocations we've hooked. Supporting RBX will require finding
12
+ # another way, possibly for all Rubies. In the meantime, something is better
13
+ # than nothing.
14
+ next if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'rbx'
15
+
16
+ require_relative '../fixtures/person'
17
+
18
+ describe DataMapper::TypesFixtures::Person do
19
+ supported_by :all do
20
+ before :all do
21
+ @resource = DataMapper::TypesFixtures::Person.new(:name => 'Thomas Edison')
22
+ end
23
+
24
+ describe 'with positions indirectly mutated as a hash' do
25
+ before :all do
26
+ @resource.positions = {
27
+ 'company' => "Soon To Be Dirty, LLC",
28
+ 'title' => "Layperson",
29
+ 'details' => { 'awesome' => true },
30
+ }
31
+ @resource.save
32
+ @resource.reload
33
+ expect(@resource.positions['title']).to eq 'Layperson'
34
+ end
35
+
36
+ describe 'when I change positions' do
37
+ before :all do
38
+ expect(@resource.clean?).to eq true
39
+ @resource.positions['title'] = 'Chief Layer of People'
40
+ @resource.save
41
+ @resource.reload
42
+ end
43
+
44
+ it 'remembers the new position' do
45
+ expect(@resource.positions['title']).to eq 'Chief Layer of People'
46
+ end
47
+ end
48
+
49
+ describe 'when I add a new attribute of the position' do
50
+ before :all do
51
+ expect(@resource.clean?).to eq true
52
+ @resource.positions['pays_buttloads_of_money'] = true
53
+ @resource.save
54
+ @resource.reload
55
+ end
56
+
57
+ it 'remembers the new attribute' do
58
+ expect(@resource.positions['pays_buttloads_of_money']).to be(true)
59
+ end
60
+ end
61
+
62
+ describe 'when I change the details of the position' do
63
+ before :all do
64
+ expect(@resource.clean?).to eq true
65
+ @resource.positions['details'].merge!('awesome' => "VERY TRUE")
66
+ @resource.save
67
+ @resource.reload
68
+ end
69
+
70
+ it 'remembers the changed detail' do
71
+ pending 'not supported (YET)'
72
+
73
+ # TODO: Not supported (yet?) -- this is a much harder problem to
74
+ # solve: using mutating accessors of nested objects. We could
75
+ # detect it from #dirty? (using the #hash method), but #dirty?
76
+ # only returns the status of known-mutated properties (not full,
77
+ # on-demand scan of object dirty-ness).
78
+ expect(@resource.positions['details']['awesome']).to eq 'VERY TRUE'
79
+ end
80
+ end
81
+
82
+ describe 'when I reload the resource while the property is dirty' do
83
+ before :all do
84
+ @resource.positions['title'] = 'Chief Layer of People'
85
+ @resource.reload
86
+ end
87
+
88
+ it 'reflects the previously set/persisted value' do
89
+ expect(@resource.positions).not_to be_nil
90
+ expect(@resource.positions['title']).to eq 'Layperson'
91
+ end
92
+ end
93
+
94
+ end # positions indirectly mutated as a hash
95
+
96
+ describe 'with positions indirectly mutated as an array' do
97
+ before :all do
98
+ @resource.positions = [
99
+ { 'company' => "Soon To Be Dirty, LLC",
100
+ 'title' => "Layperson",
101
+ 'details' => { 'awesome' => true },
102
+ },
103
+ ]
104
+ @resource.save
105
+ @resource.reload
106
+ expect(@resource.positions.first['title']).to eq 'Layperson'
107
+ end
108
+
109
+ describe 'when I remove the position' do
110
+ before :all do
111
+ expect(@resource.clean?).to eq true
112
+ @resource.positions.pop
113
+ @resource.save
114
+ @resource.reload
115
+ end
116
+
117
+ it "knows there aren't any positions" do
118
+ expect(@resource.positions).to eq []
119
+ end
120
+ end
121
+
122
+ describe "when I add a new position" do
123
+ before :all do
124
+ expect(@resource.clean?).to eq true
125
+ @resource.positions << {
126
+ 'company' => "Down and Dirty, LP",
127
+ 'title' => "Porn Star",
128
+ 'details' => { 'awesome' => "also true" },
129
+ }
130
+ @resource.save
131
+ @resource.reload
132
+ end
133
+
134
+ it "knows there's two positions" do
135
+ expect(@resource.positions.length).to eq 2
136
+ end
137
+
138
+ it 'knows which position is which' do
139
+ expect(@resource.positions.first['title']).to eq 'Layperson'
140
+ expect(@resource.positions.last['title']).to eq 'Porn Star'
141
+ end
142
+
143
+ describe 'when I change the details of one of the positions' do
144
+ before :all do
145
+ @resource.positions.last['details'].merge!('high_risk' => true)
146
+ @resource.save
147
+ @resource.reload
148
+ end
149
+
150
+ it 'remembers the changed detail' do
151
+ pending 'not supported (YET)'
152
+
153
+ # TODO: Not supported (yet?) -- this is a much harder problem to
154
+ # solve: using mutating accessors of nested objects. We could
155
+ # detect it from #dirty? (using the #hash method), but #dirty?
156
+ # only returns the status of known-mutated properties (not full,
157
+ # on-demand scan of object dirty-ness).
158
+ expect(@resource.positions.last['details']['high_risk']).to eq true
159
+ end
160
+ end
161
+ end # when I add a new position
162
+
163
+ describe 'when I remove the position with a block-based mutator' do
164
+ before :all do
165
+ expect(@resource.clean?).to eq true
166
+ @resource.positions.reject! { |_| true }
167
+ @resource.save
168
+ @resource.reload
169
+ end
170
+
171
+ it "knows there aren't any positions" do
172
+ expect(@resource.positions).to eq []
173
+ end
174
+ end
175
+
176
+ describe 'when I mutate positions through a reference' do
177
+ before :all do
178
+ expect(@resource.clean?).to eq true
179
+ @positions = @resource.positions
180
+ @positions << {
181
+ 'company' => "Ooga Booga, Inc",
182
+ 'title' => "Rocker",
183
+ }
184
+ end
185
+
186
+ it 'reflects the change in both the property and the reference' do
187
+ expect(@resource.positions.length).to eq 2
188
+ expect(@resource.positions.last['title']).to eq 'Rocker'
189
+ expect(@positions.last['title']).to eq 'Rocker'
190
+ end
191
+ end
192
+
193
+ end # positions indirectly mutated as an array
194
+
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,78 @@
1
+ require_relative '../spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require_relative '../fixtures/ticket'
6
+
7
+ describe DataMapper::TypesFixtures::Ticket do
8
+ supported_by :all do
9
+ describe 'that is dumped and then loaded' do
10
+ before :all do
11
+ @resource = DataMapper::TypesFixtures::Ticket.new(
12
+ :title => "Can't order by aggregated fields",
13
+ :id => 789,
14
+ :body => "I'm trying to use the aggregate method and sort the results by a summed field, but it doesn't work.",
15
+ :status => 'confirmed'
16
+ )
17
+
18
+ expect(@resource.save).to be(true)
19
+ @resource.reload
20
+ end
21
+
22
+ it 'preserves property value' do
23
+ expect(@resource.status).to eq :confirmed
24
+ end
25
+ end
26
+
27
+ describe 'that is supplied a matching enumeration value' do
28
+ before :all do
29
+ @resource = DataMapper::TypesFixtures::Ticket.new(:status => :assigned)
30
+ end
31
+
32
+ it 'typecasts it for outside reader' do
33
+ expect(@resource.status).to eq :assigned
34
+ end
35
+ end
36
+
37
+ describe '#get' do
38
+ before :all do
39
+ @resource = DataMapper::TypesFixtures::Ticket.new(
40
+ :title => '"sudo make install" of drizzle fails because it tries to chown mysql',
41
+ :id => 257497,
42
+ :body => "Note that at the very least, there should be a check to see whether or not the user is created before chown'ing a file to the user.",
43
+ :status => 'confirmed'
44
+ )
45
+ expect(@resource.save).to be(true)
46
+ end
47
+
48
+ it 'supports queries with equality operator on enumeration property' do
49
+ expect(DataMapper::TypesFixtures::Ticket.all(:status => :confirmed)).to include(@resource)
50
+ end
51
+
52
+ it 'supports queries with inequality operator on enumeration property' do
53
+ expect(DataMapper::TypesFixtures::Ticket.all(:status.not => :confirmed)).not_to include(@resource)
54
+ end
55
+ end
56
+
57
+ describe 'with value unknown to enumeration property' do
58
+ before :all do
59
+ @resource = DataMapper::TypesFixtures::Ticket.new(:status => :undecided)
60
+ end
61
+
62
+ # TODO: consider sharing shared spec exampels with dm-validations,
63
+ # which has 'invalid model' shared group
64
+ it 'is invalid (auto validation for :within kicks in)' do
65
+ expect(@resource).not_to be_valid
66
+ end
67
+
68
+ it 'has errors' do
69
+ expect(@resource.errors).not_to be_empty
70
+ end
71
+
72
+ it 'has a meaningful error message on invalid property' do
73
+ expect(@resource.errors.on(:status)).to include('Status must be one of unconfirmed, confirmed, assigned, resolved, not_applicable')
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,61 @@
1
+ require_relative '../spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require_relative '../fixtures/person'
6
+
7
+ describe DataMapper::TypesFixtures::Person do
8
+ supported_by :all do
9
+ before :all do
10
+ @resource = DataMapper::TypesFixtures::Person.new(:name => '')
11
+ end
12
+
13
+ describe 'with a birthday' do
14
+ before :all do
15
+ @resource.birthday = '1983-05-03'
16
+ end
17
+
18
+ describe 'after typecasting string input' do
19
+ it 'has a valid birthday' do
20
+ expect(@resource.birthday).to eq ::Time.parse('1983-05-03')
21
+ end
22
+ end
23
+
24
+ describe 'when dumped and loaded again' do
25
+ before :all do
26
+ expect(@resource.save).to be(true)
27
+ @resource.reload
28
+ end
29
+
30
+ it 'has a valid birthday' do
31
+ expect(@resource.birthday).to eq ::Time.parse('1983-05-03')
32
+ end
33
+ end
34
+ end
35
+
36
+ describe 'without a birthday' do
37
+ before :all do
38
+ @resource.birthday = nil
39
+ end
40
+
41
+ describe 'after typecasting nil' do
42
+ it 'has a nil value for birthday' do
43
+ expect(@resource.birthday).to be_nil
44
+ end
45
+ end
46
+
47
+ describe 'when dumped and loaded again' do
48
+ before :all do
49
+ expect(@resource.save).to be(true)
50
+ @resource.reload
51
+ end
52
+
53
+ it 'has a nil value for birthday' do
54
+ expect(@resource.birthday).to be_nil
55
+ end
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,160 @@
1
+ require_relative '../spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require_relative '../fixtures/software_package'
6
+
7
+ describe DataMapper::TypesFixtures::SoftwarePackage do
8
+ supported_by :all do
9
+ describe 'with source path at /var/cache/apt/archives/linux-libc-dev_2.6.28-11.40_i386.deb' do
10
+ before :all do
11
+ @source_path = '/var/cache/apt/archives/linux-libc-dev_2.6.28-11.40_i386.deb'
12
+ @resource = DataMapper::TypesFixtures::SoftwarePackage.new(:source_path => @source_path)
13
+ end
14
+
15
+ describe 'when is a new record' do
16
+ before :all do
17
+ end
18
+
19
+ it 'points to original path' do
20
+ expect(@resource.source_path.to_s).to eq @source_path
21
+ end
22
+
23
+ it 'responds to :directory?' do
24
+ expect(@resource.source_path).to respond_to(:directory?)
25
+ end
26
+
27
+ it 'responds to :file?' do
28
+ expect(@resource.source_path).to respond_to(:file?)
29
+ end
30
+
31
+ it 'responds to :dirname' do
32
+ expect(@resource.source_path).to respond_to(:dirname)
33
+ end
34
+
35
+ it 'responds to :absolute?' do
36
+ expect(@resource.source_path).to respond_to(:absolute?)
37
+ end
38
+
39
+ it 'responds to :readable?' do
40
+ expect(@resource.source_path).to respond_to(:readable?)
41
+ end
42
+
43
+ it 'responds to :size' do
44
+ expect(@resource.source_path).to respond_to(:size)
45
+ end
46
+ end
47
+ end
48
+
49
+ describe 'with destination path at /usr/local' do
50
+ before :all do
51
+ @destination_path = '/usr/local'
52
+ @resource = DataMapper::TypesFixtures::SoftwarePackage.new(:destination_path => @destination_path)
53
+ end
54
+
55
+ describe 'when saved and reloaded' do
56
+ before :all do
57
+ expect(@resource.save).to be(true)
58
+ @resource.reload
59
+ end
60
+
61
+ it 'points to original path' do
62
+ expect(@resource.destination_path.to_s).to eq @destination_path
63
+ end
64
+
65
+ it 'responds to :directory?' do
66
+ expect(@resource.destination_path).to respond_to(:directory?)
67
+ end
68
+
69
+ it 'responds to :file?' do
70
+ expect(@resource.destination_path).to respond_to(:file?)
71
+ end
72
+
73
+ it 'responds to :dirname' do
74
+ expect(@resource.destination_path).to respond_to(:dirname)
75
+ end
76
+
77
+ it 'responds to :absolute?' do
78
+ expect(@resource.destination_path).to respond_to(:absolute?)
79
+ end
80
+
81
+ it 'responds to :readable?' do
82
+ expect(@resource.destination_path).to respond_to(:readable?)
83
+ end
84
+
85
+ it 'responds to :size' do
86
+ expect(@resource.destination_path).to respond_to(:size)
87
+ end
88
+ end
89
+ end
90
+
91
+ describe 'with no (nil) source path' do
92
+ before :all do
93
+ @source_path = nil
94
+ @resource = DataMapper::TypesFixtures::SoftwarePackage.new(:source_path => @source_path)
95
+ end
96
+
97
+ describe 'when saved and reloaded' do
98
+ before :all do
99
+ expect(@resource.save).to be(true)
100
+ @resource.reload
101
+ end
102
+
103
+ it 'has nil source path' do
104
+ expect(@resource.source_path).to be_nil
105
+ end
106
+ end
107
+ end
108
+
109
+ describe 'with a blank source path' do
110
+ before :all do
111
+ @source_path = ''
112
+ @resource = DataMapper::TypesFixtures::SoftwarePackage.new(:source_path => @source_path)
113
+ end
114
+
115
+ describe 'when saved and reloaded' do
116
+ before :all do
117
+ expect(@resource.save).to be(true)
118
+ @resource.reload
119
+ end
120
+
121
+ it 'has nil source path' do
122
+ expect(@resource.source_path).to be_nil
123
+ end
124
+ end
125
+ end
126
+
127
+ describe 'with a source path assigned to an empty array' do
128
+ before :all do
129
+ @source_path = []
130
+ @resource = DataMapper::TypesFixtures::SoftwarePackage.new(:source_path => @source_path)
131
+ end
132
+
133
+ describe 'when saved and reloaded' do
134
+ before :all do
135
+ expect(@resource.save).to be(true)
136
+ @resource.reload
137
+ end
138
+
139
+ it 'has nil source path' do
140
+ expect(@resource.source_path).to be_nil
141
+ end
142
+ end
143
+ end
144
+
145
+ describe 'with a source path assigned to a Hash' do
146
+ before :all do
147
+ @source_path = { :guitar => 'Joe Satriani' }
148
+ end
149
+
150
+ describe 'when instantiated' do
151
+ it 'raises an exception' do
152
+ expect do
153
+ DataMapper::TypesFixtures::SoftwarePackage.new(:source_path => @source_path)
154
+ end.to raise_error(TypeError)
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,72 @@
1
+ require_relative '../spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require_relative '../fixtures/tshirt'
6
+
7
+ describe DataMapper::TypesFixtures::TShirt do
8
+ supported_by :all do
9
+ before do
10
+ @resource = DataMapper::TypesFixtures::TShirt.new(
11
+ :writing => 'Fork you',
12
+ :has_picture => true,
13
+ :picture => :octocat,
14
+ :color => :white
15
+ )
16
+ end
17
+
18
+ describe 'with the default value' do
19
+ it 'returns it as an array' do
20
+ expect(@resource.size).to eql(DataMapper::TypesFixtures::TShirt.properties[:size].default)
21
+ end
22
+ end
23
+
24
+ describe 'with multiple sizes' do
25
+ describe 'dumped and loaded' do
26
+ before do
27
+ @resource.size = [ :xs, :medium ]
28
+ expect(@resource.save).to be(true)
29
+ @resource.reload
30
+ end
31
+
32
+ it 'returns size as array' do
33
+ expect(@resource.size).to eq [ :xs, :medium ]
34
+ end
35
+ end
36
+ end
37
+
38
+ describe 'with a single size' do
39
+ before do
40
+ @resource.size = :large
41
+ end
42
+
43
+ describe 'dumped and loaded' do
44
+ before do
45
+ expect(@resource.save).to be(true)
46
+ @resource.reload
47
+ end
48
+
49
+ it 'returns size as array with a single value' do
50
+ expect(@resource.size).to eq [:large]
51
+ end
52
+ end
53
+ end
54
+
55
+ # Flag does not add any auto validations
56
+ describe 'without size' do
57
+ before do
58
+ expect(@resource).to be_valid
59
+ @resource.size = nil
60
+ end
61
+
62
+ it 'is valid' do
63
+ expect(@resource).to be_valid
64
+ end
65
+
66
+ it 'has no errors' do
67
+ expect(@resource.errors).to be_empty
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end