populate-me 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +655 -0
- data/Rakefile +14 -0
- data/example/config.ru +100 -0
- data/lib/populate_me.rb +2 -0
- data/lib/populate_me/admin.rb +157 -0
- data/lib/populate_me/admin/__assets__/css/asmselect.css +63 -0
- data/lib/populate_me/admin/__assets__/css/jquery-ui.min.css +6 -0
- data/lib/populate_me/admin/__assets__/css/main.css +244 -0
- data/lib/populate_me/admin/__assets__/img/help/children.png +0 -0
- data/lib/populate_me/admin/__assets__/img/help/create.png +0 -0
- data/lib/populate_me/admin/__assets__/img/help/delete.png +0 -0
- data/lib/populate_me/admin/__assets__/img/help/edit.png +0 -0
- data/lib/populate_me/admin/__assets__/img/help/form.png +0 -0
- data/lib/populate_me/admin/__assets__/img/help/list.png +0 -0
- data/lib/populate_me/admin/__assets__/img/help/login.png +0 -0
- data/lib/populate_me/admin/__assets__/img/help/logout.png +0 -0
- data/lib/populate_me/admin/__assets__/img/help/menu.png +0 -0
- data/lib/populate_me/admin/__assets__/img/help/overview.png +0 -0
- data/lib/populate_me/admin/__assets__/img/help/save.png +0 -0
- data/lib/populate_me/admin/__assets__/img/help/sort.png +0 -0
- data/lib/populate_me/admin/__assets__/img/help/sublist.png +0 -0
- data/lib/populate_me/admin/__assets__/js/asmselect.js +412 -0
- data/lib/populate_me/admin/__assets__/js/columnav.js +87 -0
- data/lib/populate_me/admin/__assets__/js/jquery-ui.min.js +7 -0
- data/lib/populate_me/admin/__assets__/js/main.js +388 -0
- data/lib/populate_me/admin/__assets__/js/mustache.js +578 -0
- data/lib/populate_me/admin/__assets__/js/sortable.js +2 -0
- data/lib/populate_me/admin/views/help.erb +94 -0
- data/lib/populate_me/admin/views/page.erb +189 -0
- data/lib/populate_me/api.rb +124 -0
- data/lib/populate_me/attachment.rb +186 -0
- data/lib/populate_me/document.rb +192 -0
- data/lib/populate_me/document_mixins/admin_adapter.rb +149 -0
- data/lib/populate_me/document_mixins/callbacks.rb +125 -0
- data/lib/populate_me/document_mixins/outcasting.rb +83 -0
- data/lib/populate_me/document_mixins/persistence.rb +95 -0
- data/lib/populate_me/document_mixins/schema.rb +198 -0
- data/lib/populate_me/document_mixins/typecasting.rb +70 -0
- data/lib/populate_me/document_mixins/validation.rb +44 -0
- data/lib/populate_me/file_system_attachment.rb +40 -0
- data/lib/populate_me/grid_fs_attachment.rb +103 -0
- data/lib/populate_me/mongo.rb +160 -0
- data/lib/populate_me/s3_attachment.rb +120 -0
- data/lib/populate_me/variation.rb +38 -0
- data/lib/populate_me/version.rb +4 -0
- data/populate-me.gemspec +34 -0
- data/test/helper.rb +37 -0
- data/test/test_admin.rb +183 -0
- data/test/test_api.rb +246 -0
- data/test/test_attachment.rb +167 -0
- data/test/test_document.rb +128 -0
- data/test/test_document_admin_adapter.rb +221 -0
- data/test/test_document_callbacks.rb +151 -0
- data/test/test_document_outcasting.rb +247 -0
- data/test/test_document_persistence.rb +83 -0
- data/test/test_document_schema.rb +280 -0
- data/test/test_document_typecasting.rb +128 -0
- data/test/test_grid_fs_attachment.rb +239 -0
- data/test/test_mongo.rb +324 -0
- data/test/test_s3_attachment.rb +281 -0
- data/test/test_variation.rb +91 -0
- data/test/test_version.rb +11 -0
- metadata +294 -0
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'populate_me/document'
|
3
|
+
|
4
|
+
class Hamburger < PopulateMe::Document
|
5
|
+
attr_accessor :taste
|
6
|
+
|
7
|
+
register_callback :layers, :bread
|
8
|
+
register_callback :layers, :cheese
|
9
|
+
register_callback :layers do
|
10
|
+
self.taste
|
11
|
+
end
|
12
|
+
|
13
|
+
register_callback :after_cook, :add_salad
|
14
|
+
register_callback :after_cook do
|
15
|
+
taste << ' with more cheese'
|
16
|
+
end
|
17
|
+
def add_salad
|
18
|
+
taste << ' with salad'
|
19
|
+
end
|
20
|
+
|
21
|
+
register_callback :after_eat do
|
22
|
+
taste << ' stomach'
|
23
|
+
end
|
24
|
+
register_callback :after_eat, prepend: true do
|
25
|
+
taste << ' my'
|
26
|
+
end
|
27
|
+
register_callback :after_eat, :prepend_for, prepend: true
|
28
|
+
def prepend_for
|
29
|
+
taste << ' for'
|
30
|
+
end
|
31
|
+
|
32
|
+
before :digest do
|
33
|
+
taste << ' taste'
|
34
|
+
end
|
35
|
+
before :digest, :add_dot
|
36
|
+
before :digest, prepend: true do
|
37
|
+
taste << ' the'
|
38
|
+
end
|
39
|
+
before :digest, :prepend_was, prepend: true
|
40
|
+
after :digest do
|
41
|
+
taste << ' taste'
|
42
|
+
end
|
43
|
+
after :digest, :add_dot
|
44
|
+
after :digest, prepend: true do
|
45
|
+
taste << ' the'
|
46
|
+
end
|
47
|
+
after :digest, :prepend_was, prepend: true
|
48
|
+
def add_dot; taste << '.'; end
|
49
|
+
def prepend_was; taste << ' was'; end
|
50
|
+
|
51
|
+
before :argument do |name|
|
52
|
+
taste << " #{name}"
|
53
|
+
end
|
54
|
+
after :argument, :after_with_arg
|
55
|
+
def after_with_arg(name)
|
56
|
+
taste << " #{name}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe PopulateMe::Document, 'Callbacks' do
|
61
|
+
|
62
|
+
parallelize_me!
|
63
|
+
|
64
|
+
let(:subject_class) { Hamburger }
|
65
|
+
subject { subject_class.new taste: 'good' }
|
66
|
+
let(:layers_callbacks) { subject_class.callbacks[:layers] }
|
67
|
+
|
68
|
+
it 'Registers callbacks as symbols or blocks' do
|
69
|
+
assert_equal 3, layers_callbacks.size
|
70
|
+
assert_equal :bread, layers_callbacks[0]
|
71
|
+
assert_equal :cheese, layers_callbacks[1]
|
72
|
+
assert_equal 'good', subject.instance_eval(&layers_callbacks[2])
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'Executes symbol or block callbacks' do
|
76
|
+
subject.exec_callback('after_cook')
|
77
|
+
assert_equal 'good with salad with more cheese', subject.taste
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'Does not raise if executing a callback which does not exist' do
|
81
|
+
subject.exec_callback(:after_burn)
|
82
|
+
assert_equal 'good', subject.taste
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'Has an option to prepend when registering callbacks' do
|
86
|
+
subject.exec_callback(:after_eat)
|
87
|
+
assert_equal 'good for my stomach', subject.taste
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'Has callbacks shortcut for before_ prefix' do
|
91
|
+
subject.exec_callback(:before_digest)
|
92
|
+
assert_equal 'good was the taste.', subject.taste
|
93
|
+
end
|
94
|
+
it 'Has callbacks shortcut for after_ prefix' do
|
95
|
+
subject.exec_callback(:after_digest)
|
96
|
+
assert_equal 'good was the taste.', subject.taste
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'Can pass the callback name as an argument to the callback method' do
|
100
|
+
subject.exec_callback(:before_argument)
|
101
|
+
assert_equal 'good before_argument', subject.taste
|
102
|
+
subject.exec_callback(:after_argument)
|
103
|
+
assert_equal 'good before_argument after_argument', subject.taste
|
104
|
+
end
|
105
|
+
|
106
|
+
describe '#ensure_position' do
|
107
|
+
|
108
|
+
class RaceCar < PopulateMe::Document
|
109
|
+
field :name
|
110
|
+
field :team
|
111
|
+
field :position_by_team, type: :position, scope: :team
|
112
|
+
position_field
|
113
|
+
end
|
114
|
+
|
115
|
+
before do
|
116
|
+
RaceCar.documents = []
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'Does not change position if already set' do
|
120
|
+
RaceCar.new(name: 'racer3', position: 3, team: 'A', position_by_team: 14).save
|
121
|
+
car = RaceCar.new(name: 'racer1', position: 12, team: 'A', position_by_team: 41)
|
122
|
+
car.ensure_position
|
123
|
+
assert_equal 12, car.position
|
124
|
+
assert_equal 41, car.position_by_team
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'Sets position fields to last position' do
|
128
|
+
RaceCar.new(name: 'racer1', position: 1, team: 'A', position_by_team: 41).save
|
129
|
+
RaceCar.new(name: 'racer2', position: 2, team: 'B', position_by_team: 12).save
|
130
|
+
RaceCar.new(name: 'racer3', position: 3, team: 'B', position_by_team: 14).save
|
131
|
+
car = RaceCar.new(team: 'B').ensure_position
|
132
|
+
assert_equal 4, car.position
|
133
|
+
assert_equal 15, car.position_by_team
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'Returns 0 when first document in scope' do
|
137
|
+
assert_equal 0, RaceCar.new.ensure_position.position
|
138
|
+
RaceCar.new(name: 'racer1', position: 1, team: 'A', position_by_team: 41).save
|
139
|
+
assert_equal 0, RaceCar.new(team: 'B').ensure_position.position_by_team
|
140
|
+
end
|
141
|
+
|
142
|
+
it "Ensures position before creating new document" do
|
143
|
+
car = RaceCar.new
|
144
|
+
car.save
|
145
|
+
assert_equal 0, car.position
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
@@ -0,0 +1,247 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'populate_me/document'
|
3
|
+
require 'populate_me/attachment'
|
4
|
+
|
5
|
+
class Outcasted < PopulateMe::Document
|
6
|
+
set :default_attachment_class, PopulateMe::Attachment
|
7
|
+
|
8
|
+
field :name
|
9
|
+
field :size, type: :select, select_options: [
|
10
|
+
{description: 'small', value: 's'},
|
11
|
+
{description: 'medium', value: 'm'},
|
12
|
+
{description: 'large', value: 'l'}
|
13
|
+
]
|
14
|
+
field :availability, type: :select, select_options: [
|
15
|
+
{description: 'Available', value: 'yes', preview_uri: 'http://www.example.org/yes.jpg' },
|
16
|
+
{description: 'On offer', value: 'almost', preview_uri: 'http://www.example.org/almost.jpg' },
|
17
|
+
{description: 'Sold', value: 'no', preview_uri: 'http://www.example.org/no.jpg' }
|
18
|
+
]
|
19
|
+
field :tags, type: :select, select_options: ['art','sport','science'], multiple: true
|
20
|
+
field :related_properties, type: :select, select_options: ['prop1','prop2','prop3'], multiple: true
|
21
|
+
field :pdf, type: :attachment
|
22
|
+
field :authors, type: :list
|
23
|
+
field :weirdo, type: :strange
|
24
|
+
field :price, type: :price
|
25
|
+
|
26
|
+
def get_size_options
|
27
|
+
[
|
28
|
+
[:small, :s],
|
29
|
+
[:medium, :m],
|
30
|
+
[:large, :l]
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
class Outcasted::Author < PopulateMe::Document
|
37
|
+
field :name
|
38
|
+
end
|
39
|
+
|
40
|
+
describe PopulateMe::Document, 'Outcasting' do
|
41
|
+
|
42
|
+
parallelize_me!
|
43
|
+
|
44
|
+
describe '#outcast' do
|
45
|
+
|
46
|
+
it 'Keeps the original info unchanged' do
|
47
|
+
original = Outcasted.fields[:name]
|
48
|
+
output = Outcasted.new.outcast(:name, original, {input_name_prefix: 'data'})
|
49
|
+
refute original.equal?(output)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'Adds input_name_prefix to input_name' do
|
53
|
+
original = Outcasted.fields[:name]
|
54
|
+
output = Outcasted.new.outcast(:name, original, {input_name_prefix: 'data'})
|
55
|
+
assert_equal 'data[name]', output[:input_name]
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'Sets input_value to the field value' do
|
59
|
+
original = Outcasted.fields[:name]
|
60
|
+
outcasted = Outcasted.new
|
61
|
+
outcasted.name = 'Thomas'
|
62
|
+
output = outcasted.outcast(:name, original, {input_name_prefix: 'data'})
|
63
|
+
assert_equal 'Thomas', output[:input_value]
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#outcast_list' do
|
69
|
+
|
70
|
+
it 'Has no value and an empty list of items when list is empty' do
|
71
|
+
original = Outcasted.fields[:authors]
|
72
|
+
output = Outcasted.new.outcast(:authors, original, {input_name_prefix: 'data'})
|
73
|
+
assert_nil output[:input_value]
|
74
|
+
assert_equal [], output[:items]
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'Nests the items in the list with their own nested prefix' do
|
78
|
+
original = Outcasted.fields[:authors]
|
79
|
+
outcasted = Outcasted.new
|
80
|
+
outcasted.authors.push(Outcasted::Author.new(name: 'Bob'))
|
81
|
+
outcasted.authors.push(Outcasted::Author.new(name: 'Mould'))
|
82
|
+
output = outcasted.outcast(:authors, original, {input_name_prefix: 'data'})
|
83
|
+
assert_nil output[:input_value]
|
84
|
+
assert_equal 2, output[:items].size
|
85
|
+
first_item = output[:items][0][:fields]
|
86
|
+
assert_equal 'data[authors][][name]', first_item[1][:input_name]
|
87
|
+
assert_equal 'Bob', first_item[1][:input_value]
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#outcast_select' do
|
93
|
+
|
94
|
+
def formated_options? original, output
|
95
|
+
assert_equal [ {description: 'small', value: 's'}, {description: 'medium', value: 'm'}, {description: 'large', value: 'l'} ], output[:select_options]
|
96
|
+
refute original[:select_options].equal?(output[:select_options])
|
97
|
+
assert output[:select_options].all?{|o|!o[:selected]}
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'Leaves the options as they are when they are already formated' do
|
101
|
+
original = Outcasted.fields[:size]
|
102
|
+
output = Outcasted.new.outcast(:size, original, {input_name_prefix: 'data'})
|
103
|
+
formated_options?(original, output)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'Can have more fields when they are already formated' do
|
107
|
+
# Mainly for adding a preview_uri but also future tweaks
|
108
|
+
original = Outcasted.fields[:availability]
|
109
|
+
output = Outcasted.new.outcast(:availability, original, {input_name_prefix: 'data'})
|
110
|
+
assert(output[:select_options].all?{|o| o.key?(:preview_uri)})
|
111
|
+
last = output[:select_options].last
|
112
|
+
assert_equal 'Sold', last[:description]
|
113
|
+
assert_equal 'no', last[:value]
|
114
|
+
assert_equal 'http://www.example.org/no.jpg', last[:preview_uri]
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'Formats the options when it is a 2 strings array' do
|
118
|
+
original = Outcasted.fields[:size].dup
|
119
|
+
original[:select_options] = [
|
120
|
+
[:small, :s],
|
121
|
+
[:medium, :m],
|
122
|
+
[:large, :l]
|
123
|
+
]
|
124
|
+
output = Outcasted.new.outcast(:size, original, {input_name_prefix: 'data'})
|
125
|
+
formated_options?(original, output)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'Formats the options when they come from a proc' do
|
129
|
+
original = Outcasted.fields[:size].dup
|
130
|
+
original[:select_options] = proc{[
|
131
|
+
[:small, :s],
|
132
|
+
[:medium, :m],
|
133
|
+
[:large, :l]
|
134
|
+
]}
|
135
|
+
output = Outcasted.new.outcast(:size, original, {input_name_prefix: 'data'})
|
136
|
+
formated_options?(original, output)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'Formats the options when they come from a symbol' do
|
140
|
+
original = Outcasted.fields[:size].dup
|
141
|
+
original[:select_options] = :get_size_options
|
142
|
+
output = Outcasted.new.outcast(:size, original, {input_name_prefix: 'data'})
|
143
|
+
formated_options?(original, output)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'Formats options when it comes from a simple string' do
|
147
|
+
original = Outcasted.fields[:size].dup
|
148
|
+
original[:select_options] = [:small,:medium,:large]
|
149
|
+
output = Outcasted.new.outcast(:size, original, {input_name_prefix: 'data'})
|
150
|
+
assert_equal [ {description: 'Small', value: 'small'}, {description: 'Medium', value: 'medium'}, {description: 'Large', value: 'large'} ], output[:select_options]
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'Selects the input value' do
|
154
|
+
original = Outcasted.fields[:size]
|
155
|
+
outcasted = Outcasted.new size: 'm'
|
156
|
+
output = outcasted.outcast(:size, original, {input_name_prefix: 'data'})
|
157
|
+
assert_equal 1, output[:select_options].select{|o|o[:selected]}.size
|
158
|
+
assert output[:select_options].find{|o|o[:value]=='m'}[:selected]
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'Adds [] at the end of input_name if multiple is true' do
|
162
|
+
original = Outcasted.fields[:tags]
|
163
|
+
output = Outcasted.new.outcast(:tags, original, {input_name_prefix: 'data'})
|
164
|
+
assert_equal 'data[tags][]', output[:input_name]
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'Selects multiple options when input_value is an array' do
|
168
|
+
original = Outcasted.fields[:tags]
|
169
|
+
outcasted = Outcasted.new tags: ['art','science']
|
170
|
+
output = outcasted.outcast(:tags, original, {input_name_prefix: 'data'})
|
171
|
+
assert output[:select_options].find{|o|o[:value]=='art'}[:selected]
|
172
|
+
assert output[:select_options].find{|o|o[:value]=='science'}[:selected]
|
173
|
+
refute output[:select_options].find{|o|o[:value]=='sport'}[:selected]
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'Orders input values at the begining when multiple options' do
|
177
|
+
original = Outcasted.fields[:related_properties]
|
178
|
+
|
179
|
+
# Normal
|
180
|
+
outcasted = Outcasted.new related_properties: ['prop3','prop1']
|
181
|
+
output = outcasted.outcast(:related_properties, original, {input_name_prefix: 'data'})
|
182
|
+
assert_equal 'prop3', output[:select_options][0][:value]
|
183
|
+
assert output[:select_options][0][:selected]
|
184
|
+
assert_equal 'prop1', output[:select_options][1][:value]
|
185
|
+
assert output[:select_options][1][:selected]
|
186
|
+
assert_equal 'prop2', output[:select_options][2][:value]
|
187
|
+
refute output[:select_options][2][:selected]
|
188
|
+
|
189
|
+
# When input_value is nil
|
190
|
+
outcasted = Outcasted.new
|
191
|
+
output = outcasted.outcast(:related_properties, original, {input_name_prefix: 'data'})
|
192
|
+
assert_equal 'prop1', output[:select_options][0][:value]
|
193
|
+
refute output[:select_options][0][:selected]
|
194
|
+
assert_equal 'prop2', output[:select_options][1][:value]
|
195
|
+
refute output[:select_options][1][:selected]
|
196
|
+
assert_equal 'prop3', output[:select_options][2][:value]
|
197
|
+
refute output[:select_options][2][:selected]
|
198
|
+
|
199
|
+
# When input_value has a non existing value
|
200
|
+
outcasted = Outcasted.new related_properties: ['stale','prop2']
|
201
|
+
output = outcasted.outcast(:related_properties, original, {input_name_prefix: 'data'})
|
202
|
+
assert_equal 'prop2', output[:select_options][0][:value]
|
203
|
+
assert output[:select_options][0][:selected]
|
204
|
+
assert_equal 'prop1', output[:select_options][1][:value]
|
205
|
+
refute output[:select_options][1][:selected]
|
206
|
+
assert_equal 'prop3', output[:select_options][2][:value]
|
207
|
+
refute output[:select_options][2][:selected]
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
describe '#outcast_price' do
|
213
|
+
|
214
|
+
it 'Displays the price in dollars/pounds' do
|
215
|
+
original = Outcasted.fields[:price]
|
216
|
+
outcasted = Outcasted.new price: 2999
|
217
|
+
output = outcasted.outcast(:price, original, {input_name_prefix: 'data'})
|
218
|
+
assert_equal '29.99', output[:input_value]
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'Leaves the field alone when value not an integer' do
|
222
|
+
original = Outcasted.fields[:price]
|
223
|
+
outcasted = Outcasted.new
|
224
|
+
output = outcasted.outcast(:price, original, {input_name_prefix: 'data'})
|
225
|
+
assert_nil outcasted.price
|
226
|
+
assert_nil output[:input_value]
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
describe '#outcast_attachment' do
|
232
|
+
|
233
|
+
it 'Sets url' do
|
234
|
+
original = Outcasted.fields[:pdf]
|
235
|
+
outcasted = Outcasted.new
|
236
|
+
output = outcasted.outcast(:pdf, original, {input_name_prefix: 'data'})
|
237
|
+
assert_nil output[:url]
|
238
|
+
|
239
|
+
outcasted.pdf = 'guidelines.pdf'
|
240
|
+
output = outcasted.outcast(:pdf, original, {input_name_prefix: 'data'})
|
241
|
+
assert_equal outcasted.attachment(:pdf).url, output[:url]
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
247
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'populate_me/document'
|
3
|
+
|
4
|
+
class Stuborn < PopulateMe::Document
|
5
|
+
attr_accessor :age
|
6
|
+
field :position
|
7
|
+
field :reversed, direction: :desc
|
8
|
+
end
|
9
|
+
|
10
|
+
describe PopulateMe::Document, 'Persistence' do
|
11
|
+
|
12
|
+
parallelize_me!
|
13
|
+
|
14
|
+
let(:subject_class) { Stuborn }
|
15
|
+
subject { subject_class.new }
|
16
|
+
|
17
|
+
describe '::is_unique' do
|
18
|
+
|
19
|
+
before do
|
20
|
+
Stuborn.documents = []
|
21
|
+
end
|
22
|
+
|
23
|
+
# def doc_doesnt_exist
|
24
|
+
# subject_class.stub(:admin_get, nil) do
|
25
|
+
# yield
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
# def doc_exists
|
29
|
+
# subject_class.stub(:admin_get, subject) do
|
30
|
+
# yield
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
|
34
|
+
describe 'The document does not exist yet' do
|
35
|
+
it 'Saves an entry with the ID `unique` by default' do
|
36
|
+
Stuborn.is_unique
|
37
|
+
assert_equal 1, Stuborn.documents.count
|
38
|
+
assert_equal 'unique', Stuborn.documents[0]['id']
|
39
|
+
end
|
40
|
+
it 'Saves an entry with a provided ID' do
|
41
|
+
Stuborn.is_unique('provided_id')
|
42
|
+
assert_equal 1, Stuborn.documents.count
|
43
|
+
assert_equal 'provided_id', Stuborn.documents[0]['id']
|
44
|
+
end
|
45
|
+
end
|
46
|
+
describe 'The document already exist' do
|
47
|
+
it 'Does not create a new document and preserve the current one' do
|
48
|
+
doc = Stuborn.new({'id'=>'unique', 'age'=>4})
|
49
|
+
doc.save
|
50
|
+
Stuborn.is_unique
|
51
|
+
assert_equal 1, Stuborn.documents.count
|
52
|
+
assert_equal doc.to_h, Stuborn.documents[0]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '::set_indexes' do
|
58
|
+
|
59
|
+
before do
|
60
|
+
Stuborn.documents = []
|
61
|
+
Stuborn.new('id' => 'a').save
|
62
|
+
Stuborn.new('id' => 'b').save
|
63
|
+
Stuborn.new('id' => 'c').save
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'Sets the indexes on the provided field' do
|
67
|
+
Stuborn.set_indexes(:position,['b','a','c'])
|
68
|
+
assert_equal 1, Stuborn.admin_get('a').position
|
69
|
+
assert_equal 0, Stuborn.admin_get('b').position
|
70
|
+
assert_equal 2, Stuborn.admin_get('c').position
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'Sets the indexes taking direction into account' do
|
74
|
+
Stuborn.set_indexes(:reversed,['b','a','c'])
|
75
|
+
assert_equal 1, Stuborn.admin_get('a').reversed
|
76
|
+
assert_equal 2, Stuborn.admin_get('b').reversed
|
77
|
+
assert_equal 0, Stuborn.admin_get('c').reversed
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|