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.
- checksums.yaml +15 -0
- data/.gitignore +35 -0
- data/Gemfile +13 -0
- data/LICENSE +21 -0
- data/README.md +70 -0
- data/Rakefile +4 -0
- data/ardm.gemspec +29 -0
- data/db/.gitignore +1 -0
- data/lib/ardm/active_record/associations.rb +80 -0
- data/lib/ardm/active_record/base.rb +49 -0
- data/lib/ardm/active_record/dirty.rb +25 -0
- data/lib/ardm/active_record/hooks.rb +31 -0
- data/lib/ardm/active_record/inheritance.rb +37 -0
- data/lib/ardm/active_record/is/state_machine.rb +21 -0
- data/lib/ardm/active_record/is.rb +22 -0
- data/lib/ardm/active_record/not_found.rb +7 -0
- data/lib/ardm/active_record/predicate_builder/array_handler.rb +31 -0
- data/lib/ardm/active_record/predicate_builder/rails3.rb +147 -0
- data/lib/ardm/active_record/predicate_builder/rails4.rb +139 -0
- data/lib/ardm/active_record/predicate_builder/relation_handler.rb +15 -0
- data/lib/ardm/active_record/predicate_builder.rb +19 -0
- data/lib/ardm/active_record/property.rb +357 -0
- data/lib/ardm/active_record/query.rb +108 -0
- data/lib/ardm/active_record/record.rb +70 -0
- data/lib/ardm/active_record/relation.rb +83 -0
- data/lib/ardm/active_record/repository.rb +38 -0
- data/lib/ardm/active_record/serialization.rb +164 -0
- data/lib/ardm/active_record/storage_names.rb +28 -0
- data/lib/ardm/active_record/validations.rb +111 -0
- data/lib/ardm/active_record.rb +43 -0
- data/lib/ardm/data_mapper/not_found.rb +5 -0
- data/lib/ardm/data_mapper/record.rb +41 -0
- data/lib/ardm/data_mapper.rb +5 -0
- data/lib/ardm/env.rb +5 -0
- data/lib/ardm/property/api_key.rb +30 -0
- data/lib/ardm/property/bcrypt_hash.rb +31 -0
- data/lib/ardm/property/binary.rb +23 -0
- data/lib/ardm/property/boolean.rb +29 -0
- data/lib/ardm/property/class.rb +19 -0
- data/lib/ardm/property/comma_separated_list.rb +28 -0
- data/lib/ardm/property/csv.rb +35 -0
- data/lib/ardm/property/date.rb +12 -0
- data/lib/ardm/property/datetime.rb +12 -0
- data/lib/ardm/property/decimal.rb +38 -0
- data/lib/ardm/property/discriminator.rb +65 -0
- data/lib/ardm/property/enum.rb +51 -0
- data/lib/ardm/property/epoch_time.rb +38 -0
- data/lib/ardm/property/file_path.rb +25 -0
- data/lib/ardm/property/flag.rb +65 -0
- data/lib/ardm/property/float.rb +18 -0
- data/lib/ardm/property/integer.rb +24 -0
- data/lib/ardm/property/invalid_value_error.rb +22 -0
- data/lib/ardm/property/ip_address.rb +35 -0
- data/lib/ardm/property/json.rb +49 -0
- data/lib/ardm/property/lookup.rb +29 -0
- data/lib/ardm/property/numeric.rb +40 -0
- data/lib/ardm/property/object.rb +36 -0
- data/lib/ardm/property/paranoid_boolean.rb +18 -0
- data/lib/ardm/property/paranoid_datetime.rb +17 -0
- data/lib/ardm/property/regexp.rb +22 -0
- data/lib/ardm/property/serial.rb +16 -0
- data/lib/ardm/property/slug.rb +29 -0
- data/lib/ardm/property/string.rb +40 -0
- data/lib/ardm/property/support/dirty_minder.rb +169 -0
- data/lib/ardm/property/support/flags.rb +41 -0
- data/lib/ardm/property/support/paranoid_base.rb +78 -0
- data/lib/ardm/property/text.rb +11 -0
- data/lib/ardm/property/time.rb +12 -0
- data/lib/ardm/property/uri.rb +27 -0
- data/lib/ardm/property/uuid.rb +65 -0
- data/lib/ardm/property/validation.rb +208 -0
- data/lib/ardm/property/yaml.rb +38 -0
- data/lib/ardm/property.rb +891 -0
- data/lib/ardm/property_set.rb +152 -0
- data/lib/ardm/query/expression.rb +85 -0
- data/lib/ardm/query/ext/symbol.rb +37 -0
- data/lib/ardm/query/operator.rb +64 -0
- data/lib/ardm/record.rb +1 -0
- data/lib/ardm/support/assertions.rb +8 -0
- data/lib/ardm/support/deprecate.rb +12 -0
- data/lib/ardm/support/descendant_set.rb +89 -0
- data/lib/ardm/support/equalizer.rb +48 -0
- data/lib/ardm/support/ext/array.rb +22 -0
- data/lib/ardm/support/ext/blank.rb +25 -0
- data/lib/ardm/support/ext/hash.rb +67 -0
- data/lib/ardm/support/ext/module.rb +47 -0
- data/lib/ardm/support/ext/object.rb +57 -0
- data/lib/ardm/support/ext/string.rb +24 -0
- data/lib/ardm/support/ext/try_dup.rb +12 -0
- data/lib/ardm/support/hook.rb +405 -0
- data/lib/ardm/support/lazy_array.rb +451 -0
- data/lib/ardm/support/local_object_space.rb +13 -0
- data/lib/ardm/support/logger.rb +201 -0
- data/lib/ardm/support/mash.rb +176 -0
- data/lib/ardm/support/naming_conventions.rb +90 -0
- data/lib/ardm/support/ordered_set.rb +380 -0
- data/lib/ardm/support/subject.rb +33 -0
- data/lib/ardm/support/subject_set.rb +250 -0
- data/lib/ardm/version.rb +3 -0
- data/lib/ardm.rb +56 -0
- data/spec/fixtures/api_user.rb +11 -0
- data/spec/fixtures/article.rb +22 -0
- data/spec/fixtures/bookmark.rb +14 -0
- data/spec/fixtures/invention.rb +5 -0
- data/spec/fixtures/network_node.rb +23 -0
- data/spec/fixtures/person.rb +17 -0
- data/spec/fixtures/software_package.rb +22 -0
- data/spec/fixtures/ticket.rb +12 -0
- data/spec/fixtures/tshirt.rb +15 -0
- data/spec/integration/api_key_spec.rb +25 -0
- data/spec/integration/bcrypt_hash_spec.rb +45 -0
- data/spec/integration/comma_separated_list_spec.rb +85 -0
- data/spec/integration/dirty_minder_spec.rb +197 -0
- data/spec/integration/enum_spec.rb +79 -0
- data/spec/integration/epoch_time_spec.rb +59 -0
- data/spec/integration/file_path_spec.rb +158 -0
- data/spec/integration/flag_spec.rb +72 -0
- data/spec/integration/ip_address_spec.rb +151 -0
- data/spec/integration/json_spec.rb +70 -0
- data/spec/integration/slug_spec.rb +65 -0
- data/spec/integration/uri_spec.rb +136 -0
- data/spec/integration/uuid_spec.rb +102 -0
- data/spec/integration/yaml_spec.rb +85 -0
- data/spec/public/property/binary_spec.rb +41 -0
- data/spec/public/property/boolean_spec.rb +30 -0
- data/spec/public/property/class_spec.rb +28 -0
- data/spec/public/property/date_spec.rb +22 -0
- data/spec/public/property/date_time_spec.rb +22 -0
- data/spec/public/property/decimal_spec.rb +23 -0
- data/spec/public/property/discriminator_spec.rb +133 -0
- data/spec/public/property/float_spec.rb +22 -0
- data/spec/public/property/integer_spec.rb +22 -0
- data/spec/public/property/object_spec.rb +103 -0
- data/spec/public/property/serial_spec.rb +22 -0
- data/spec/public/property/string_spec.rb +22 -0
- data/spec/public/property/text_spec.rb +23 -0
- data/spec/public/property/time_spec.rb +22 -0
- data/spec/public/property_spec.rb +316 -0
- data/spec/rcov.opts +6 -0
- data/spec/schema.rb +86 -0
- data/spec/semipublic/property/binary_spec.rb +14 -0
- data/spec/semipublic/property/boolean_spec.rb +48 -0
- data/spec/semipublic/property/class_spec.rb +36 -0
- data/spec/semipublic/property/date_spec.rb +44 -0
- data/spec/semipublic/property/date_time_spec.rb +47 -0
- data/spec/semipublic/property/decimal_spec.rb +83 -0
- data/spec/semipublic/property/discriminator_spec.rb +22 -0
- data/spec/semipublic/property/float_spec.rb +83 -0
- data/spec/semipublic/property/integer_spec.rb +83 -0
- data/spec/semipublic/property/lookup_spec.rb +27 -0
- data/spec/semipublic/property/serial_spec.rb +14 -0
- data/spec/semipublic/property/string_spec.rb +14 -0
- data/spec/semipublic/property/text_spec.rb +30 -0
- data/spec/semipublic/property/time_spec.rb +49 -0
- data/spec/semipublic/property_spec.rb +51 -0
- data/spec/shared/flags_shared_spec.rb +36 -0
- data/spec/shared/identity_function_group.rb +5 -0
- data/spec/shared/public_property_spec.rb +229 -0
- data/spec/shared/semipublic_property_spec.rb +159 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +58 -0
- data/spec/unit/bcrypt_hash_spec.rb +154 -0
- data/spec/unit/csv_spec.rb +139 -0
- data/spec/unit/dirty_minder_spec.rb +64 -0
- data/spec/unit/enum_spec.rb +125 -0
- data/spec/unit/epoch_time_spec.rb +72 -0
- data/spec/unit/file_path_spec.rb +75 -0
- data/spec/unit/flag_spec.rb +114 -0
- data/spec/unit/ip_address_spec.rb +109 -0
- data/spec/unit/json_spec.rb +127 -0
- data/spec/unit/paranoid_boolean_spec.rb +142 -0
- data/spec/unit/paranoid_datetime_spec.rb +149 -0
- data/spec/unit/regexp_spec.rb +62 -0
- data/spec/unit/uri_spec.rb +64 -0
- data/spec/unit/yaml_spec.rb +111 -0
- data/tasks/spec.rake +40 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +350 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'addressable/uri'
|
|
4
|
+
|
|
5
|
+
# instance methods
|
|
6
|
+
describe Ardm::Property do
|
|
7
|
+
|
|
8
|
+
# define the model prior to supported_by
|
|
9
|
+
before do
|
|
10
|
+
class ::Track < Ardm::Record
|
|
11
|
+
property :id, Serial
|
|
12
|
+
property :artist, String, :lazy => false, :index => :artist_album
|
|
13
|
+
property :title, String, :field => 'name', :index => true
|
|
14
|
+
property :album, String, :index => :artist_album
|
|
15
|
+
property :musicbrainz_hash, String, :unique => true, :unique_index => true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class ::Image < Ardm::Record
|
|
19
|
+
property :md5hash, String, :key => true, :length => 32
|
|
20
|
+
property :title, String, :required => true, :unique => true
|
|
21
|
+
property :description, Text, :length => 1..1024, :lazy => [ :detail ]
|
|
22
|
+
property :width, Integer, :lazy => [:dimensions]
|
|
23
|
+
property :height, Integer, :lazy => [:dimensions]
|
|
24
|
+
property :format, String, :default => 'jpeg'
|
|
25
|
+
property :taken_at, Time, :default => proc { Time.now }
|
|
26
|
+
|
|
27
|
+
validates_presence_of :format
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe '#field' do
|
|
32
|
+
it 'returns @field value if it is present' do
|
|
33
|
+
Track.properties[:title].field.should eql('name')
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe '#default_for' do
|
|
38
|
+
it 'returns default value for non-callables' do
|
|
39
|
+
Image.properties[:format].default_for(Image.new).should == 'jpeg'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'returns result of a call for callable values' do
|
|
43
|
+
Image.properties[:taken_at].default_for(Image.new).year.should == Time.now.year
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "sets the default when the record is created" do
|
|
47
|
+
img = Image.create!(title: 'My Picture')
|
|
48
|
+
img.format.should == 'jpeg'
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe '#eql?' do
|
|
53
|
+
it 'is true for properties with the same model and name' do
|
|
54
|
+
Track.properties[:title].should eql(Track.properties[:title])
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
it 'is false for properties of different models' do
|
|
59
|
+
Track.properties[:title].should_not eql(Image.properties[:title])
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'is false for properties with different names' do
|
|
63
|
+
Track.properties[:title].should_not eql(Track.properties[:id])
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe '#get!' do
|
|
68
|
+
before do
|
|
69
|
+
@image = Image.new
|
|
70
|
+
|
|
71
|
+
# now some dark Ruby magic
|
|
72
|
+
@image.instance_variable_set(:@description, 'Is set by magic')
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'gets instance variable value from the resource directly' do
|
|
76
|
+
pending "support for this in ActiveRecord is questionable" do
|
|
77
|
+
# if you know a better way to test direct instance variable access,
|
|
78
|
+
# go ahead and make changes to this example
|
|
79
|
+
Image.properties[:description].get!(@image).should == 'Is set by magic'
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe '#index' do
|
|
85
|
+
it 'returns true when property has an index' do
|
|
86
|
+
Track.properties[:title].index.should be(true)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'returns index name when property has a named index' do
|
|
90
|
+
Track.properties[:album].index.should eql(:artist_album)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it 'returns false when property has no index' do
|
|
94
|
+
Track.properties[:musicbrainz_hash].index.should be(false)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
describe '#initialize' do
|
|
99
|
+
describe 'when tracking strategy is explicitly given' do
|
|
100
|
+
it 'uses tracking strategy from options'
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
describe '#inspect' do
|
|
105
|
+
before do
|
|
106
|
+
@str = Track.properties[:title].inspect
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it 'features model name' do
|
|
110
|
+
@str.should =~ /@model=Track/
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it 'features property name' do
|
|
114
|
+
@str.should =~ /@name=:title/
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
describe '#key?' do
|
|
119
|
+
describe 'returns true when property is a ' do
|
|
120
|
+
it 'serial key' do
|
|
121
|
+
Track.properties[:id].key?.should be(true)
|
|
122
|
+
end
|
|
123
|
+
it 'natural key' do
|
|
124
|
+
Image.properties[:md5hash].key?.should be(true)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it 'returns true when property is a part of composite key'
|
|
129
|
+
|
|
130
|
+
it 'returns false when property does not relate to a key' do
|
|
131
|
+
Track.properties[:title].key?.should be(false)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
describe '#lazy?' do
|
|
136
|
+
it 'returns true when property is lazy loaded' do
|
|
137
|
+
Image.properties[:description].lazy?.should be(true)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it 'returns false when property is not lazy loaded' do
|
|
141
|
+
Track.properties[:artist].lazy?.should be(false)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
describe '#length' do
|
|
146
|
+
it 'returns upper bound for Range values' do
|
|
147
|
+
Image.properties[:description].length.should eql(1024)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it 'returns value as is for integer values' do
|
|
151
|
+
Image.properties[:md5hash].length.should eql(32)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
describe '#min' do
|
|
156
|
+
describe 'when :min and :max options not provided to constructor' do
|
|
157
|
+
before do
|
|
158
|
+
@property = Image.property(:integer_with_nil_min, Integer)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it 'should be nil' do
|
|
162
|
+
@property.min.should be_nil
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
describe 'when :min option not provided to constructor, but :max is provided' do
|
|
167
|
+
before do
|
|
168
|
+
@property = Image.property(:integer_with_default_min, Integer, :max => 1)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it 'should be the default value' do
|
|
172
|
+
@property.min.should == 0
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
describe 'when :min and :max options provided to constructor' do
|
|
177
|
+
before do
|
|
178
|
+
@min = 1
|
|
179
|
+
@property = Image.property(:integer_with_explicit_min, Integer, :min => @min, :max => 2)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it 'should be the expected value' do
|
|
183
|
+
@property.min.should == @min
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
describe '#max' do
|
|
189
|
+
describe 'when :min and :max options not provided to constructor' do
|
|
190
|
+
before do
|
|
191
|
+
@property = Image.property(:integer_with_nil_max, Integer)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it 'should be nil' do
|
|
195
|
+
@property.max.should be_nil
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
describe 'when :max option not provided to constructor, but :min is provided' do
|
|
200
|
+
before do
|
|
201
|
+
@property = Image.property(:integer_with_default_max, Integer, :min => 1)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it 'should be the default value' do
|
|
205
|
+
@property.max.should == 2**31-1
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
describe 'when :min and :max options provided to constructor' do
|
|
210
|
+
before do
|
|
211
|
+
@max = 2
|
|
212
|
+
@property = Image.property(:integer_with_explicit_max, Integer, :min => 1, :max => @max)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
it 'should be the expected value' do
|
|
216
|
+
@property.max.should == @max
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
describe '#allow_nil?' do
|
|
222
|
+
it 'returns true when property can accept nil as its value' do
|
|
223
|
+
Track.properties[:artist].allow_nil?.should be(true)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
it 'returns false when property nil value is prohibited for this property' do
|
|
227
|
+
Image.properties[:title].allow_nil?.should be(false)
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
describe '#serial?' do
|
|
232
|
+
it 'returns true when property is serial (auto incrementing)' do
|
|
233
|
+
Track.properties[:id].serial?.should be(true)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it 'returns false when property is NOT serial (auto incrementing)' do
|
|
237
|
+
Image.properties[:md5hash].serial?.should be(false)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
describe '#set' do
|
|
242
|
+
before do
|
|
243
|
+
# keep in mind we must run these examples with a
|
|
244
|
+
# saved model instance
|
|
245
|
+
@image = Image.create(
|
|
246
|
+
:md5hash => '5268f0f3f452844c79843e820f998869',
|
|
247
|
+
:title => 'Rome at the sunset',
|
|
248
|
+
:description => 'Just wow'
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
@property = Image.properties[:title]
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
it 'triggers lazy loading for given resource'
|
|
255
|
+
|
|
256
|
+
it 'type casts given value' do
|
|
257
|
+
@property.set(@image, Addressable::URI.parse('http://test.example/'))
|
|
258
|
+
# get a string that has been typecasted using #to_str
|
|
259
|
+
@image.title.should == 'http://test.example/'
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
it 'sets new property value' do
|
|
263
|
+
@property.set(@image, 'Updated value')
|
|
264
|
+
@image.title.should == 'Updated value'
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
describe '#set!' do
|
|
269
|
+
before do
|
|
270
|
+
@image = Image.new(:md5hash => '5268f0f3f452844c79843e820f998869',
|
|
271
|
+
:title => 'Rome at the sunset',
|
|
272
|
+
:description => 'Just wow')
|
|
273
|
+
|
|
274
|
+
@property = Image.properties[:title]
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
it 'directly sets instance variable on given resource' do
|
|
278
|
+
@property.set!(@image, 'Set with dark Ruby magic')
|
|
279
|
+
@image.title.should == 'Set with dark Ruby magic'
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
describe '#unique?' do
|
|
284
|
+
it 'is true for fields that explicitly given uniq index' do
|
|
285
|
+
Track.properties[:musicbrainz_hash].unique?.should be(true)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
it 'is true for serial fields' do
|
|
289
|
+
pending do
|
|
290
|
+
Track.properties[:title].unique?.should be(true)
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
it 'is true for keys' do
|
|
295
|
+
Image.properties[:md5hash].unique?.should be(true)
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
describe '#unique_index' do
|
|
300
|
+
it 'returns true when property has unique index' do
|
|
301
|
+
Track.properties[:musicbrainz_hash].unique_index.should be(true)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
it 'returns false when property has no unique index' do
|
|
305
|
+
Track.properties[:title].unique_index.should be(false)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
it 'returns true when property is unique' do
|
|
309
|
+
Image.properties[:title].unique_index.should be(true)
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
it 'returns :key when property is a key' do
|
|
313
|
+
Track.properties[:id].unique_index.should == :key
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
end
|
data/spec/rcov.opts
ADDED
data/spec/schema.rb
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
::ActiveRecord::Schema.define do
|
|
2
|
+
|
|
3
|
+
create_table :api_users, :force => true do |t|
|
|
4
|
+
t.string :name
|
|
5
|
+
t.string :api_key
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
create_table :articles, :force => true do |t|
|
|
9
|
+
t.string :title
|
|
10
|
+
t.text :body
|
|
11
|
+
t.timestamps
|
|
12
|
+
t.datetime :published_at
|
|
13
|
+
t.boolean :deleted
|
|
14
|
+
t.datetime :deleted_at
|
|
15
|
+
t.string :slug
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
create_table :bookmarks, :force => true do |t|
|
|
19
|
+
t.string :title
|
|
20
|
+
t.boolean :shared
|
|
21
|
+
t.string :uri
|
|
22
|
+
t.text :tags
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
create_table :images, :force => true, :id => false do |t|
|
|
26
|
+
t.string :md5hash, :length => 32
|
|
27
|
+
t.index :md5hash, :unique => true
|
|
28
|
+
t.string :title
|
|
29
|
+
t.text :description, :length => 1024
|
|
30
|
+
t.integer :width
|
|
31
|
+
t.integer :height
|
|
32
|
+
t.string :format
|
|
33
|
+
t.time :taken_at
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
create_table :network_nodes, :force => true do |t|
|
|
37
|
+
t.string :ip_address
|
|
38
|
+
t.integer :cidr_subnet_bits
|
|
39
|
+
t.string :node_uuid
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
create_table :people, :force => true do |t|
|
|
43
|
+
t.string :name
|
|
44
|
+
t.text :positions
|
|
45
|
+
t.text :inventions
|
|
46
|
+
t.time :birthday
|
|
47
|
+
t.text :interests
|
|
48
|
+
t.string :password
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
create_table :software_packages, :force => true do |t|
|
|
52
|
+
t.integer :node_number
|
|
53
|
+
t.string :source_path
|
|
54
|
+
t.string :destination_path
|
|
55
|
+
t.string :product
|
|
56
|
+
t.string :version
|
|
57
|
+
t.datetime :released_at
|
|
58
|
+
t.boolean :security_update
|
|
59
|
+
t.datetime :installed_at
|
|
60
|
+
t.string :installed_by
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
create_table :tickets, :force => true do |t|
|
|
64
|
+
t.string :title
|
|
65
|
+
t.text :body
|
|
66
|
+
t.integer :status
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
create_table :tracks, :force => true do |t|
|
|
70
|
+
t.string :artist
|
|
71
|
+
t.string :name
|
|
72
|
+
t.string :album
|
|
73
|
+
t.string :musicbrainz_hash
|
|
74
|
+
t.index [:artist, :album]
|
|
75
|
+
t.index :name
|
|
76
|
+
t.index :musicbrainz_hash, :unique => true
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
create_table :tshirts, :force => true do |t|
|
|
80
|
+
t.string :writing
|
|
81
|
+
t.boolean :has_picture
|
|
82
|
+
t.text :picture
|
|
83
|
+
t.text :color
|
|
84
|
+
t.text :size
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Ardm::Property::Binary do
|
|
4
|
+
let(:name) { :title }
|
|
5
|
+
let(:type) { described_class }
|
|
6
|
+
let(:options) { {} }
|
|
7
|
+
let(:value) { 'value' }
|
|
8
|
+
let(:other_value) { 'return value' }
|
|
9
|
+
let(:invalid_value) { 1 }
|
|
10
|
+
let(:model) { Blog::Article }
|
|
11
|
+
let(:property) { type.new(model, name, options) }
|
|
12
|
+
|
|
13
|
+
it_should_behave_like 'A semipublic Property'
|
|
14
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Ardm::Property::Boolean do
|
|
4
|
+
let(:name) { :active }
|
|
5
|
+
let(:type) { described_class }
|
|
6
|
+
let(:options) { {:set => [true, false]} }
|
|
7
|
+
let(:value) { true }
|
|
8
|
+
let(:other_value) { false }
|
|
9
|
+
let(:invalid_value) { 1 }
|
|
10
|
+
let(:model) { Blog::Article }
|
|
11
|
+
let(:property) { type.new(model, name, options) }
|
|
12
|
+
|
|
13
|
+
it_should_behave_like 'A semipublic Property'
|
|
14
|
+
|
|
15
|
+
describe '#valid?' do
|
|
16
|
+
[ true, false ].each do |value|
|
|
17
|
+
it "returns true when value is #{value.inspect}" do
|
|
18
|
+
property.valid?(value).should be(true)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
[ 'true', 'TRUE', '1', 1, 't', 'T', 'false', 'FALSE', '0', 0, 'f', 'F' ].each do |value|
|
|
23
|
+
it "returns false for #{value.inspect}" do
|
|
24
|
+
property.valid?(value).should be(false)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe '#typecast' do
|
|
30
|
+
[ true, 'true', 'TRUE', '1', 1, 't', 'T' ].each do |value|
|
|
31
|
+
it "returns true when value is #{value.inspect}" do
|
|
32
|
+
property.typecast(value).should be(true)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
[ false, 'false', 'FALSE', '0', 0, 'f', 'F' ].each do |value|
|
|
37
|
+
it "returns false when value is #{value.inspect}" do
|
|
38
|
+
property.typecast(value).should be(false)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
[ 'string', 2, 1.0, BigDecimal('1.0'), DateTime.now, Time.now, Date.today, Class, Object.new, ].each do |value|
|
|
43
|
+
it "does not typecast value #{value.inspect}" do
|
|
44
|
+
property.typecast(value).should equal(value)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Ardm::Property::Class do
|
|
4
|
+
before do
|
|
5
|
+
Object.send(:remove_const, :Foo) if defined?(Foo)
|
|
6
|
+
Object.send(:remove_const, :Bar) if defined?(Bar)
|
|
7
|
+
|
|
8
|
+
class ::Foo; end
|
|
9
|
+
class ::Bar; end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
let(:name) { :type }
|
|
13
|
+
let(:type) { described_class }
|
|
14
|
+
let(:options) { {} }
|
|
15
|
+
let(:value) { Foo }
|
|
16
|
+
let(:other_value) { Bar }
|
|
17
|
+
let(:invalid_value) { 1 }
|
|
18
|
+
let(:model) { Blog::Article }
|
|
19
|
+
let(:property) { type.new(model, name, options) }
|
|
20
|
+
|
|
21
|
+
it_should_behave_like 'A semipublic Property'
|
|
22
|
+
|
|
23
|
+
describe '#typecast' do
|
|
24
|
+
it 'returns same value if a class' do
|
|
25
|
+
property.typecast(model).should equal(model)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'returns the class if found' do
|
|
29
|
+
property.typecast(model.name).should eql(model)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'does not typecast non-class values' do
|
|
33
|
+
property.typecast('NoClass').should eql('NoClass')
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Ardm::Property::Date do
|
|
4
|
+
let(:name) { :created_on }
|
|
5
|
+
let(:type) { described_class }
|
|
6
|
+
let(:options) { {} }
|
|
7
|
+
let(:value) { Date.today }
|
|
8
|
+
let(:other_value) { Date.today + 1 }
|
|
9
|
+
let(:invalid_value) { 1 }
|
|
10
|
+
let(:model) { Blog::Article }
|
|
11
|
+
let(:property) { type.new(model, name, options) }
|
|
12
|
+
|
|
13
|
+
it_should_behave_like 'A semipublic Property'
|
|
14
|
+
|
|
15
|
+
describe '#typecast' do
|
|
16
|
+
describe 'and value given as a hash with keys like :year, :month, etc' do
|
|
17
|
+
it 'builds a Date instance from hash values' do
|
|
18
|
+
result = property.typecast(
|
|
19
|
+
:year => '2007',
|
|
20
|
+
:month => '3',
|
|
21
|
+
:day => '25'
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
result.should be_kind_of(Date)
|
|
25
|
+
result.year.should eql(2007)
|
|
26
|
+
result.month.should eql(3)
|
|
27
|
+
result.day.should eql(25)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe 'and value is a string' do
|
|
32
|
+
it 'parses the string' do
|
|
33
|
+
result = property.typecast('Dec 20th, 2006')
|
|
34
|
+
result.month.should == 12
|
|
35
|
+
result.day.should == 20
|
|
36
|
+
result.year.should == 2006
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'does not typecast non-date values' do
|
|
41
|
+
property.typecast('not-date').should eql('not-date')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Ardm::Property::DateTime do
|
|
4
|
+
let(:name) { :created_at }
|
|
5
|
+
let(:type) { described_class }
|
|
6
|
+
let(:options) { {} }
|
|
7
|
+
let(:value) { DateTime.now }
|
|
8
|
+
let(:other_value) { DateTime.now + 15 }
|
|
9
|
+
let(:invalid_value) { 1 }
|
|
10
|
+
let(:model) { Blog::Article }
|
|
11
|
+
let(:property) { type.new(model, name, options) }
|
|
12
|
+
|
|
13
|
+
it_should_behave_like 'A semipublic Property'
|
|
14
|
+
|
|
15
|
+
describe '#typecast' do
|
|
16
|
+
describe 'and value given as a hash with keys like :year, :month, etc' do
|
|
17
|
+
it 'builds a DateTime instance from hash values' do
|
|
18
|
+
result = property.typecast(
|
|
19
|
+
:year => '2006',
|
|
20
|
+
:month => '11',
|
|
21
|
+
:day => '23',
|
|
22
|
+
:hour => '12',
|
|
23
|
+
:min => '0',
|
|
24
|
+
:sec => '0'
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
result.should be_kind_of(DateTime)
|
|
28
|
+
result.year.should eql(2006)
|
|
29
|
+
result.month.should eql(11)
|
|
30
|
+
result.day.should eql(23)
|
|
31
|
+
result.hour.should eql(12)
|
|
32
|
+
result.min.should eql(0)
|
|
33
|
+
result.sec.should eql(0)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe 'and value is a string' do
|
|
38
|
+
it 'parses the string' do
|
|
39
|
+
property.typecast('Dec, 2006').month.should == 12
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'does not typecast non-datetime values' do
|
|
44
|
+
property.typecast('not-datetime').should eql('not-datetime')
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Ardm::Property::Decimal do
|
|
4
|
+
let(:name) { :rate }
|
|
5
|
+
let(:type) { described_class }
|
|
6
|
+
let(:options) { { :precision => 5, :scale => 2 } }
|
|
7
|
+
let(:value) { BigDecimal('1.0') }
|
|
8
|
+
let(:other_value) { BigDecimal('2.0') }
|
|
9
|
+
let(:invalid_value) { true }
|
|
10
|
+
let(:model) { Blog::Article }
|
|
11
|
+
let(:property) { type.new(model, name, options) }
|
|
12
|
+
|
|
13
|
+
it_should_behave_like 'A semipublic Property'
|
|
14
|
+
|
|
15
|
+
describe '#typecast' do
|
|
16
|
+
it 'returns same value if a decimal' do
|
|
17
|
+
@value = BigDecimal('24.0')
|
|
18
|
+
property.typecast(@value).should equal(@value)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'returns decimal representation of a zero string integer' do
|
|
22
|
+
property.typecast('0').should eql(BigDecimal('0.0'))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'returns decimal representation of a positive string integer' do
|
|
26
|
+
property.typecast('24').should eql(BigDecimal('24.0'))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'returns decimal representation of a negative string integer' do
|
|
30
|
+
property.typecast('-24').should eql(BigDecimal('-24.0'))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'returns decimal representation of a zero string float' do
|
|
34
|
+
property.typecast('0.0').should eql(BigDecimal('0.0'))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'returns decimal representation of a positive string float' do
|
|
38
|
+
property.typecast('24.35').should eql(BigDecimal('24.35'))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'returns decimal representation of a negative string float' do
|
|
42
|
+
property.typecast('-24.35').should eql(BigDecimal('-24.35'))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'returns decimal representation of a zero string float, with no leading digits' do
|
|
46
|
+
property.typecast('.0').should eql(BigDecimal('0.0'))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'returns decimal representation of a positive string float, with no leading digits' do
|
|
50
|
+
property.typecast('.41').should eql(BigDecimal('0.41'))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'returns decimal representation of a zero integer' do
|
|
54
|
+
property.typecast(0).should eql(BigDecimal('0.0'))
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'returns decimal representation of a positive integer' do
|
|
58
|
+
property.typecast(24).should eql(BigDecimal('24.0'))
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'returns decimal representation of a negative integer' do
|
|
62
|
+
property.typecast(-24).should eql(BigDecimal('-24.0'))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'returns decimal representation of a zero float' do
|
|
66
|
+
property.typecast(0.0).should eql(BigDecimal('0.0'))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'returns decimal representation of a positive float' do
|
|
70
|
+
property.typecast(24.35).should eql(BigDecimal('24.35'))
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'returns decimal representation of a negative float' do
|
|
74
|
+
property.typecast(-24.35).should eql(BigDecimal('-24.35'))
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
[ Object.new, true, '0.', '-.0', 'string' ].each do |value|
|
|
78
|
+
it "does not typecast non-numeric value #{value.inspect}" do
|
|
79
|
+
property.typecast(value).should equal(value)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|