ardm 0.0.1

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 (179) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +35 -0
  3. data/Gemfile +13 -0
  4. data/LICENSE +21 -0
  5. data/README.md +70 -0
  6. data/Rakefile +4 -0
  7. data/ardm.gemspec +29 -0
  8. data/db/.gitignore +1 -0
  9. data/lib/ardm/active_record/associations.rb +80 -0
  10. data/lib/ardm/active_record/base.rb +49 -0
  11. data/lib/ardm/active_record/dirty.rb +25 -0
  12. data/lib/ardm/active_record/hooks.rb +31 -0
  13. data/lib/ardm/active_record/inheritance.rb +37 -0
  14. data/lib/ardm/active_record/is/state_machine.rb +21 -0
  15. data/lib/ardm/active_record/is.rb +22 -0
  16. data/lib/ardm/active_record/not_found.rb +7 -0
  17. data/lib/ardm/active_record/predicate_builder/array_handler.rb +31 -0
  18. data/lib/ardm/active_record/predicate_builder/rails3.rb +147 -0
  19. data/lib/ardm/active_record/predicate_builder/rails4.rb +139 -0
  20. data/lib/ardm/active_record/predicate_builder/relation_handler.rb +15 -0
  21. data/lib/ardm/active_record/predicate_builder.rb +19 -0
  22. data/lib/ardm/active_record/property.rb +357 -0
  23. data/lib/ardm/active_record/query.rb +108 -0
  24. data/lib/ardm/active_record/record.rb +70 -0
  25. data/lib/ardm/active_record/relation.rb +83 -0
  26. data/lib/ardm/active_record/repository.rb +38 -0
  27. data/lib/ardm/active_record/serialization.rb +164 -0
  28. data/lib/ardm/active_record/storage_names.rb +28 -0
  29. data/lib/ardm/active_record/validations.rb +111 -0
  30. data/lib/ardm/active_record.rb +43 -0
  31. data/lib/ardm/data_mapper/not_found.rb +5 -0
  32. data/lib/ardm/data_mapper/record.rb +41 -0
  33. data/lib/ardm/data_mapper.rb +5 -0
  34. data/lib/ardm/env.rb +5 -0
  35. data/lib/ardm/property/api_key.rb +30 -0
  36. data/lib/ardm/property/bcrypt_hash.rb +31 -0
  37. data/lib/ardm/property/binary.rb +23 -0
  38. data/lib/ardm/property/boolean.rb +29 -0
  39. data/lib/ardm/property/class.rb +19 -0
  40. data/lib/ardm/property/comma_separated_list.rb +28 -0
  41. data/lib/ardm/property/csv.rb +35 -0
  42. data/lib/ardm/property/date.rb +12 -0
  43. data/lib/ardm/property/datetime.rb +12 -0
  44. data/lib/ardm/property/decimal.rb +38 -0
  45. data/lib/ardm/property/discriminator.rb +65 -0
  46. data/lib/ardm/property/enum.rb +51 -0
  47. data/lib/ardm/property/epoch_time.rb +38 -0
  48. data/lib/ardm/property/file_path.rb +25 -0
  49. data/lib/ardm/property/flag.rb +65 -0
  50. data/lib/ardm/property/float.rb +18 -0
  51. data/lib/ardm/property/integer.rb +24 -0
  52. data/lib/ardm/property/invalid_value_error.rb +22 -0
  53. data/lib/ardm/property/ip_address.rb +35 -0
  54. data/lib/ardm/property/json.rb +49 -0
  55. data/lib/ardm/property/lookup.rb +29 -0
  56. data/lib/ardm/property/numeric.rb +40 -0
  57. data/lib/ardm/property/object.rb +36 -0
  58. data/lib/ardm/property/paranoid_boolean.rb +18 -0
  59. data/lib/ardm/property/paranoid_datetime.rb +17 -0
  60. data/lib/ardm/property/regexp.rb +22 -0
  61. data/lib/ardm/property/serial.rb +16 -0
  62. data/lib/ardm/property/slug.rb +29 -0
  63. data/lib/ardm/property/string.rb +40 -0
  64. data/lib/ardm/property/support/dirty_minder.rb +169 -0
  65. data/lib/ardm/property/support/flags.rb +41 -0
  66. data/lib/ardm/property/support/paranoid_base.rb +78 -0
  67. data/lib/ardm/property/text.rb +11 -0
  68. data/lib/ardm/property/time.rb +12 -0
  69. data/lib/ardm/property/uri.rb +27 -0
  70. data/lib/ardm/property/uuid.rb +65 -0
  71. data/lib/ardm/property/validation.rb +208 -0
  72. data/lib/ardm/property/yaml.rb +38 -0
  73. data/lib/ardm/property.rb +891 -0
  74. data/lib/ardm/property_set.rb +152 -0
  75. data/lib/ardm/query/expression.rb +85 -0
  76. data/lib/ardm/query/ext/symbol.rb +37 -0
  77. data/lib/ardm/query/operator.rb +64 -0
  78. data/lib/ardm/record.rb +1 -0
  79. data/lib/ardm/support/assertions.rb +8 -0
  80. data/lib/ardm/support/deprecate.rb +12 -0
  81. data/lib/ardm/support/descendant_set.rb +89 -0
  82. data/lib/ardm/support/equalizer.rb +48 -0
  83. data/lib/ardm/support/ext/array.rb +22 -0
  84. data/lib/ardm/support/ext/blank.rb +25 -0
  85. data/lib/ardm/support/ext/hash.rb +67 -0
  86. data/lib/ardm/support/ext/module.rb +47 -0
  87. data/lib/ardm/support/ext/object.rb +57 -0
  88. data/lib/ardm/support/ext/string.rb +24 -0
  89. data/lib/ardm/support/ext/try_dup.rb +12 -0
  90. data/lib/ardm/support/hook.rb +405 -0
  91. data/lib/ardm/support/lazy_array.rb +451 -0
  92. data/lib/ardm/support/local_object_space.rb +13 -0
  93. data/lib/ardm/support/logger.rb +201 -0
  94. data/lib/ardm/support/mash.rb +176 -0
  95. data/lib/ardm/support/naming_conventions.rb +90 -0
  96. data/lib/ardm/support/ordered_set.rb +380 -0
  97. data/lib/ardm/support/subject.rb +33 -0
  98. data/lib/ardm/support/subject_set.rb +250 -0
  99. data/lib/ardm/version.rb +3 -0
  100. data/lib/ardm.rb +56 -0
  101. data/spec/fixtures/api_user.rb +11 -0
  102. data/spec/fixtures/article.rb +22 -0
  103. data/spec/fixtures/bookmark.rb +14 -0
  104. data/spec/fixtures/invention.rb +5 -0
  105. data/spec/fixtures/network_node.rb +23 -0
  106. data/spec/fixtures/person.rb +17 -0
  107. data/spec/fixtures/software_package.rb +22 -0
  108. data/spec/fixtures/ticket.rb +12 -0
  109. data/spec/fixtures/tshirt.rb +15 -0
  110. data/spec/integration/api_key_spec.rb +25 -0
  111. data/spec/integration/bcrypt_hash_spec.rb +45 -0
  112. data/spec/integration/comma_separated_list_spec.rb +85 -0
  113. data/spec/integration/dirty_minder_spec.rb +197 -0
  114. data/spec/integration/enum_spec.rb +79 -0
  115. data/spec/integration/epoch_time_spec.rb +59 -0
  116. data/spec/integration/file_path_spec.rb +158 -0
  117. data/spec/integration/flag_spec.rb +72 -0
  118. data/spec/integration/ip_address_spec.rb +151 -0
  119. data/spec/integration/json_spec.rb +70 -0
  120. data/spec/integration/slug_spec.rb +65 -0
  121. data/spec/integration/uri_spec.rb +136 -0
  122. data/spec/integration/uuid_spec.rb +102 -0
  123. data/spec/integration/yaml_spec.rb +85 -0
  124. data/spec/public/property/binary_spec.rb +41 -0
  125. data/spec/public/property/boolean_spec.rb +30 -0
  126. data/spec/public/property/class_spec.rb +28 -0
  127. data/spec/public/property/date_spec.rb +22 -0
  128. data/spec/public/property/date_time_spec.rb +22 -0
  129. data/spec/public/property/decimal_spec.rb +23 -0
  130. data/spec/public/property/discriminator_spec.rb +133 -0
  131. data/spec/public/property/float_spec.rb +22 -0
  132. data/spec/public/property/integer_spec.rb +22 -0
  133. data/spec/public/property/object_spec.rb +103 -0
  134. data/spec/public/property/serial_spec.rb +22 -0
  135. data/spec/public/property/string_spec.rb +22 -0
  136. data/spec/public/property/text_spec.rb +23 -0
  137. data/spec/public/property/time_spec.rb +22 -0
  138. data/spec/public/property_spec.rb +316 -0
  139. data/spec/rcov.opts +6 -0
  140. data/spec/schema.rb +86 -0
  141. data/spec/semipublic/property/binary_spec.rb +14 -0
  142. data/spec/semipublic/property/boolean_spec.rb +48 -0
  143. data/spec/semipublic/property/class_spec.rb +36 -0
  144. data/spec/semipublic/property/date_spec.rb +44 -0
  145. data/spec/semipublic/property/date_time_spec.rb +47 -0
  146. data/spec/semipublic/property/decimal_spec.rb +83 -0
  147. data/spec/semipublic/property/discriminator_spec.rb +22 -0
  148. data/spec/semipublic/property/float_spec.rb +83 -0
  149. data/spec/semipublic/property/integer_spec.rb +83 -0
  150. data/spec/semipublic/property/lookup_spec.rb +27 -0
  151. data/spec/semipublic/property/serial_spec.rb +14 -0
  152. data/spec/semipublic/property/string_spec.rb +14 -0
  153. data/spec/semipublic/property/text_spec.rb +30 -0
  154. data/spec/semipublic/property/time_spec.rb +49 -0
  155. data/spec/semipublic/property_spec.rb +51 -0
  156. data/spec/shared/flags_shared_spec.rb +36 -0
  157. data/spec/shared/identity_function_group.rb +5 -0
  158. data/spec/shared/public_property_spec.rb +229 -0
  159. data/spec/shared/semipublic_property_spec.rb +159 -0
  160. data/spec/spec.opts +4 -0
  161. data/spec/spec_helper.rb +58 -0
  162. data/spec/unit/bcrypt_hash_spec.rb +154 -0
  163. data/spec/unit/csv_spec.rb +139 -0
  164. data/spec/unit/dirty_minder_spec.rb +64 -0
  165. data/spec/unit/enum_spec.rb +125 -0
  166. data/spec/unit/epoch_time_spec.rb +72 -0
  167. data/spec/unit/file_path_spec.rb +75 -0
  168. data/spec/unit/flag_spec.rb +114 -0
  169. data/spec/unit/ip_address_spec.rb +109 -0
  170. data/spec/unit/json_spec.rb +127 -0
  171. data/spec/unit/paranoid_boolean_spec.rb +142 -0
  172. data/spec/unit/paranoid_datetime_spec.rb +149 -0
  173. data/spec/unit/regexp_spec.rb +62 -0
  174. data/spec/unit/uri_spec.rb +64 -0
  175. data/spec/unit/yaml_spec.rb +111 -0
  176. data/tasks/spec.rake +40 -0
  177. data/tasks/yard.rake +9 -0
  178. data/tasks/yardstick.rake +19 -0
  179. metadata +350 -0
