ardm-validations 1.2.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 (153) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/.travis.yml +11 -0
  4. data/Gemfile +51 -0
  5. data/LICENSE +21 -0
  6. data/README.rdoc +122 -0
  7. data/Rakefile +4 -0
  8. data/ardm-validations.gemspec +28 -0
  9. data/lib/ardm-validations.rb +1 -0
  10. data/lib/dm-validations.rb +169 -0
  11. data/lib/dm-validations/auto_validate.rb +252 -0
  12. data/lib/dm-validations/context.rb +66 -0
  13. data/lib/dm-validations/contextual_validators.rb +220 -0
  14. data/lib/dm-validations/exceptions.rb +5 -0
  15. data/lib/dm-validations/formats/email.rb +65 -0
  16. data/lib/dm-validations/formats/url.rb +27 -0
  17. data/lib/dm-validations/support/object.rb +18 -0
  18. data/lib/dm-validations/support/ordered_hash.rb +434 -0
  19. data/lib/dm-validations/validation_errors.rb +137 -0
  20. data/lib/dm-validations/validators/absent_field_validator.rb +58 -0
  21. data/lib/dm-validations/validators/acceptance_validator.rb +79 -0
  22. data/lib/dm-validations/validators/block_validator.rb +61 -0
  23. data/lib/dm-validations/validators/confirmation_validator.rb +92 -0
  24. data/lib/dm-validations/validators/format_validator.rb +124 -0
  25. data/lib/dm-validations/validators/generic_validator.rb +184 -0
  26. data/lib/dm-validations/validators/length_validator.rb +249 -0
  27. data/lib/dm-validations/validators/method_validator.rb +64 -0
  28. data/lib/dm-validations/validators/numeric_validator.rb +182 -0
  29. data/lib/dm-validations/validators/primitive_validator.rb +58 -0
  30. data/lib/dm-validations/validators/required_field_validator.rb +83 -0
  31. data/lib/dm-validations/validators/uniqueness_validator.rb +67 -0
  32. data/lib/dm-validations/validators/within_validator.rb +74 -0
  33. data/lib/dm-validations/version.rb +5 -0
  34. data/spec/fixtures/barcode.rb +40 -0
  35. data/spec/fixtures/basketball_court.rb +58 -0
  36. data/spec/fixtures/basketball_player.rb +34 -0
  37. data/spec/fixtures/beta_tester_account.rb +33 -0
  38. data/spec/fixtures/bill_of_landing.rb +47 -0
  39. data/spec/fixtures/boat_dock.rb +26 -0
  40. data/spec/fixtures/city.rb +24 -0
  41. data/spec/fixtures/company.rb +93 -0
  42. data/spec/fixtures/corporate_world.rb +39 -0
  43. data/spec/fixtures/country.rb +24 -0
  44. data/spec/fixtures/ethernet_frame.rb +56 -0
  45. data/spec/fixtures/event.rb +44 -0
  46. data/spec/fixtures/g3_concert.rb +57 -0
  47. data/spec/fixtures/jabberwock.rb +27 -0
  48. data/spec/fixtures/kayak.rb +28 -0
  49. data/spec/fixtures/lernean_hydra.rb +39 -0
  50. data/spec/fixtures/llama_spaceship.rb +15 -0
  51. data/spec/fixtures/mathematical_function.rb +34 -0
  52. data/spec/fixtures/memory_object.rb +30 -0
  53. data/spec/fixtures/mittelschnauzer.rb +39 -0
  54. data/spec/fixtures/motor_launch.rb +21 -0
  55. data/spec/fixtures/multibyte.rb +16 -0
  56. data/spec/fixtures/page.rb +32 -0
  57. data/spec/fixtures/phone_number.rb +28 -0
  58. data/spec/fixtures/pirogue.rb +28 -0
  59. data/spec/fixtures/programming_language.rb +83 -0
  60. data/spec/fixtures/reservation.rb +38 -0
  61. data/spec/fixtures/scm_operation.rb +56 -0
  62. data/spec/fixtures/sms_message.rb +22 -0
  63. data/spec/fixtures/udp_packet.rb +49 -0
  64. data/spec/integration/absent_field_validator/absent_field_validator_spec.rb +90 -0
  65. data/spec/integration/absent_field_validator/spec_helper.rb +7 -0
  66. data/spec/integration/acceptance_validator/acceptance_validator_spec.rb +196 -0
  67. data/spec/integration/acceptance_validator/spec_helper.rb +7 -0
  68. data/spec/integration/automatic_validation/custom_messages_for_inferred_validation_spec.rb +57 -0
  69. data/spec/integration/automatic_validation/disabling_inferred_validation_spec.rb +49 -0
  70. data/spec/integration/automatic_validation/inferred_boolean_properties_validation_spec.rb +100 -0
  71. data/spec/integration/automatic_validation/inferred_float_property_validation_spec.rb +45 -0
  72. data/spec/integration/automatic_validation/inferred_format_validation_spec.rb +35 -0
  73. data/spec/integration/automatic_validation/inferred_integer_properties_validation_spec.rb +70 -0
  74. data/spec/integration/automatic_validation/inferred_length_validation_spec.rb +142 -0
  75. data/spec/integration/automatic_validation/inferred_presence_validation_spec.rb +45 -0
  76. data/spec/integration/automatic_validation/inferred_primitive_validation_spec.rb +22 -0
  77. data/spec/integration/automatic_validation/inferred_uniqueness_validation_spec.rb +52 -0
  78. data/spec/integration/automatic_validation/inferred_within_validation_spec.rb +39 -0
  79. data/spec/integration/automatic_validation/spec_helper.rb +57 -0
  80. data/spec/integration/block_validator/block_validator_spec.rb +32 -0
  81. data/spec/integration/block_validator/spec_helper.rb +5 -0
  82. data/spec/integration/conditional_validation/if_condition_spec.rb +63 -0
  83. data/spec/integration/conditional_validation/spec_helper.rb +5 -0
  84. data/spec/integration/confirmation_validator/confirmation_validator_spec.rb +76 -0
  85. data/spec/integration/confirmation_validator/spec_helper.rb +5 -0
  86. data/spec/integration/datamapper_models/association_validation_spec.rb +29 -0
  87. data/spec/integration/datamapper_models/inheritance_spec.rb +82 -0
  88. data/spec/integration/dirty_attributes/dirty_attributes_spec.rb +13 -0
  89. data/spec/integration/duplicated_validations/duplicated_validations_spec.rb +24 -0
  90. data/spec/integration/duplicated_validations/spec_helper.rb +5 -0
  91. data/spec/integration/format_validator/email_format_validator_spec.rb +139 -0
  92. data/spec/integration/format_validator/format_validator_spec.rb +64 -0
  93. data/spec/integration/format_validator/regexp_validator_spec.rb +33 -0
  94. data/spec/integration/format_validator/spec_helper.rb +5 -0
  95. data/spec/integration/format_validator/url_format_validator_spec.rb +93 -0
  96. data/spec/integration/length_validator/default_value_spec.rb +14 -0
  97. data/spec/integration/length_validator/equality_spec.rb +87 -0
  98. data/spec/integration/length_validator/error_message_spec.rb +22 -0
  99. data/spec/integration/length_validator/maximum_spec.rb +49 -0
  100. data/spec/integration/length_validator/minimum_spec.rb +54 -0
  101. data/spec/integration/length_validator/range_spec.rb +87 -0
  102. data/spec/integration/length_validator/spec_helper.rb +7 -0
  103. data/spec/integration/method_validator/method_validator_spec.rb +241 -0
  104. data/spec/integration/method_validator/spec_helper.rb +5 -0
  105. data/spec/integration/numeric_validator/equality_with_float_type_spec.rb +65 -0
  106. data/spec/integration/numeric_validator/equality_with_integer_type_spec.rb +41 -0
  107. data/spec/integration/numeric_validator/float_type_spec.rb +90 -0
  108. data/spec/integration/numeric_validator/gt_with_float_type_spec.rb +37 -0
  109. data/spec/integration/numeric_validator/gte_with_float_type_spec.rb +37 -0
  110. data/spec/integration/numeric_validator/integer_only_true_spec.rb +91 -0
  111. data/spec/integration/numeric_validator/integer_type_spec.rb +86 -0
  112. data/spec/integration/numeric_validator/lt_with_float_type_spec.rb +37 -0
  113. data/spec/integration/numeric_validator/lte_with_float_type_spec.rb +37 -0
  114. data/spec/integration/numeric_validator/spec_helper.rb +5 -0
  115. data/spec/integration/primitive_validator/primitive_validator_spec.rb +92 -0
  116. data/spec/integration/primitive_validator/spec_helper.rb +5 -0
  117. data/spec/integration/pure_ruby_objects/plain_old_ruby_object_validation_spec.rb +118 -0
  118. data/spec/integration/required_field_validator/association_spec.rb +72 -0
  119. data/spec/integration/required_field_validator/boolean_type_value_spec.rb +155 -0
  120. data/spec/integration/required_field_validator/date_type_value_spec.rb +127 -0
  121. data/spec/integration/required_field_validator/datetime_type_value_spec.rb +127 -0
  122. data/spec/integration/required_field_validator/float_type_value_spec.rb +131 -0
  123. data/spec/integration/required_field_validator/integer_type_value_spec.rb +99 -0
  124. data/spec/integration/required_field_validator/plain_old_ruby_object_spec.rb +35 -0
  125. data/spec/integration/required_field_validator/shared_examples.rb +26 -0
  126. data/spec/integration/required_field_validator/spec_helper.rb +7 -0
  127. data/spec/integration/required_field_validator/string_type_value_spec.rb +167 -0
  128. data/spec/integration/required_field_validator/text_type_value_spec.rb +49 -0
  129. data/spec/integration/shared/default_validation_context.rb +13 -0
  130. data/spec/integration/shared/valid_and_invalid_model.rb +35 -0
  131. data/spec/integration/uniqueness_validator/spec_helper.rb +5 -0
  132. data/spec/integration/uniqueness_validator/uniqueness_validator_spec.rb +116 -0
  133. data/spec/integration/within_validator/spec_helper.rb +5 -0
  134. data/spec/integration/within_validator/within_validator_spec.rb +168 -0
  135. data/spec/public/resource_spec.rb +105 -0
  136. data/spec/rcov.opts +6 -0
  137. data/spec/spec.opts +4 -0
  138. data/spec/spec_helper.rb +29 -0
  139. data/spec/unit/contextual_validators/emptiness_spec.rb +50 -0
  140. data/spec/unit/contextual_validators/execution_spec.rb +48 -0
  141. data/spec/unit/contextual_validators/spec_helper.rb +37 -0
  142. data/spec/unit/generic_validator/equality_operator_spec.rb +26 -0
  143. data/spec/unit/generic_validator/optional_spec.rb +54 -0
  144. data/spec/unit/validation_errors/adding_spec.rb +54 -0
  145. data/spec/unit/validation_errors/emptiness_spec.rb +38 -0
  146. data/spec/unit/validation_errors/enumerable_spec.rb +32 -0
  147. data/spec/unit/validation_errors/reading_spec.rb +35 -0
  148. data/spec/unit/validation_errors/respond_to_spec.rb +15 -0
  149. data/spec/unit/validators/within_validator_spec.rb +23 -0
  150. data/tasks/spec.rake +38 -0
  151. data/tasks/yard.rake +9 -0
  152. data/tasks/yardstick.rake +19 -0
  153. metadata +256 -0
