ardm-types 1.2.2

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 (77) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +36 -0
  3. data/.travis.yml +11 -0
  4. data/Gemfile +51 -0
  5. data/LICENSE +20 -0
  6. data/README.rdoc +3 -0
  7. data/Rakefile +4 -0
  8. data/ardm-types.gemspec +29 -0
  9. data/lib/ardm-types.rb +1 -0
  10. data/lib/dm-types/api_key.rb +30 -0
  11. data/lib/dm-types/bcrypt_hash.rb +34 -0
  12. data/lib/dm-types/comma_separated_list.rb +29 -0
  13. data/lib/dm-types/csv.rb +38 -0
  14. data/lib/dm-types/enum.rb +51 -0
  15. data/lib/dm-types/epoch_time.rb +41 -0
  16. data/lib/dm-types/file_path.rb +32 -0
  17. data/lib/dm-types/flag.rb +63 -0
  18. data/lib/dm-types/ip_address.rb +42 -0
  19. data/lib/dm-types/json.rb +50 -0
  20. data/lib/dm-types/paranoid/base.rb +55 -0
  21. data/lib/dm-types/paranoid_boolean.rb +23 -0
  22. data/lib/dm-types/paranoid_datetime.rb +22 -0
  23. data/lib/dm-types/regexp.rb +21 -0
  24. data/lib/dm-types/slug.rb +29 -0
  25. data/lib/dm-types/support/dirty_minder.rb +166 -0
  26. data/lib/dm-types/support/flags.rb +41 -0
  27. data/lib/dm-types/uri.rb +38 -0
  28. data/lib/dm-types/uuid.rb +74 -0
  29. data/lib/dm-types/version.rb +5 -0
  30. data/lib/dm-types/yaml.rb +41 -0
  31. data/lib/dm-types.rb +23 -0
  32. data/spec/fixtures/api_user.rb +14 -0
  33. data/spec/fixtures/article.rb +35 -0
  34. data/spec/fixtures/bookmark.rb +23 -0
  35. data/spec/fixtures/invention.rb +7 -0
  36. data/spec/fixtures/network_node.rb +36 -0
  37. data/spec/fixtures/person.rb +25 -0
  38. data/spec/fixtures/software_package.rb +33 -0
  39. data/spec/fixtures/ticket.rb +21 -0
  40. data/spec/fixtures/tshirt.rb +24 -0
  41. data/spec/integration/api_key_spec.rb +27 -0
  42. data/spec/integration/bcrypt_hash_spec.rb +47 -0
  43. data/spec/integration/comma_separated_list_spec.rb +87 -0
  44. data/spec/integration/dirty_minder_spec.rb +197 -0
  45. data/spec/integration/enum_spec.rb +80 -0
  46. data/spec/integration/epoch_time_spec.rb +61 -0
  47. data/spec/integration/file_path_spec.rb +160 -0
  48. data/spec/integration/flag_spec.rb +72 -0
  49. data/spec/integration/ip_address_spec.rb +153 -0
  50. data/spec/integration/json_spec.rb +72 -0
  51. data/spec/integration/slug_spec.rb +67 -0
  52. data/spec/integration/uri_spec.rb +139 -0
  53. data/spec/integration/uuid_spec.rb +102 -0
  54. data/spec/integration/yaml_spec.rb +69 -0
  55. data/spec/rcov.opts +6 -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.opts +4 -0
  59. data/spec/spec_helper.rb +30 -0
  60. data/spec/unit/bcrypt_hash_spec.rb +155 -0
  61. data/spec/unit/csv_spec.rb +142 -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 +87 -0
  65. data/spec/unit/flag_spec.rb +114 -0
  66. data/spec/unit/ip_address_spec.rb +121 -0
  67. data/spec/unit/json_spec.rb +144 -0
  68. data/spec/unit/paranoid_boolean_spec.rb +150 -0
  69. data/spec/unit/paranoid_datetime_spec.rb +154 -0
  70. data/spec/unit/regexp_spec.rb +63 -0
  71. data/spec/unit/uri_spec.rb +64 -0
  72. data/spec/unit/uuid_spec.rb +25 -0
  73. data/spec/unit/yaml_spec.rb +111 -0
  74. data/tasks/spec.rake +38 -0
  75. data/tasks/yard.rake +9 -0
  76. data/tasks/yardstick.rake +19 -0
  77. metadata +236 -0
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ try_spec do
4
+ require './spec/fixtures/api_user'
5
+
6
+ describe DataMapper::TypesFixtures::APIUser do
7
+ supported_by :all do
8
+ subject { described_class.new(:name => 'alice') }
9
+
10
+ let(:original_api_key) { subject.api_key }
11
+
12
+ it "should have a default value" do
13
+ original_api_key.should_not be_nil
14
+ end
15
+
16
+ it "should preserve the default value" do
17
+ subject.api_key.should == original_api_key
18
+ end
19
+
20
+ it "should generate unique API Keys for each resource" do
21
+ other_resource = described_class.new(:name => 'eve')
22
+
23
+ other_resource.api_key.should_not == original_api_key
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require './spec/fixtures/person'
6
+
7
+ describe DataMapper::TypesFixtures::Person do
8
+ supported_by :all do
9
+ before :all do
10
+ @resource = DataMapper::TypesFixtures::Person.create(:password => 'DataMapper R0cks!')
11
+ DataMapper::TypesFixtures::Person.create(:password => 'password1')
12
+
13
+ @people = DataMapper::TypesFixtures::Person.all
14
+ @resource.reload
15
+ end
16
+
17
+ it 'persists the password on initial save' do
18
+ @resource.password.should == 'DataMapper R0cks!'
19
+ @people.last.password.should == 'password1'
20
+ end
21
+
22
+ it 'recalculates password hash on attribute update' do
23
+ @resource.attribute_set(:password, 'bcryptic obscure')
24
+ @resource.save
25
+
26
+ @resource.reload
27
+ @resource.password.should == 'bcryptic obscure'
28
+ @resource.password.should_not == 'DataMapper R0cks!'
29
+ end
30
+
31
+ it 'does not change password value on reload' do
32
+ resource = @people.last
33
+ original = resource.password.to_s
34
+ resource.reload
35
+ resource.password.to_s.should == original
36
+ end
37
+
38
+ it 'uses cost of BCrypt::Engine::DEFAULT_COST' do
39
+ @resource.password.cost.should == BCrypt::Engine::DEFAULT_COST
40
+ end
41
+
42
+ it 'allows Bcrypt::Password#hash to be an Integer' do
43
+ @resource.password.hash.should be_kind_of(Integer)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require './spec/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
+ @resource.save.should be(true)
21
+ @resource.reload
22
+ end
23
+
24
+ it 'has no interests' do
25
+ @resource.interests.should == 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
+ @resource.save.should be(true)
38
+ @resource.reload
39
+ end
40
+
41
+ it 'has empty interests list' do
42
+ @resource.interests.should == []
43
+ end
44
+ end
45
+ end
46
+
47
+ describe 'with interests information given as a Hash' do
48
+ it 'raises ArgumentError' do
49
+ lambda do
50
+ @resource.interests = { :hash => 'value' }
51
+ @resource.save
52
+ end.should 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
+ @resource.save.should be(true)
65
+ @resource.reload
66
+ end
67
+
68
+ it 'includes "fire" in interests' do
69
+ @resource.interests.should include('fire')
70
+ end
71
+
72
+ it 'includes "water" in interests' do
73
+ @resource.interests.should include('water')
74
+ end
75
+
76
+ it 'includes "a whole lot of other interesting things" in interests' do
77
+ @resource.interests.should include('a whole lot of other interesting things')
78
+ end
79
+
80
+ it 'has blank entries removed' do
81
+ @resource.interests.any? { |i| DataMapper::Ext.blank?(i) }.should be(false)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,197 @@
1
+ require '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 './spec/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
+ @resource.positions['title'].should == 'Layperson'
34
+ end
35
+
36
+ describe "when I change positions" do
37
+ before :all do
38
+ @resource.clean?.should == true
39
+ @resource.positions['title'] = 'Chief Layer of People'
40
+ @resource.save
41
+ @resource.reload
42
+ end
43
+
44
+ it "should remember the new position" do
45
+ @resource.positions['title'].should == '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
+ @resource.clean?.should == true
52
+ @resource.positions['pays_buttloads_of_money'] = true
53
+ @resource.save
54
+ @resource.reload
55
+ end
56
+
57
+ it "should remember the new attribute" do
58
+ @resource.positions['pays_buttloads_of_money'].should be(true)
59
+ end
60
+ end
61
+
62
+ describe "when I change the details of the position" do
63
+ before :all do
64
+ @resource.clean?.should == true
65
+ @resource.positions['details'].merge!('awesome' => "VERY TRUE")
66
+ @resource.save
67
+ @resource.reload
68
+ end
69
+
70
+ it "should remember the changed detail" do
71
+ pending "not supported (YET)" do
72
+ # TODO: Not supported (yet?) -- this is a much harder problem to
73
+ # solve: using mutating accessors of nested objects. We could
74
+ # detect it from #dirty? (using the #hash method), but #dirty?
75
+ # only returns the status of known-mutated properties (not full,
76
+ # on-demand scan of object dirty-ness).
77
+ @resource.positions['details']['awesome'].should == 'VERY TRUE'
78
+ end
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 "should reflect the previously set/persisted value" do
89
+ @resource.positions.should_not be_nil
90
+ @resource.positions['title'].should == '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
+ @resource.positions.first['title'].should == 'Layperson'
107
+ end
108
+
109
+ describe "when I remove the position" do
110
+ before :all do
111
+ @resource.clean?.should == true
112
+ @resource.positions.pop
113
+ @resource.save
114
+ @resource.reload
115
+ end
116
+
117
+ it "should know there aren't any positions" do
118
+ @resource.positions.should == []
119
+ end
120
+ end
121
+
122
+ describe "when I add a new position" do
123
+ before :all do
124
+ @resource.clean?.should == 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 "should know there's two positions" do
135
+ @resource.positions.length.should == 2
136
+ end
137
+
138
+ it "should know which position is which" do
139
+ @resource.positions.first['title'].should == "Layperson"
140
+ @resource.positions.last['title'].should == "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 "should remember the changed detail" do
151
+ pending "not supported (YET)" do
152
+ # TODO: Not supported (yet?) -- this is a much harder problem to
153
+ # solve: using mutating accessors of nested objects. We could
154
+ # detect it from #dirty? (using the #hash method), but #dirty?
155
+ # only returns the status of known-mutated properties (not full,
156
+ # on-demand scan of object dirty-ness).
157
+ @resource.positions.last['details']['high_risk'].should == true
158
+ end
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
+ @resource.clean?.should == true
166
+ @resource.positions.reject! { |_| true }
167
+ @resource.save
168
+ @resource.reload
169
+ end
170
+
171
+ it "should know there aren't any positions" do
172
+ @resource.positions.should == []
173
+ end
174
+ end
175
+
176
+ describe "when I mutate positions through a reference" do
177
+ before :all do
178
+ @resource.clean?.should == true
179
+ @positions = @resource.positions
180
+ @positions << {
181
+ 'company' => "Ooga Booga, Inc",
182
+ 'title' => "Rocker",
183
+ }
184
+ end
185
+
186
+ it "should reflect the change in both the property and the reference" do
187
+ @resource.positions.length.should == 2
188
+ @resource.positions.last['title'].should == 'Rocker'
189
+ @positions.last['title'].should == 'Rocker'
190
+ end
191
+ end
192
+
193
+ end # positions indirectly mutated as an array
194
+
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require './spec/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
+ @resource.save.should be(true)
19
+ @resource.reload
20
+ end
21
+
22
+ it 'preserves property value' do
23
+ @resource.status.should == :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
+ @resource.status.should == :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
+ @resource.save.should be(true)
46
+ end
47
+
48
+ it 'supports queries with equality operator on enumeration property' do
49
+ DataMapper::TypesFixtures::Ticket.all(:status => :confirmed).
50
+ should include(@resource)
51
+ end
52
+
53
+ it 'supports queries with inequality operator on enumeration property' do
54
+ DataMapper::TypesFixtures::Ticket.all(:status.not => :confirmed).
55
+ should_not include(@resource)
56
+ end
57
+ end
58
+
59
+ describe 'with value unknown to enumeration property' do
60
+ before :all do
61
+ @resource = DataMapper::TypesFixtures::Ticket.new(:status => :undecided)
62
+ end
63
+
64
+ # TODO: consider sharing shared spec exampels with dm-validations,
65
+ # which has 'invalid model' shared group
66
+ it 'is invalid (auto validation for :within kicks in)' do
67
+ @resource.should_not be_valid
68
+ end
69
+
70
+ it 'has errors' do
71
+ @resource.errors.should_not be_empty
72
+ end
73
+
74
+ it 'has a meaningful error message on invalid property' do
75
+ @resource.errors.on(:status).should include('Status must be one of unconfirmed, confirmed, assigned, resolved, not_applicable')
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require './spec/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
+ @resource.birthday.should == ::Time.parse('1983-05-03')
21
+ end
22
+ end
23
+
24
+ describe 'when dumped and loaded again' do
25
+ before :all do
26
+ @resource.save.should be(true)
27
+ @resource.reload
28
+ end
29
+
30
+ it 'has a valid birthday' do
31
+ @resource.birthday.should == ::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
+ @resource.birthday.should be_nil
44
+ end
45
+ end
46
+
47
+ describe 'when dumped and loaded again' do
48
+ before :all do
49
+ @resource.save.should be(true)
50
+ @resource.reload
51
+ end
52
+
53
+ it 'has a nil value for birthday' do
54
+ @resource.birthday.should be_nil
55
+ end
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,160 @@
1
+ require 'spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require './spec/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
+ @resource.source_path.to_s.should == @source_path
21
+ end
22
+
23
+ it 'responds to :directory?' do
24
+ @resource.source_path.should respond_to(:directory?)
25
+ end
26
+
27
+ it 'responds to :file?' do
28
+ @resource.source_path.should respond_to(:file?)
29
+ end
30
+
31
+ it 'responds to :dirname' do
32
+ @resource.source_path.should respond_to(:dirname)
33
+ end
34
+
35
+ it 'responds to :absolute?' do
36
+ @resource.source_path.should respond_to(:absolute?)
37
+ end
38
+
39
+ it 'responds to :readable?' do
40
+ @resource.source_path.should respond_to(:readable?)
41
+ end
42
+
43
+ it 'responds to :size' do
44
+ @resource.source_path.should 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
+ @resource.save.should be(true)
58
+ @resource.reload
59
+ end
60
+
61
+ it 'points to original path' do
62
+ @resource.destination_path.to_s.should == @destination_path
63
+ end
64
+
65
+ it 'responds to :directory?' do
66
+ @resource.destination_path.should respond_to(:directory?)
67
+ end
68
+
69
+ it 'responds to :file?' do
70
+ @resource.destination_path.should respond_to(:file?)
71
+ end
72
+
73
+ it 'responds to :dirname' do
74
+ @resource.destination_path.should respond_to(:dirname)
75
+ end
76
+
77
+ it 'responds to :absolute?' do
78
+ @resource.destination_path.should respond_to(:absolute?)
79
+ end
80
+
81
+ it 'responds to :readable?' do
82
+ @resource.destination_path.should respond_to(:readable?)
83
+ end
84
+
85
+ it 'responds to :size' do
86
+ @resource.destination_path.should 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
+ @resource.save.should be(true)
100
+ @resource.reload
101
+ end
102
+
103
+ it 'has nil source path' do
104
+ @resource.source_path.should 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
+ @resource.save.should be(true)
118
+ @resource.reload
119
+ end
120
+
121
+ it 'has nil source path' do
122
+ @resource.source_path.should 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
+ @resource.save.should be(true)
136
+ @resource.reload
137
+ end
138
+
139
+ it 'has nil source path' do
140
+ @resource.source_path.should 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
+ lambda do
153
+ DataMapper::TypesFixtures::SoftwarePackage.new(:source_path => @source_path)
154
+ end.should raise_error(TypeError)
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end