ardm 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ardm::Property::Discriminator 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
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ardm::Property::Float do
|
4
|
+
let(:name) { :rating }
|
5
|
+
let(:type) { described_class }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:value) { 0.1 }
|
8
|
+
let(:other_value) { 0.2 }
|
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
|
+
it 'returns same value if a float' do
|
17
|
+
value = 24.0
|
18
|
+
property.typecast(value).should equal(value)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns float representation of a zero string integer' do
|
22
|
+
property.typecast('0').should eql(0.0)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns float representation of a positive string integer' do
|
26
|
+
property.typecast('24').should eql(24.0)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns float representation of a negative string integer' do
|
30
|
+
property.typecast('-24').should eql(-24.0)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns float representation of a zero string float' do
|
34
|
+
property.typecast('0.0').should eql(0.0)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'returns float representation of a positive string float' do
|
38
|
+
property.typecast('24.35').should eql(24.35)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'returns float representation of a negative string float' do
|
42
|
+
property.typecast('-24.35').should eql(-24.35)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'returns float representation of a zero string float, with no leading digits' do
|
46
|
+
property.typecast('.0').should eql(0.0)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns float representation of a positive string float, with no leading digits' do
|
50
|
+
property.typecast('.41').should eql(0.41)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'returns float representation of a zero integer' do
|
54
|
+
property.typecast(0).should eql(0.0)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'returns float representation of a positive integer' do
|
58
|
+
property.typecast(24).should eql(24.0)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'returns float representation of a negative integer' do
|
62
|
+
property.typecast(-24).should eql(-24.0)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'returns float representation of a zero decimal' do
|
66
|
+
property.typecast(BigDecimal('0.0')).should eql(0.0)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'returns float representation of a positive decimal' do
|
70
|
+
property.typecast(BigDecimal('24.35')).should eql(24.35)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'returns float representation of a negative decimal' do
|
74
|
+
property.typecast(BigDecimal('-24.35')).should eql(-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
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ardm::Property::Integer do
|
4
|
+
let(:name) { :age }
|
5
|
+
let(:type) { described_class }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:value) { 1 }
|
8
|
+
let(:other_value) { 2 }
|
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
|
+
it 'returns same value if an integer' do
|
17
|
+
value = 24
|
18
|
+
property.typecast(value).should equal(value)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns integer representation of a zero string integer' do
|
22
|
+
property.typecast('0').should eql(0)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns integer representation of a positive string integer' do
|
26
|
+
property.typecast('24').should eql(24)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns integer representation of a negative string integer' do
|
30
|
+
property.typecast('-24').should eql(-24)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns integer representation of a zero string float' do
|
34
|
+
property.typecast('0.0').should eql(0)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'returns integer representation of a positive string float' do
|
38
|
+
property.typecast('24.35').should eql(24)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'returns integer representation of a negative string float' do
|
42
|
+
property.typecast('-24.35').should eql(-24)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'returns integer representation of a zero string float, with no leading digits' do
|
46
|
+
property.typecast('.0').should eql(0)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns integer representation of a positive string float, with no leading digits' do
|
50
|
+
property.typecast('.41').should eql(0)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'returns integer representation of a zero float' do
|
54
|
+
property.typecast(0.0).should eql(0)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'returns integer representation of a positive float' do
|
58
|
+
property.typecast(24.35).should eql(24)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'returns integer representation of a negative float' do
|
62
|
+
property.typecast(-24.35).should eql(-24)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'returns integer representation of a zero decimal' do
|
66
|
+
property.typecast(BigDecimal('0.0')).should eql(0)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'returns integer representation of a positive decimal' do
|
70
|
+
property.typecast(BigDecimal('24.35')).should eql(24)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'returns integer representation of a negative decimal' do
|
74
|
+
property.typecast(BigDecimal('-24.35')).should eql(-24)
|
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
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module LookupFoo
|
4
|
+
class OtherProperty < Ardm::Property::String; end
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Ardm::Property::Lookup do
|
8
|
+
before do
|
9
|
+
@klass = Class.new(Ardm::Record) do
|
10
|
+
self.table_name = "articles"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should provide access to Property classes' do
|
15
|
+
@klass::Serial.should == Ardm::Property::Serial
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should provide access to Property classes from outside of the Property namespace' do
|
19
|
+
@klass::OtherProperty.should eq(LookupFoo::OtherProperty)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should not provide access to unknown Property classes' do
|
23
|
+
lambda {
|
24
|
+
@klass::Bla
|
25
|
+
}.should raise_error(NameError)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ardm::Property::Serial do
|
4
|
+
let(:name) { :id }
|
5
|
+
let(:type) { described_class }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:value) { 1 }
|
8
|
+
let(:other_value) { 2 }
|
9
|
+
let(:invalid_value) { 'foo' }
|
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,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ardm::Property::String do
|
4
|
+
let(:name) { :name }
|
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,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ardm::Property::Text 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
|
+
|
15
|
+
describe '#load' do
|
16
|
+
before do
|
17
|
+
@value = 'value'
|
18
|
+
end
|
19
|
+
|
20
|
+
subject { property.load(@value) }
|
21
|
+
|
22
|
+
let(:property) { type.new(model, name) }
|
23
|
+
|
24
|
+
it 'should delegate to #type.load' do
|
25
|
+
return_value = 'return value'
|
26
|
+
property.should_receive(:load).with(@value).and_return(return_value)
|
27
|
+
subject.should == return_value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ardm::Property::Time do
|
4
|
+
let(:name) { :deleted_at }
|
5
|
+
let(:type) { described_class }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:value) { Time.now }
|
8
|
+
let(:other_value) { Time.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 Time 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(Time)
|
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
|
+
result = property.typecast('22:24')
|
40
|
+
result.hour.should eql(22)
|
41
|
+
result.min.should eql(24)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'does not typecast non-time values' do
|
46
|
+
property.typecast('not-time').should eql('not-time')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# instance methods
|
4
|
+
describe Ardm::Property do
|
5
|
+
describe ".find_class" do
|
6
|
+
[ :Serial, :Text ].each do |type|
|
7
|
+
describe "with #{type}" do
|
8
|
+
subject { Ardm::Property.find_class(type) }
|
9
|
+
|
10
|
+
it { subject.should be(Ardm::Property.const_get(type)) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ".determine_class" do
|
16
|
+
[ Integer, String, Float, Class, String, Time, DateTime, Date ].each do |type|
|
17
|
+
describe "with #{type}" do
|
18
|
+
subject { Ardm::Property.determine_class(type) }
|
19
|
+
|
20
|
+
it { subject.should be(Ardm::Property.const_get(type.name)) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "with property subclasses" do
|
25
|
+
before do
|
26
|
+
Object.send(:remove_const, :CustomProps) if Object.const_defined?(:CustomProps)
|
27
|
+
|
28
|
+
module ::CustomProps
|
29
|
+
module Property
|
30
|
+
class Hash < Ardm::Property::Object; end
|
31
|
+
class Other < Ardm::Property::Object; end
|
32
|
+
class Serial < Ardm::Property::Object; end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "with ::Foo::Property::Hash" do
|
38
|
+
subject { Ardm::Property.determine_class(Hash) }
|
39
|
+
|
40
|
+
it { subject.should be(::CustomProps::Property::Hash) }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "with ::Foo::Property::Other" do
|
44
|
+
subject { Ardm::Property.determine_class(::CustomProps::Property::Other) }
|
45
|
+
|
46
|
+
it { subject.should be(::CustomProps::Property::Other) }
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
share_examples_for "A property with flags" do
|
2
|
+
before do
|
3
|
+
%w[ @property_klass ].each do |ivar|
|
4
|
+
raise "+#{ivar}+ should be defined in before block" unless instance_variable_defined?(ivar)
|
5
|
+
end
|
6
|
+
|
7
|
+
@flags = [ :one, :two, :three ]
|
8
|
+
|
9
|
+
class ::User < Ardm::Record
|
10
|
+
end
|
11
|
+
|
12
|
+
@property = User.property :item, @property_klass[@flags], :key => true
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ".generated_classes" do
|
16
|
+
it "should cache the generated class" do
|
17
|
+
@property_klass.generated_classes[@flags].should_not be_nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should include :flags in accepted_options" do
|
22
|
+
@property_klass.accepted_options.should include(:flags)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should respond to :generated_classes" do
|
26
|
+
@property_klass.should respond_to(:generated_classes)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should respond to :flag_map" do
|
30
|
+
@property.should respond_to(:flag_map)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should be custom" do
|
34
|
+
@property.custom?.should be(true)
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,229 @@
|
|
1
|
+
share_examples_for 'A public Property' do
|
2
|
+
before do
|
3
|
+
%w[ @type @load_as @name @value @other_value ].each do |ivar|
|
4
|
+
raise "+#{ivar}+ should be defined in before block" unless instance_variable_defined?(ivar)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ::Blog
|
8
|
+
class Article < Ardm::Record
|
9
|
+
self.table_name = "articles"
|
10
|
+
property :id, Serial
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
@model = Blog::Article
|
15
|
+
@options ||= {}
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "with a sub-type" do
|
19
|
+
before do
|
20
|
+
class ::SubType < @type; end
|
21
|
+
@subtype = ::SubType
|
22
|
+
@type.accept_options :foo, :bar
|
23
|
+
end
|
24
|
+
|
25
|
+
before do
|
26
|
+
@original = @type.accepted_options.dup
|
27
|
+
end
|
28
|
+
|
29
|
+
after do
|
30
|
+
@type.accepted_options.replace(@original - [ :foo, :bar ])
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "predefined options" do
|
34
|
+
before do
|
35
|
+
class ::ChildSubType < @subtype
|
36
|
+
default nil
|
37
|
+
end
|
38
|
+
@child_subtype = ChildSubType
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "when parent type overrides a default" do
|
42
|
+
before do
|
43
|
+
@subtype.default "foo"
|
44
|
+
end
|
45
|
+
|
46
|
+
after do
|
47
|
+
Ardm::Property.descendants.delete(ChildSubType)
|
48
|
+
Object.send(:remove_const, :ChildSubType)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should not override the child's type setting" do
|
52
|
+
@child_subtype.default.should eql(nil)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
after do
|
58
|
+
Ardm::Property.descendants.delete(SubType)
|
59
|
+
Object.send(:remove_const, :SubType)
|
60
|
+
end
|
61
|
+
|
62
|
+
describe ".accept_options" do
|
63
|
+
describe "when provided :foo, :bar" do
|
64
|
+
it "should add new options" do
|
65
|
+
[@type, @subtype].each do |type|
|
66
|
+
type.accepted_options.include?(:foo).should be(true)
|
67
|
+
type.accepted_options.include?(:bar).should be(true)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should create predefined option setters" do
|
72
|
+
[@type, @subtype].each do |type|
|
73
|
+
type.should respond_to(:foo)
|
74
|
+
type.should respond_to(:bar)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "auto-generated option setters" do
|
79
|
+
before do
|
80
|
+
@type.foo true
|
81
|
+
@type.bar 1
|
82
|
+
@property = @type.new(@model, @name, @options)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should set the pre-defined option values" do
|
86
|
+
@property.options[:foo].should == true
|
87
|
+
@property.options[:bar].should == 1
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should ask the superclass for the value if unknown" do
|
91
|
+
@subtype.foo.should == true
|
92
|
+
@subtype.bar.should == 1
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe ".descendants" do
|
99
|
+
it "should include the sub-type" do
|
100
|
+
@type.descendants.include?(SubType).should be(true)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe ".load_as" do
|
105
|
+
it "should return the load_as" do
|
106
|
+
[@type, @subtype].each do |type|
|
107
|
+
type.load_as.should be(@load_as)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should change the load_as class" do
|
112
|
+
@subtype.load_as Object
|
113
|
+
@subtype.load_as.should be(Object)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
[:allow_blank, :allow_nil].each do |opt|
|
119
|
+
describe "##{method = "#{opt}?"}" do
|
120
|
+
[true, false].each do |value|
|
121
|
+
describe "when created with :#{opt} => #{value}" do
|
122
|
+
before do
|
123
|
+
@property = @type.new(@model, @name, @options.merge(opt => value))
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should return #{value}" do
|
127
|
+
@property.send(method).should be(value)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "when created with :#{opt} => true and :required => true" do
|
133
|
+
it "should fail with ArgumentError" do
|
134
|
+
lambda {
|
135
|
+
@property = @type.new(@model, @name, @options.merge(opt => true, :required => true))
|
136
|
+
}.should raise_error(ArgumentError,
|
137
|
+
"options[:required] cannot be mixed with :allow_nil or :allow_blank")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
[:key?, :required?, :index, :unique_index, :unique?].each do |method|
|
144
|
+
describe "##{method}" do
|
145
|
+
[true, false].each do |value|
|
146
|
+
describe "when created with :#{method} => #{value}" do
|
147
|
+
before do
|
148
|
+
opt = method.to_s.chomp('?').to_sym
|
149
|
+
@property = @type.new(@model, @name, @options.merge(opt => value))
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should return #{value}" do
|
153
|
+
@property.send(method).should be(value)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe "#lazy?" do
|
161
|
+
describe "when created with :lazy => true, :key => false" do
|
162
|
+
before do
|
163
|
+
@property = @type.new(@model, @name, @options.merge(:lazy => true, :key => false))
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should return true" do
|
167
|
+
@property.lazy?.should be(true)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "when created with :lazy => true, :key => true" do
|
172
|
+
before do
|
173
|
+
@property = @type.new(@model, @name, @options.merge(:lazy => true, :key => true))
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should return false" do
|
177
|
+
@property.lazy?.should be(false)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe '#instance_of?' do
|
183
|
+
subject { property.instance_of?(klass) }
|
184
|
+
|
185
|
+
let(:property) { @type.new(@model, @name, @options) }
|
186
|
+
|
187
|
+
context 'when provided the property class' do
|
188
|
+
let(:klass) { @type }
|
189
|
+
|
190
|
+
it { should be(true) }
|
191
|
+
end
|
192
|
+
|
193
|
+
context 'when provided the property superclass' do
|
194
|
+
let(:klass) { @type.superclass }
|
195
|
+
|
196
|
+
it { should be(false) }
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'when provided the Ardm::Property class' do
|
200
|
+
let(:klass) { Ardm::Property }
|
201
|
+
|
202
|
+
it { should be(false) }
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
describe '#kind_of?' do
|
207
|
+
subject { property.kind_of?(klass) }
|
208
|
+
|
209
|
+
let(:property) { @type.new(@model, @name, @options) }
|
210
|
+
|
211
|
+
context 'when provided the property class' do
|
212
|
+
let(:klass) { @type }
|
213
|
+
|
214
|
+
it { should be(true) }
|
215
|
+
end
|
216
|
+
|
217
|
+
context 'when provided the property superclass' do
|
218
|
+
let(:klass) { @type.superclass }
|
219
|
+
|
220
|
+
it { should be(true) }
|
221
|
+
end
|
222
|
+
|
223
|
+
context 'when provided the Ardm::Property class' do
|
224
|
+
let(:klass) { Ardm::Property }
|
225
|
+
|
226
|
+
it { should be(true) }
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|