@@ -0,0 +1,250 @@
1
+ module Ardm
2
+
3
+ # An insertion ordered set of named objects
4
+ #
5
+ # {SubjectSet} uses {Ardm::OrderedSet}
6
+ # under the hood to keep track of a set of
7
+ # entries. In Ardm code, a subject
8
+ # can be either a {Ardm::Property}, or
9
+ # a {Ardm::Associations::Relationship}.
10
+ #
11
+ # All entries added to instances of this
12
+ # class must respond to the {#name} method
13
+ #
14
+ # The motivation behind this is that we
15
+ # use this class as a base to keep track
16
+ # properties and relationships.
17
+ # The following constraints apply for these
18
+ # types of objects: {Property} names must be
19
+ # unique within any model.
20
+ # {Associations::Relationship} names must be
21
+ # unique within any model
22
+ #
23
+ # When adding an entry with a name that
24
+ # already exists, the already existing
25
+ # entry will be replaced with the new
26
+ # entry with the same name. This is because
27
+ # we want to be able to update properties,
28
+ # and relationship during the course of
29
+ # initializing our application.
30
+ #
31
+ # This also happens to be consistent with
32
+ # the way ruby handles redefining methods,
33
+ # where the last definitions "wins".
34
+ #
35
+ # Furthermore, the builtin ruby {Set#<<} method
36
+ # also updates the old object if a new object
37
+ # gets added.
38
+ #
39
+ # @api private
40
+ class SubjectSet
41
+
42
+ # An {OrderedSet::Cache::API} implementation that establishes
43
+ # set semantics based on the name of its entries. The cache
44
+ # uses the entries' names as cache key and refuses to add
45
+ # entries that don't respond_to?(:name).
46
+ #
47
+ # @see OrderedSet::Cache::API
48
+ #
49
+ # @api private
50
+ class NameCache
51
+
52
+ include OrderedSet::Cache::API
53
+
54
+ # Tests if the given entry qualifies to be added to the cache
55
+ #
56
+ # @param [#name] entry
57
+ # the entry to be checked
58
+ #
59
+ # @return [Boolean]
60
+ # true if the entry respond_to?(:name)
61
+ #
62
+ # @api private
63
+ def valid?(entry)
64
+ entry.respond_to?(:name)
65
+ end
66
+
67
+ # Given an entry, return the key to be used in the cache
68
+ #
69
+ # @param [#name] entry
70
+ # the entry to get the key for
71
+ #
72
+ # @return [#to_s, nil]
73
+ # the entry's name or nil if the entry isn't #valid?
74
+ #
75
+ # @api private
76
+ def key_for(entry)
77
+ valid?(entry) ? entry.name : nil
78
+ end
79
+
80
+ end # class NameCache
81
+
82
+ include Enumerable
83
+
84
+ # The elements in the SubjectSet
85
+ #
86
+ # @return [OrderedSet]
87
+ #
88
+ # @api private
89
+ attr_reader :entries
90
+
91
+ # Initialize a SubjectSet
92
+ #
93
+ # @param [Enumerable<#name>] entries
94
+ # the entries to initialize this set with
95
+ #
96
+ # @api private
97
+ def initialize(entries = [])
98
+ @entries = OrderedSet.new(entries, NameCache)
99
+ end
100
+
101
+ # Initialize a copy of a SubjectSet
102
+ #
103
+ # @api private
104
+ def initialize_copy(*)
105
+ @entries = @entries.dup
106
+ end
107
+
108
+ # Make sure that entry is part of this SubjectSet
109
+ #
110
+ # If an entry with the same name already exists, it
111
+ # will be updated. If no such named entry exists, it
112
+ # will be added.
113
+ #
114
+ # @param [#name] entry
115
+ # the entry to be added
116
+ #
117
+ # @return [SubjectSet] self
118
+ #
119
+ # @api private
120
+ def <<(entry)
121
+ entries << entry
122
+ self
123
+ end
124
+
125
+ # Delete an entry from this SubjectSet
126
+ #
127
+ # @param [#name] entry
128
+ # the entry to delete
129
+ #
130
+ # @return [#name, nil]
131
+ # the deleted entry or nil
132
+ #
133
+ # @api private
134
+ def delete(entry)
135
+ entries.delete(entry)
136
+ end
137
+
138
+ # Removes all entries and returns self
139
+ #
140
+ # @return [SubjectSet] self
141
+ #
142
+ # @api private
143
+ def clear
144
+ entries.clear
145
+ self
146
+ end
147
+
148
+ # Test if the given entry is included in this SubjectSet
149
+ #
150
+ # @param [#name] entry
151
+ # the entry to test for
152
+ #
153
+ # @return [Boolean]
154
+ # true if the entry is included in this SubjectSet
155
+ #
156
+ # @api private
157
+ def include?(entry)
158
+ entries.include?(entry)
159
+ end
160
+
161
+ # Tests wether the SubjectSet contains a entry named name
162
+ #
163
+ # @param [#to_s] name
164
+ # the entry name to test for
165
+ #
166
+ # @return [Boolean]
167
+ # true if the SubjectSet contains a entry named name
168
+ #
169
+ # @api private
170
+ def named?(name)
171
+ !self[name].nil?
172
+ end
173
+
174
+ # Check if there are any entries
175
+ #
176
+ # @return [Boolean]
177
+ # true if the set contains at least one entry
178
+ #
179
+ # @api private
180
+ def empty?
181
+ entries.empty?
182
+ end
183
+
184
+ # Lookup an entry in the SubjectSet based on a given name
185
+ #
186
+ # @param [#to_s] name
187
+ # the name of the entry
188
+ #
189
+ # @return [Object, nil]
190
+ # the entry having the given name, or nil if not found
191
+ #
192
+ # @api private
193
+ def [](name)
194
+ name = name.to_s
195
+ entries.detect { |entry| entry.name.to_s == name }
196
+ end
197
+
198
+ # Iterate over each entry in the set
199
+ #
200
+ # @yield [entry]
201
+ # each entry in the set
202
+ #
203
+ # @yieldparam [#name] entry
204
+ # an entry in the set
205
+ #
206
+ # @return [SubjectSet] self
207
+ #
208
+ # @api private
209
+ def each
210
+ entries.each { |entry| yield(entry) }
211
+ self
212
+ end
213
+
214
+ # All entries (or nil values) that have any of the given names
215
+ #
216
+ # @param [Enumerable<#to_s>] names
217
+ # the names of the desired entries
218
+ #
219
+ # @return [Array<#name, nil>]
220
+ # an array containing entries whose names match any of the given
221
+ # names, or nil values for those names with no matching entries
222
+ # in the set
223
+ #
224
+ # @api private
225
+ def values_at(*names)
226
+ names.map { |name| self[name] }
227
+ end
228
+
229
+ # Get the number of elements inside this SubjectSet
230
+ #
231
+ # @return [Integer]
232
+ # the number of elements
233
+ #
234
+ # @api private
235
+ def size
236
+ entries.size
237
+ end
238
+
239
+ # Convert the SubjectSet into an Array
240
+ #
241
+ # @return [Array]
242
+ # an array containing all the SubjectSet's entries
243
+ #
244
+ # @api private
245
+ def to_ary
246
+ to_a
247
+ end
248
+
249
+ end # class SubjectSet
250
+ end # module Ardm
@@ -0,0 +1,3 @@
1
+ module Ardm
2
+ VERSION = '0.0.1'
3
+ end
data/lib/ardm.rb ADDED
@@ -0,0 +1,56 @@
1
+ puts __FILE__
2
+ module Ardm
3
+ # Check which ORM is loaded in Ardm.
4
+ #
5
+ # @api public
6
+ def self.orm
7
+ @orm ||= :active_record
8
+ end
9
+
10
+ # Set which orm to load.
11
+ #
12
+ # @api public
13
+ def self.orm=(orm)
14
+ if defined?(Ardm::ActiveRecord) || defined?(Ardm::DataMapper)
15
+ raise "Cannot change Ardm.orm when #{orm} libs are already loaded."
16
+ end
17
+
18
+ @orm = case orm.to_s
19
+ when /active_?record/, '' then :active_record
20
+ when /data_?mapper/ then :data_mapper
21
+ else raise "Unknown ENV['ORM']: #{ENV['ORM']}"
22
+ end
23
+ end
24
+
25
+ # Return true if Ardm has loaded ActiveRecord ORM.
26
+ #
27
+ # @api public
28
+ def self.active_record?
29
+ orm == :active_record
30
+ end
31
+
32
+ # Return true if Ardm has loaded DataMapper ORM.
33
+ #
34
+ # @api public
35
+ def self.data_mapper?
36
+ orm == :data_mapper
37
+ end
38
+
39
+ # Yield if Ardm has loaded ActiveRecord ORM.
40
+ #
41
+ # @api public
42
+ def self.active_record
43
+ yield if block_given? && active_record?
44
+ end
45
+
46
+ # Yield if Ardm has loaded DataMapper ORM.
47
+ #
48
+ # @api public
49
+ def self.data_mapper
50
+ yield if block_given? && data_mapper?
51
+ end
52
+
53
+ def self.lib
54
+ "ardm/#{orm}"
55
+ end
56
+ end
@@ -0,0 +1,11 @@
1
+ module Ardm
2
+ module Fixtures
3
+ class APIUser < Ardm::Record
4
+ self.table_name = "api_users"
5
+
6
+ property :id, Serial
7
+ property :name, String
8
+ property :api_key, APIKey
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,22 @@
1
+ module Ardm
2
+ module Fixtures
3
+ class Article < Ardm::Record
4
+ self.table_name = "articles"
5
+
6
+ property :id, Serial
7
+
8
+ property :title, String, :length => 255
9
+ property :body, Text
10
+
11
+ property :created_at, DateTime
12
+ property :updated_at, DateTime
13
+ property :published_at, DateTime
14
+
15
+ property :slug, Slug
16
+
17
+ before_validation do
18
+ self.slug = self.title
19
+ end
20
+ end # Article
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ module Ardm
2
+ module Fixtures
3
+ class Bookmark < Ardm::Record
4
+ self.table_name = "bookmarks"
5
+
6
+ property :id, Serial
7
+
8
+ property :title, String, :length => 255
9
+ property :shared, Boolean
10
+ property :uri, URI
11
+ property :tags, Yaml
12
+ end # Bookmark
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ module Ardm
2
+ module Fixtures
3
+ Invention = Struct.new(:name)
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ module Ardm
2
+ module Fixtures
3
+ class NetworkNode < Ardm::Record
4
+ self.table_name = "network_nodes"
5
+
6
+ property :id, Serial
7
+ property :ip_address, IPAddress
8
+ property :cidr_subnet_bits, Integer
9
+ property :node_uuid, UUID
10
+
11
+ alias_method :uuid, :node_uuid
12
+ alias_method :uuid=, :node_uuid=
13
+
14
+ def runs_ipv6?
15
+ self.ip_address.ipv6?
16
+ end
17
+
18
+ def runs_ipv4?
19
+ self.ip_address.ipv4?
20
+ end
21
+ end # NetworkNode
22
+ end # Fixtures
23
+ end # Ardm
@@ -0,0 +1,17 @@
1
+ module Ardm
2
+ module Fixtures
3
+ class Person < Ardm::Record
4
+ self.table_name = "people"
5
+
6
+ property :id, Serial
7
+ property :name, String
8
+ property :positions, Json
9
+ property :inventions, Yaml
10
+ property :birthday, EpochTime
11
+
12
+ property :interests, CommaSeparatedList
13
+
14
+ property :password, BCryptHash
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ module Ardm
2
+ module Fixtures
3
+ class SoftwarePackage < ::Ardm::Record
4
+ self.table_name = "software_packages"
5
+
6
+ property :id, Serial
7
+ property :node_number, Integer, :index => true
8
+
9
+ property :source_path, FilePath
10
+ property :destination_path, FilePath
11
+
12
+ property :product, String
13
+ property :version, String
14
+ property :released_at, DateTime
15
+
16
+ property :security_update, Boolean
17
+
18
+ property :installed_at, DateTime
19
+ property :installed_by, String
20
+ end # SoftwarePackage
21
+ end # Fixtures
22
+ end # Ardm
@@ -0,0 +1,12 @@
1
+ module Ardm
2
+ module Fixtures
3
+ class Ticket < ::Ardm::Record
4
+ self.table_name = "tickets"
5
+
6
+ property :id, Serial
7
+ property :title, String, :length => 255
8
+ property :body, Text
9
+ property :status, Enum[:unconfirmed, :confirmed, :assigned, :resolved, :not_applicable]
10
+ end # Ticket
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ module Ardm
2
+ module Fixtures
3
+ class TShirt < ::Ardm::Record
4
+ self.table_name = "tshirts"
5
+
6
+ property :id, Serial
7
+ property :writing, String
8
+ property :has_picture, Boolean, :default => false, :required => true
9
+ property :picture, Enum[:octocat, :fork_you, :git_down]
10
+
11
+ property :color, Enum[:white, :black, :red, :orange, :yellow, :green, :cyan, :blue, :purple]
12
+ property :size, Flag[:xs, :small, :medium, :large, :xl, :xxl], :default => :xs
13
+ end # Shirt
14
+ end # Fixtures
15
+ end # Ardm
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ try_spec do
4
+ require './spec/fixtures/api_user'
5
+
6
+ describe Ardm::Fixtures::APIUser do
7
+ subject { described_class.new(:name => 'alice') }
8
+
9
+ let(:original_api_key) { subject.api_key }
10
+
11
+ it "should have a default value" do
12
+ original_api_key.should_not be_nil
13
+ end
14
+
15
+ it "should preserve the default value" do
16
+ subject.api_key.should == original_api_key
17
+ end
18
+
19
+ it "should generate unique API Keys for each resource" do
20
+ other_resource = described_class.new(:name => 'eve')
21
+
22
+ other_resource.api_key.should_not == original_api_key
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require './spec/fixtures/person'
6
+
7
+ describe Ardm::Fixtures::Person do
8
+ before do
9
+ @resource = Ardm::Fixtures::Person.create!(:password => 'Ardm R0cks!')
10
+ Ardm::Fixtures::Person.create!(:password => 'password1')
11
+
12
+ @people = Ardm::Fixtures::Person.all
13
+ @resource.reload
14
+ end
15
+
16
+ it 'persists the password on initial save' do
17
+ @resource.password.should == 'Ardm R0cks!'
18
+ @people.last.password.should == 'password1'
19
+ end
20
+
21
+ it 'recalculates password hash on attribute update' do
22
+ @resource.attribute_set(:password, 'bcryptic obscure')
23
+ @resource.save
24
+
25
+ @resource.reload
26
+ @resource.password.should == 'bcryptic obscure'
27
+ @resource.password.should_not == 'Ardm R0cks!'
28
+ end
29
+
30
+ it 'does not change password value on reload' do
31
+ resource = @people.last
32
+ original = resource.password.to_s
33
+ resource.reload
34
+ resource.password.to_s.should == original
35
+ end
36
+
37
+ it 'uses cost of BCrypt::Engine::DEFAULT_COST' do
38
+ @resource.password.cost.should == BCrypt::Engine::DEFAULT_COST
39
+ end
40
+
41
+ it 'allows Bcrypt::Password#hash to be an Integer' do
42
+ @resource.password.hash.should be_kind_of(Integer)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require './spec/fixtures/person'
6
+
7
+ describe Ardm::Fixtures::Person do
8
+ before do
9
+ @resource = Ardm::Fixtures::Person.new(:name => '')
10
+ end
11
+
12
+ describe 'with no interests information' do
13
+ before do
14
+ @resource.interests = nil
15
+ end
16
+
17
+ describe 'when dumped and loaded again' do
18
+ before do
19
+ @resource.save.should be_true
20
+ @resource.reload
21
+ end
22
+
23
+ it 'has no interests' do
24
+ @resource.interests.should == nil
25
+ end
26
+ end
27
+ end
28
+
29
+ describe 'with no interests information' do
30
+ before do
31
+ @resource.interests = []
32
+ end
33
+
34
+ describe 'when dumped and loaded again' do
35
+ before do
36
+ @resource.save.should be_true
37
+ @resource.reload
38
+ end
39
+
40
+ it 'has empty interests list' do
41
+ @resource.interests.should == []
42
+ end
43
+ end
44
+ end
45
+
46
+ describe 'with interests information given as a Hash' do
47
+ it 'raises ArgumentError' do
48
+ lambda do
49
+ @resource.interests = { :hash => 'value' }
50
+ @resource.save
51
+ end.should raise_error(ArgumentError, /must be a string, an array or nil/)
52
+ end
53
+ end
54
+
55
+ describe 'with a few items on the interests list' do
56
+ before do
57
+ @input = 'fire, water, fire, a whole lot of other interesting things, ,,,'
58
+ @resource.interests = @input
59
+ end
60
+
61
+ describe 'when dumped and loaded again' do
62
+ before do
63
+ @resource.save.should be_true
64
+ @resource.reload
65
+ end
66
+
67
+ it 'includes "fire" in interests' do
68
+ @resource.interests.should include('fire')
69
+ end
70
+
71
+ it 'includes "water" in interests' do
72
+ @resource.interests.should include('water')
73
+ end
74
+
75
+ it 'includes "a whole lot of other interesting things" in interests' do
76
+ @resource.interests.should include('a whole lot of other interesting things')
77
+ end
78
+
79
+ it 'has blank entries removed' do
80
+ @resource.interests.any? { |i| Ardm::Ext.blank?(i) }.should be_false
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end