@@ -0,0 +1,5 @@
1
+ # make sure you check out spec/fixtures to see fixture models
2
+ # already written
3
+ #
4
+ # DataMapper developers feels strongly against foobars in the spec
5
+ # suite
@@ -0,0 +1,168 @@
1
+ require 'spec_helper'
2
+ require 'integration/within_validator/spec_helper'
3
+
4
+ describe 'DataMapper::Validations::Fixtures::PhoneNumber' do
5
+ before :all do
6
+ DataMapper::Validations::Fixtures::PhoneNumber.auto_migrate!
7
+
8
+ @model = DataMapper::Validations::Fixtures::PhoneNumber.new(:type_of_number => 'cell')
9
+ @model.should be_valid
10
+ end
11
+
12
+ describe "with type of number set to 'home'" do
13
+ before :all do
14
+ @model.type_of_number = 'home'
15
+ end
16
+
17
+ it_should_behave_like "valid model"
18
+ end
19
+
20
+
21
+ describe "with type of number set to 'cell'" do
22
+ before :all do
23
+ @model.type_of_number = 'cell'
24
+ end
25
+
26
+ it_should_behave_like "valid model"
27
+ end
28
+
29
+
30
+ describe "with type of number set to 'work'" do
31
+ before :all do
32
+ @model.type_of_number = 'home'
33
+ end
34
+
35
+ it_should_behave_like "valid model"
36
+ end
37
+
38
+
39
+ describe "with type of number set to 'fax'" do
40
+ before :all do
41
+ @model.type_of_number = 'fax'
42
+ end
43
+
44
+ it_should_behave_like "invalid model"
45
+
46
+ it "has meaningful error message on invalid property" do
47
+ @model.errors.on(:type_of_number).should == [ 'Should be one of: home, cell or work' ]
48
+ end
49
+ end
50
+ end
51
+
52
+
53
+
54
+ describe 'DataMapper::Validations::Fixtures::MathematicalFunction' do
55
+ before :all do
56
+ DataMapper::Validations::Fixtures::MathematicalFunction.auto_migrate!
57
+
58
+ @model = DataMapper::Validations::Fixtures::MathematicalFunction.new(:input => 2, :output => -2)
59
+ @model.should be_valid
60
+ end
61
+
62
+ describe "with input = 0" do
63
+ before :all do
64
+ @model.input = 0
65
+ end
66
+
67
+ it_should_behave_like "invalid model"
68
+
69
+ it "notices 'greater than or equal to 1' in the error message" do
70
+ @model.errors.on(:input).should == [ 'Input must be greater than or equal to 1' ]
71
+ end
72
+ end
73
+
74
+ describe "with input = -10" do
75
+ before :all do
76
+ @model.input = -10
77
+ end
78
+
79
+ it_should_behave_like "invalid model"
80
+
81
+ it "notices 'greater than or equal to 1' in the error message" do
82
+ @model.errors.on(:input).should == [ 'Input must be greater than or equal to 1' ]
83
+ end
84
+ end
85
+
86
+ describe "with input = -Infinity" do
87
+ before :all do
88
+ @model.input = -(1.0/0)
89
+ end
90
+
91
+ it_should_behave_like "invalid model"
92
+
93
+ it "notices 'greater than or equal to 1' in the error message" do
94
+ @model.errors.on(:input).should == [ 'Input must be greater than or equal to 1' ]
95
+ end
96
+ end
97
+
98
+ describe "with input = 10" do
99
+ before :all do
100
+ @model.input = 10
101
+ end
102
+
103
+ it_should_behave_like "valid model"
104
+ end
105
+
106
+
107
+ describe "with input = Infinity" do
108
+ before :all do
109
+ @model.input = (1.0/0)
110
+ end
111
+
112
+ it_should_behave_like "valid model"
113
+ end
114
+
115
+
116
+ #
117
+ # Function range
118
+ #
119
+
120
+ describe "with output = 0" do
121
+ before :all do
122
+ @model.output = 0
123
+ end
124
+
125
+ it_should_behave_like "valid model"
126
+ end
127
+
128
+ describe "with output = -10" do
129
+ before :all do
130
+ @model.output = -10
131
+ end
132
+
133
+ it_should_behave_like "valid model"
134
+ end
135
+
136
+ describe "with output = -Infinity" do
137
+ before :all do
138
+ @model.output = -(1.0/0)
139
+ end
140
+
141
+ it_should_behave_like "valid model"
142
+ end
143
+
144
+ describe "with output = 10" do
145
+ before :all do
146
+ @model.output = 10
147
+ end
148
+
149
+ it_should_behave_like "invalid model"
150
+
151
+ it "uses overriden error message" do
152
+ @model.errors.on(:output).should == [ 'Negative values or zero only, please' ]
153
+ end
154
+ end
155
+
156
+
157
+ describe "with output = Infinity" do
158
+ before :all do
159
+ @model.output = (1.0/0)
160
+ end
161
+
162
+ it_should_behave_like "invalid model"
163
+
164
+ it "uses overriden error message" do
165
+ @model.errors.on(:output).should == [ 'Negative values or zero only, please' ]
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'DataMapper::Resource' do
4
+ before :all do
5
+ DataMapper::Validations::Fixtures::Barcode.destroy!
6
+
7
+ @resource = DataMapper::Validations::Fixtures::Barcode.new
8
+ end
9
+
10
+ describe '#update' do
11
+ describe 'when provided valid attributes' do
12
+ before :all do
13
+ @response = @resource.update(:code => 'a' * 10)
14
+ end
15
+
16
+ it 'should return true' do
17
+ @response.should be(true)
18
+ end
19
+ end
20
+
21
+ describe 'when provided invalid attributes' do
22
+ before :all do
23
+ @response = @resource.update(:code => 'a' * 11)
24
+ end
25
+
26
+ it 'should return false' do
27
+ @response.should be(false)
28
+ end
29
+
30
+ it 'should set errors' do
31
+ @resource.errors.to_a.should == [ [ 'Code must be at most 10 characters long' ] ]
32
+ end
33
+ end
34
+
35
+ describe 'when provided invalid attributes and a context' do
36
+ before :all do
37
+ DataMapper::Validations::Fixtures::Organisation.destroy!
38
+ DataMapper::Validations::Fixtures::Department.destroy!
39
+ DataMapper::Validations::Fixtures::User.destroy!
40
+
41
+ organization = DataMapper::Validations::Fixtures::Organisation.create(:name => 'Org 101', :domain => '101')
42
+ dept = DataMapper::Validations::Fixtures::Department.create(:name => 'accounting')
43
+
44
+ attributes = {
45
+ :organisation => organization,
46
+ :user_name => 'guy',
47
+ :department => dept,
48
+ }
49
+
50
+ # create a record that will be a dupe when User#update is executed below
51
+ DataMapper::Validations::Fixtures::User.create(attributes).should be_saved
52
+
53
+ @resource = DataMapper::Validations::Fixtures::User.create(attributes.merge(:user_name => 'other'))
54
+
55
+ @response = @resource.update(attributes, :signing_up_for_department_account)
56
+ end
57
+
58
+ it 'should return false' do
59
+ @response.should be(false)
60
+ end
61
+
62
+ it 'should set errors' do
63
+ @resource.errors.to_a.should == [ [ 'User name is already taken' ] ]
64
+ end
65
+ end
66
+ end
67
+
68
+ describe '#save' do
69
+ before :all do
70
+ @resource.code = 'a' * 10
71
+ @resource.save
72
+ end
73
+
74
+ describe 'on a new resource' do
75
+ it 'should call valid? once' do
76
+ @resource.valid_hook_call_count.should == 1
77
+ end
78
+ end
79
+
80
+ describe 'on a saved, non-dirty resource' do
81
+ before :all do
82
+ # reload the resource
83
+ @resource = @resource.model.get(*@resource.key)
84
+ @resource.save
85
+ end
86
+
87
+ it 'should call valid?' do
88
+ @resource.valid_hook_call_count.should == 1
89
+ end
90
+ end
91
+
92
+ describe 'on a saved, dirty resource' do
93
+ before :all do
94
+ # reload the resource
95
+ @resource = @resource.model.get(*@resource.key)
96
+ @resource.code = 'b' * 10
97
+ @resource.save
98
+ end
99
+
100
+ it 'should call valid? once' do
101
+ @resource.valid_hook_call_count.should == 1
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,6 @@
1
+ --exclude "spec,^/"
2
+ --sort coverage
3
+ --callsites
4
+ --xrefs
5
+ --profile
6
+ --text-summary
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --loadby random
3
+ --format profile
4
+ --backtrace
@@ -0,0 +1,29 @@
1
+ require 'dm-core/spec/setup'
2
+ require 'dm-core/spec/lib/adapter_helpers'
3
+
4
+ require 'dm-validations'
5
+ require 'dm-types'
6
+ require 'dm-migrations'
7
+
8
+ class Hash
9
+ def except(*keys)
10
+ hash = dup
11
+ keys.each { |key| hash.delete(key) }
12
+ hash
13
+ end
14
+ end
15
+
16
+ SPEC_ROOT = Pathname(__FILE__).dirname
17
+ Pathname.glob((SPEC_ROOT + 'fixtures/**/*.rb').to_s).each { |file| require file }
18
+ Pathname.glob((SPEC_ROOT + 'integration/shared/**/*.rb').to_s).each { |file| require file }
19
+
20
+ DataMapper::Spec.setup
21
+ DataMapper.finalize
22
+
23
+ Spec::Runner.configure do |config|
24
+ config.extend(DataMapper::Spec::Adapters::Helpers)
25
+
26
+ config.before :suite do
27
+ DataMapper.finalize.auto_migrate!
28
+ end
29
+ end
@@ -0,0 +1,50 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'unit/contextual_validators/spec_helper'
4
+
5
+ describe 'DataMapper::Validations::ContextualValidators' do
6
+ before :all do
7
+ @validators = DataMapper::Validations::ContextualValidators.new
8
+ end
9
+
10
+ describe "initially" do
11
+ it "is empty" do
12
+ @validators.should be_empty
13
+ end
14
+ end
15
+
16
+
17
+ describe "after first reference to context" do
18
+ before :all do
19
+ @validators.context(:create)
20
+ end
21
+
22
+ it "initializes list of validators for referred context" do
23
+ @validators.context(:create).should be_empty
24
+ end
25
+ end
26
+
27
+
28
+ describe "after a context being added" do
29
+ before :all do
30
+ @validators.context(:default) << DataMapper::Validations::PresenceValidator.new(:toc, :when => [:publishing])
31
+ end
32
+
33
+ it "is no longer empty" do
34
+ @validators.should_not be_empty
35
+ end
36
+ end
37
+
38
+
39
+ describe "when cleared" do
40
+ before :all do
41
+ @validators.context(:default) << DataMapper::Validations::PresenceValidator.new(:toc, :when => [:publishing])
42
+ @validators.should_not be_empty
43
+ @validators.clear!
44
+ end
45
+
46
+ it "becomes empty again" do
47
+ @validators.should be_empty
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,48 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'unit/contextual_validators/spec_helper'
4
+
5
+ describe 'DataMapper::Validations::ContextualValidators' do
6
+ before :all do
7
+ @validators = DataMapper::Validations::ContextualValidators.new
8
+ end
9
+
10
+ describe "#execute(name, target)" do
11
+ before do
12
+ @validator_one = DataMapper::Validations::PresenceValidator.new(:name)
13
+ @validator_two = DataMapper::Validations::WithinValidator.new(:operating_system, :set => ["Mac OS X", "Linux", "FreeBSD", "Solaris"])
14
+
15
+ @validators.context(:default) << @validator_one << @validator_two
16
+ end
17
+
18
+
19
+ describe "when target satisfies all validators" do
20
+ before do
21
+ @target = DataMapper::Validations::Fixtures::PieceOfSoftware.new(:name => 'gcc', :operating_system => "Mac OS X")
22
+ @validator_one.call(@target).should be(true)
23
+ @validator_two.call(@target).should be(true)
24
+
25
+ @result = @validators.execute(:default, @target)
26
+ end
27
+
28
+ it "returns true" do
29
+ @result.should be(true)
30
+ end
31
+ end
32
+
33
+
34
+ describe "when target does not satisfy all validators" do
35
+ before do
36
+ @target = DataMapper::Validations::Fixtures::PieceOfSoftware.new(:name => 'Skitch', :operating_system => "Haiku")
37
+ @validator_one.call(@target).should be(true)
38
+ @validator_two.call(@target).should be(false)
39
+
40
+ @result = @validators.execute(:default, @target)
41
+ end
42
+
43
+ it "returns true" do
44
+ @result.should be(false)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,37 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module DataMapper
4
+ module Validations
5
+ module Fixtures
6
+
7
+ class PieceOfSoftware
8
+ #
9
+ # Behaviors
10
+ #
11
+
12
+ include DataMapper::Validations
13
+
14
+ #
15
+ # Attributes
16
+ #
17
+
18
+ attr_accessor :name, :operating_system
19
+
20
+ #
21
+ # Validations
22
+ #
23
+
24
+ #
25
+ # API
26
+ #
27
+
28
+ def initialize(attributes = {})
29
+ attributes.each do |key, value|
30
+ self.send("#{key}=", value)
31
+ end
32
+ end
33
+ end
34
+
35
+ end # Fixtures
36
+ end # Validations
37
+ end # DataMapper