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,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ardm::Property::EpochTime do
4
+ before do
5
+ class ::User < Ardm::Record
6
+ property :id, Serial
7
+ property :bday, EpochTime
8
+ end
9
+
10
+ @property = User.properties[:bday]
11
+ end
12
+
13
+ describe '#dump' do
14
+ subject { @property.dump(value) }
15
+
16
+ describe 'with a Time instance' do
17
+ let(:value) { Time.now }
18
+
19
+ it { should == value.to_i }
20
+ end
21
+
22
+ describe 'with nil' do
23
+ let(:value) { nil }
24
+
25
+ it { should == value }
26
+ end
27
+ end
28
+
29
+ describe '#typecast' do
30
+ subject { @property.typecast(value) }
31
+
32
+ describe 'with a DateTime instance' do
33
+ let(:value) { DateTime.now }
34
+
35
+ it { should == Time.parse(value.to_s) }
36
+ end
37
+
38
+ describe 'with a number' do
39
+ let(:value) { Time.now.to_i }
40
+
41
+ it { should == ::Time.at(value) }
42
+ end
43
+
44
+ describe 'with a numeric string' do
45
+ let(:value) { Time.now.to_i.to_s }
46
+
47
+ it { should == ::Time.at(value.to_i) }
48
+ end
49
+
50
+ describe 'with a DateTime string' do
51
+ let(:value) { '2011-07-11 15:00:04 UTC' }
52
+
53
+ it { should == ::Time.parse(value) }
54
+ end
55
+ end
56
+
57
+ describe '#load' do
58
+ subject { @property.load(value) }
59
+
60
+ describe 'with a number' do
61
+ let(:value) { Time.now.to_i }
62
+
63
+ it { should == Time.at(value) }
64
+ end
65
+
66
+ describe 'with nil' do
67
+ let(:value) { nil }
68
+
69
+ it { should == value }
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+ require './spec/fixtures/software_package'
3
+
4
+ try_spec do
5
+ describe Ardm::Property::FilePath do
6
+ before do
7
+ @property = Ardm::Fixtures::SoftwarePackage.properties[:source_path]
8
+ end
9
+
10
+ before do
11
+ @input = '/usr/bin/ruby'
12
+ @path = Pathname.new(@input)
13
+ end
14
+
15
+ describe '.dump' do
16
+ describe 'when input is a string' do
17
+ it 'does not modify input' do
18
+ @property.dump(@input).should == @input
19
+ end
20
+ end
21
+
22
+ describe 'when input is nil' do
23
+ it 'returns nil' do
24
+ @property.dump(nil).should be_nil
25
+ end
26
+ end
27
+
28
+ describe 'when input is a blank string' do
29
+ it 'returns nil' do
30
+ @property.dump('').should be_nil
31
+ end
32
+ end
33
+ end
34
+
35
+ describe '.load' do
36
+ describe 'when value is a non-blank file path' do
37
+ it 'returns Pathname for a path' do
38
+ @property.load(@input).should == @path
39
+ end
40
+ end
41
+
42
+ describe 'when value is nil' do
43
+ it 'return nil' do
44
+ @property.load(nil).should be_nil
45
+ end
46
+ end
47
+
48
+ describe 'when value is a blank string' do
49
+ it 'returns nil' do
50
+ @property.load('').should be_nil
51
+ end
52
+ end
53
+ end
54
+
55
+ describe '.typecast' do
56
+ describe 'when a Pathname is given' do
57
+ it 'does not modify input' do
58
+ @property.typecast(@path).should == @path
59
+ end
60
+ end
61
+
62
+ describe 'when a nil is given' do
63
+ it 'does not modify input' do
64
+ @property.typecast(nil).should == nil
65
+ end
66
+ end
67
+
68
+ describe 'when a string is given' do
69
+ it 'returns Pathname for given path' do
70
+ @property.typecast(@input).should == @path
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+
3
+ require './spec/fixtures/tshirt'
4
+
5
+ try_spec do
6
+ describe Ardm::Property::Flag do
7
+ describe '.dump' do
8
+ before do
9
+ @flag = Ardm::Fixtures::TShirt.property(
10
+ :stuff, Ardm::Property::Flag[:first, :second, :third, :fourth, :fifth])
11
+
12
+ @property_klass = Ardm::Property::Flag
13
+ end
14
+
15
+ it_should_behave_like "A property with flags"
16
+
17
+ describe 'when argument matches a value in the flag map' do
18
+ before do
19
+ @result = @flag.dump(:first)
20
+ end
21
+
22
+ it 'returns flag bit of value' do
23
+ @result.should == 1
24
+ end
25
+ end
26
+
27
+ describe 'when argument matches 2nd value in the flag map' do
28
+ before do
29
+ @result = @flag.dump(:second)
30
+ end
31
+
32
+ it 'returns flag bit of value' do
33
+ @result.should == 2
34
+ end
35
+ end
36
+
37
+ describe 'when argument matches multiple Symbol values in the flag map' do
38
+ before do
39
+ @result = @flag.dump([ :second, :fourth ])
40
+ end
41
+
42
+ it 'builds binary flag from key values of all matches' do
43
+ @result.should == 10
44
+ end
45
+ end
46
+
47
+ describe 'when argument matches multiple string values in the flag map' do
48
+ before do
49
+ @result = @flag.dump(['first', 'second', 'third', 'fourth', 'fifth'])
50
+ end
51
+
52
+ it 'builds binary flag from key values of all matches' do
53
+ @result.should == 31
54
+ end
55
+ end
56
+
57
+ describe 'when argument does not match a single value in the flag map' do
58
+ before do
59
+ @result = @flag.dump(:zero)
60
+ end
61
+
62
+ it 'returns zero' do
63
+ @result.should == 0
64
+ end
65
+ end
66
+
67
+ describe 'when argument contains duplicate flags' do
68
+ before do
69
+ @result = @flag.dump([ :second, :fourth, :second ])
70
+ end
71
+
72
+ it 'behaves the same as if there were no duplicates' do
73
+ @result.should == @flag.dump([ :second, :fourth ])
74
+ end
75
+ end
76
+ end
77
+
78
+ describe '.load' do
79
+ before do
80
+ @flag = Ardm::Fixtures::TShirt.property(:stuff, Ardm::Property::Flag, :flags => [:uno, :dos, :tres, :cuatro, :cinco])
81
+ end
82
+
83
+ describe 'when argument matches a key in the flag map' do
84
+ before do
85
+ @result = @flag.load(4)
86
+ end
87
+
88
+ it 'returns array with a single matching element' do
89
+ @result.should == [ :tres ]
90
+ end
91
+ end
92
+
93
+ describe 'when argument matches multiple keys in the flag map' do
94
+ before do
95
+ @result = @flag.load(10)
96
+ end
97
+
98
+ it 'returns array of matching values' do
99
+ @result.should == [ :dos, :cuatro ]
100
+ end
101
+ end
102
+
103
+ describe 'when argument does not match a single key in the flag map' do
104
+ before do
105
+ @result = @flag.load(nil)
106
+ end
107
+
108
+ it 'returns an empty array' do
109
+ @result.should == []
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ require './spec/fixtures/network_node'
4
+
5
+ try_spec do
6
+ describe Ardm::Property::IPAddress do
7
+ before do
8
+ @stored = '81.20.130.1'
9
+ @input = IPAddr.new(@stored)
10
+ @property = Ardm::Fixtures::NetworkNode.properties[:ip_address]
11
+ end
12
+
13
+ describe '.dump' do
14
+ describe 'when argument is an IP address given as Ruby object' do
15
+ before do
16
+ @result = @property.dump(@input)
17
+ end
18
+
19
+ it 'dumps input into a string' do
20
+ @result.should == @stored
21
+ end
22
+ end
23
+
24
+ describe 'when argument is nil' do
25
+ before do
26
+ @result = @property.dump(nil)
27
+ end
28
+
29
+ it 'returns nil' do
30
+ @result.should be_nil
31
+ end
32
+ end
33
+
34
+ describe 'when input is a blank string' do
35
+ before do
36
+ @result = @property.dump('')
37
+ end
38
+
39
+ it 'retuns a blank string' do
40
+ @result.should == ''
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '.load' do
46
+ describe 'when argument is a valid IP address as a string' do
47
+ before do
48
+ @result = @property.load(@stored)
49
+ end
50
+
51
+ it 'returns IPAddr instance from stored value' do
52
+ @result.should == @input
53
+ end
54
+ end
55
+
56
+ describe 'when argument is nil' do
57
+ before do
58
+ @result = @property.load(nil)
59
+ end
60
+
61
+ it 'returns nil' do
62
+ @result.should be_nil
63
+ end
64
+ end
65
+
66
+ describe 'when argument is a blank string' do
67
+ before do
68
+ @result = @property.load('')
69
+ end
70
+
71
+ it 'returns IPAddr instance from stored value' do
72
+ @result.should == IPAddr.new('0.0.0.0')
73
+ end
74
+ end
75
+
76
+ describe 'when argument is an Array instance' do
77
+ before do
78
+ @operation = lambda { @property.load([]) }
79
+ end
80
+
81
+ it 'raises ArgumentError with a meaningful message' do
82
+ @operation.should raise_error(ArgumentError, '+value+ must be nil or a String')
83
+ end
84
+ end
85
+ end
86
+
87
+ describe '.typecast' do
88
+ describe 'when argument is an IpAddr object' do
89
+ before do
90
+ @result = @property.typecast(@input)
91
+ end
92
+
93
+ it 'does not change the value' do
94
+ @result.should == @input
95
+ end
96
+ end
97
+
98
+ describe 'when argument is a valid IP address as a string' do
99
+ before do
100
+ @result = @property.typecast(@stored)
101
+ end
102
+
103
+ it 'instantiates IPAddr instance' do
104
+ @result.should == @input
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+ require 'shared/identity_function_group'
3
+
4
+ try_spec do
5
+
6
+ require './spec/fixtures/person'
7
+
8
+ describe Ardm::Property::Json do
9
+ before do
10
+ @property = Ardm::Fixtures::Person.properties[:positions]
11
+ end
12
+
13
+ describe '.load' do
14
+ describe 'when nil is provided' do
15
+ it 'returns nil' do
16
+ @property.load(nil).should be_nil
17
+ end
18
+ end
19
+
20
+ describe 'when Json encoded primitive string is provided' do
21
+ it 'returns decoded value as Ruby string' do
22
+ @property.load(MultiJson.dump(:value => 'JSON encoded string')).should == { 'value' => 'JSON encoded string' }
23
+ end
24
+ end
25
+
26
+ describe 'when something else is provided' do
27
+ it 'raises ArgumentError with a meaningful message' do
28
+ lambda {
29
+ @property.load(:sym)
30
+ }.should raise_error(ArgumentError, '+value+ of a property of JSON type must be nil or a String')
31
+ end
32
+ end
33
+ end
34
+
35
+ describe '.dump' do
36
+ describe 'when nil is provided' do
37
+ it 'returns nil' do
38
+ @property.dump(nil).should be_nil
39
+ end
40
+ end
41
+
42
+ describe 'when Json encoded primitive string is provided' do
43
+ it 'does not do double encoding' do
44
+ @property.dump('Json encoded string').should == 'Json encoded string'
45
+ end
46
+ end
47
+
48
+ describe 'when regular Ruby string is provided' do
49
+ it 'dumps argument to Json' do
50
+ @property.dump('dump me (to JSON)').should == 'dump me (to JSON)'
51
+ end
52
+ end
53
+
54
+ describe 'when Ruby array is provided' do
55
+ it 'dumps argument to Json' do
56
+ @property.dump([1, 2, 3]).should == '[1,2,3]'
57
+ end
58
+ end
59
+
60
+ describe 'when Ruby hash is provided' do
61
+ it 'dumps argument to Json' do
62
+ @property.dump({ :datamapper => 'Data access layer in Ruby' }).
63
+ should == '{"datamapper":"Data access layer in Ruby"}'
64
+ end
65
+ end
66
+ end
67
+
68
+ describe '.typecast' do
69
+ class ::SerializeMe
70
+ attr_accessor :name
71
+ end
72
+
73
+ describe 'when given instance of a Hash' do
74
+ before do
75
+ @input = { :library => 'Ardm' }
76
+
77
+ @result = @property.typecast(@input)
78
+ end
79
+
80
+ it_should_behave_like 'identity function'
81
+ end
82
+
83
+ describe 'when given instance of an Array' do
84
+ before do
85
+ @input = %w[ ardm dm-more ]
86
+
87
+ @result = @property.typecast(@input)
88
+ end
89
+
90
+ it_should_behave_like 'identity function'
91
+ end
92
+
93
+ describe 'when given nil' do
94
+ before do
95
+ @input = nil
96
+
97
+ @result = @property.typecast(@input)
98
+ end
99
+
100
+ it_should_behave_like 'identity function'
101
+ end
102
+
103
+ describe 'when given JSON encoded value' do
104
+ before do
105
+ @input = '{ "value": 11 }'
106
+
107
+ @result = @property.typecast(@input)
108
+ end
109
+
110
+ it 'decodes value from JSON' do
111
+ @result.should == { 'value' => 11 }
112
+ end
113
+ end
114
+
115
+ describe 'when given instance of a custom class' do
116
+ before do
117
+ @input = SerializeMe.new
118
+ @input.name = 'Hello!'
119
+
120
+ # @result = @property.typecast(@input)
121
+ end
122
+
123
+ it 'attempts to load value from JSON string'
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,142 @@
1
+ require 'spec_helper'
2
+
3
+ module ::ParanoidBooleanBlog
4
+ class Draft < Ardm::Record
5
+ self.table_name = "articles"
6
+ property :id, Serial
7
+ property :deleted, ParanoidBoolean
8
+
9
+ before_destroy :before_destroy
10
+
11
+ def before_destroy; end
12
+ end
13
+
14
+ class Article < Draft; end
15
+
16
+ class Review < Article; end
17
+ end
18
+
19
+ describe Ardm::Property::ParanoidBoolean do
20
+ before do
21
+ @model = ParanoidBooleanBlog::Article
22
+ end
23
+
24
+ describe 'Property#destroy' do
25
+ subject { @resource.destroy }
26
+
27
+ describe 'with a new resource' do
28
+ before do
29
+ @resource = @model.new
30
+ end
31
+
32
+ it 'should not delete the resource from the datastore' do
33
+ method(:subject).should_not change { @model.with_deleted.size }.from(0)
34
+ end
35
+
36
+ it 'should not set the paranoid column' do
37
+ method(:subject).should_not change { @resource.deleted }.from(false)
38
+ end
39
+
40
+ it 'should run the destroy hook' do
41
+ # NOTE: changed behavior because AR doesn't call hooks on destroying new objects
42
+ @resource.should_not_receive(:before_destroy).with(no_args)
43
+ subject
44
+ end
45
+ end
46
+
47
+ describe 'with a saved resource' do
48
+ before do
49
+ @resource = @model.create
50
+ end
51
+
52
+ it { (!!subject).should be_true }
53
+
54
+ it 'should not delete the resource from the datastore' do
55
+ method(:subject).should_not change { @model.with_deleted.size }.from(1)
56
+ end
57
+
58
+ it 'should set the paranoid column' do
59
+ method(:subject).should change { @resource.deleted }.from(false).to(true)
60
+ end
61
+
62
+ it 'should run the destroy hook' do
63
+ @resource.should_receive(:before_destroy).with(no_args)
64
+ subject
65
+ end
66
+ end
67
+ end
68
+
69
+ describe 'Property#delete' do
70
+ subject { @resource.delete }
71
+
72
+ describe 'with a new resource' do
73
+ before do
74
+ @resource = @model.new
75
+ end
76
+
77
+ it 'should not delete the resource from the datastore' do
78
+ method(:subject).should_not change { @model.with_deleted.size }.from(0)
79
+ end
80
+
81
+ it 'should not set the paranoid column' do
82
+ method(:subject).should_not change { @resource.deleted }.from(false)
83
+ end
84
+
85
+ it 'should not run the destroy hook' do
86
+ @resource.should_not_receive(:before_destroy).with(no_args)
87
+ subject
88
+ end
89
+ end
90
+
91
+ describe 'with a saved resource' do
92
+ before do
93
+ @resource = @model.create
94
+ end
95
+
96
+ it { (!!subject).should be_true }
97
+
98
+ it 'should delete the resource from the datastore' do
99
+ method(:subject).should change { @model.with_deleted.size }.from(1).to(0)
100
+ end
101
+
102
+ it 'should not set the paranoid column' do
103
+ method(:subject).should_not change { @resource.deleted }.from(false)
104
+ end
105
+
106
+ it 'should not run the destroy hook' do
107
+ @resource.should_not_receive(:before_destroy).with(no_args)
108
+ subject
109
+ end
110
+ end
111
+ end
112
+
113
+ describe 'Model#with_deleted' do
114
+ before do
115
+ @resource = @model.create
116
+ @resource.destroy
117
+ end
118
+
119
+ describe 'with a block' do
120
+ subject { @model.with_deleted { @model.all } }
121
+
122
+ it 'should scope the block to return all resources' do
123
+ subject.map { |resource| resource.key }.should == [ @resource.key ]
124
+ end
125
+ end
126
+
127
+ describe 'without a block' do
128
+ subject { @model.with_deleted }
129
+
130
+ it 'should return a collection scoped to return all resources' do
131
+ subject.map { |resource| resource.key }.should == [ @resource.key ]
132
+ end
133
+ end
134
+ end
135
+
136
+ describe 'Model.inherited' do
137
+ it 'sets @paranoid_properties' do
138
+ ::ParanoidBooleanBlog::Review.instance_variable_get(:@paranoid_properties).should ==
139
+ ::ParanoidBooleanBlog::Article.instance_variable_get(:@paranoid_properties)
140
+ end
141
+ end
142
+ end