populate-me 0.0.9 → 0.0.10
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.
- data/lib/populate_me/mongo/crushyform.rb +7 -0
- data/lib/populate_me/mongo/mutation.rb +4 -1
- data/populate-me.gemspec +1 -1
- data/test/spec_mongo_mutation.rb +260 -0
- metadata +3 -2
@@ -32,6 +32,13 @@ module PopulateMe
|
|
32
32
|
:slug => proc do |m,c,o|
|
33
33
|
crushyform_types[:string].call(m,c,o)
|
34
34
|
end,
|
35
|
+
:price => proc do |m,c,o|
|
36
|
+
crushid = m.field_id_for(c)
|
37
|
+
price_main, price_cents = o[:input_value].to_i.divmod(100)
|
38
|
+
out = "<input type='text' name='%s[]' id='%s-main' class='%s price-main' value='%s' size='10' /> • "
|
39
|
+
out << "<input type='text' name='%s[]' id='%s-cents' class='%s price-cents' value='%s' size='2' maxlength='2' style='width: auto;' />"
|
40
|
+
out % [o[:input_name], crushid, o[:input_class], price_main, o[:input_name], crushid, o[:input_class], price_cents]
|
41
|
+
end,
|
35
42
|
:boolean => proc do |m,c,o|
|
36
43
|
crushid = m.field_id_for(c)
|
37
44
|
checked = 'checked' if o[:input_value]
|
@@ -8,7 +8,7 @@ module PopulateMe
|
|
8
8
|
|
9
9
|
def self.included(weak)
|
10
10
|
weak.extend(MutateClass)
|
11
|
-
weak.db = DB
|
11
|
+
weak.db = DB if defined?(DB)
|
12
12
|
weak.schema = BSON::OrderedHash.new
|
13
13
|
weak.relationships = BSON::OrderedHash.new
|
14
14
|
end
|
@@ -212,6 +212,9 @@ module PopulateMe
|
|
212
212
|
def validate; end
|
213
213
|
def after_validation; end
|
214
214
|
def fix_type_integer(k,v); @doc[k] = v.to_i; end
|
215
|
+
def fix_type_price(k,v)
|
216
|
+
v.kind_of?(Array) ? @doc[k] = (v[0].to_i*100)+v[1].to_i : @doc[k] = v.to_i
|
217
|
+
end
|
215
218
|
def fix_type_boolean(k,v); @doc[k] = (v=='true'||v==true) ? true : false; end
|
216
219
|
def fix_type_slug(k,v); @doc[k] = self.auto_slug if v.to_s==''; end
|
217
220
|
def fix_type_date(k,v)
|
data/populate-me.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'populate-me'
|
3
|
-
s.version = "0.0.
|
3
|
+
s.version = "0.0.10"
|
4
4
|
s.platform = Gem::Platform::RUBY
|
5
5
|
s.summary = "ALPHA !!! Populate Me is relatively complete but simple CMS"
|
6
6
|
s.description = "ALPHA !!! Populate Me is relatively complete but simple CMS. It includes a Rack middleware for putting in your Rack stack, and a bespoke MongoDB ODM. But Populate Me is not really finished yet."
|
@@ -0,0 +1,260 @@
|
|
1
|
+
Encoding.default_internal = Encoding.default_external = Encoding::UTF_8 if RUBY_VERSION >= '1.9.0'
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bacon'
|
5
|
+
require 'mongo'
|
6
|
+
$:.unshift './lib'
|
7
|
+
require 'populate_me/mongo'
|
8
|
+
|
9
|
+
MONGO = ::Mongo::MongoClient.new
|
10
|
+
class NoDB
|
11
|
+
include PopulateMe::Mongo::Plug
|
12
|
+
def self.human_name; 'No DB'; end
|
13
|
+
end
|
14
|
+
DB = MONGO['test-mongo-mutation']
|
15
|
+
|
16
|
+
class Naked; include PopulateMe::Mongo::Plug; end
|
17
|
+
|
18
|
+
class Person
|
19
|
+
include PopulateMe::Mongo::Plug
|
20
|
+
slot "name" # no options
|
21
|
+
slot "surname"
|
22
|
+
slot "age", :type=>:integer, :default=>18
|
23
|
+
image_slot "portrait"
|
24
|
+
slot 'subscribed_on', :type=>:date, :default=>proc{Time.now}
|
25
|
+
end
|
26
|
+
|
27
|
+
class Address
|
28
|
+
include PopulateMe::Mongo::Plug
|
29
|
+
slot "body"
|
30
|
+
end
|
31
|
+
|
32
|
+
class Article
|
33
|
+
include PopulateMe::Mongo::Plug
|
34
|
+
slot 'title'
|
35
|
+
slot 'content', :type=>:text
|
36
|
+
image_slot
|
37
|
+
end
|
38
|
+
|
39
|
+
class FeatureBox
|
40
|
+
include PopulateMe::Mongo::Plug
|
41
|
+
slot 'header'
|
42
|
+
self.label_column = 'header'
|
43
|
+
def self.human_plural_name; 'Feature Boxes'; end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "PopulateMe::Mongo::Mutation" do
|
47
|
+
|
48
|
+
describe ".db" do
|
49
|
+
it "Should be set to DB constant by default" do
|
50
|
+
NoDB.db.should==nil
|
51
|
+
Naked.db.should==DB
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
shared "Empty BSON" do
|
56
|
+
it "Should be set to an empty BSON ordered hash by default" do
|
57
|
+
@bson.class.should==::BSON::OrderedHash
|
58
|
+
@bson.empty?.should==true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe ".schema" do
|
63
|
+
before { @bson = Naked.schema }
|
64
|
+
behaves_like "Empty BSON"
|
65
|
+
end
|
66
|
+
|
67
|
+
describe ".relationships" do
|
68
|
+
before { @bson = Naked.relationships }
|
69
|
+
behaves_like "Empty BSON"
|
70
|
+
end
|
71
|
+
|
72
|
+
describe ".human_name" do
|
73
|
+
it "Returns a legible version of the class name - override when incorrect" do
|
74
|
+
Article.human_name.should=='Article'
|
75
|
+
FeatureBox.human_name.should=='Feature Box'
|
76
|
+
# No accronym for simplicity
|
77
|
+
# Easier to override when needed
|
78
|
+
NoDB.human_name.should=='No DB'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe ".human_plural_name" do
|
83
|
+
it "Only adds an 's' to human name - override if needed" do
|
84
|
+
Article.human_plural_name.should=='Articles'
|
85
|
+
# No rules for simplicity
|
86
|
+
# Easier to override when needed
|
87
|
+
FeatureBox.human_plural_name.should=='Feature Boxes'
|
88
|
+
# Here only .human_name was overridden
|
89
|
+
NoDB.human_plural_name.should=='No DBs'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe ".ref" do
|
94
|
+
it 'Returns a selector for a BSON::ObjectId' do
|
95
|
+
id = BSON::ObjectId.new
|
96
|
+
Address.ref(id).should=={'_id'=>id}
|
97
|
+
end
|
98
|
+
it 'Makes the argument a BSON::ObjectId if it is a valid string' do
|
99
|
+
string_id = '000000000000000000000000'
|
100
|
+
BSON::ObjectId.legal?(string_id).should==true
|
101
|
+
Address.ref(string_id).should=={'_id'=>BSON::ObjectId.from_string(string_id)}
|
102
|
+
end
|
103
|
+
it 'Just put an empty string in selector for any invalid argument' do
|
104
|
+
Address.ref('abc').should=={'_id'=>''}
|
105
|
+
Address.ref([]).should=={'_id'=>''}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
shared "Basic slot" do
|
110
|
+
it "Adds the declared slot to the schema" do
|
111
|
+
@klass.schema.key?(@key).should==true
|
112
|
+
end
|
113
|
+
it "Defines getters and setters" do
|
114
|
+
@klass.new.respond_to?(@key).should==true
|
115
|
+
@klass.new.respond_to?(@key+'=').should==true
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe ".slot" do
|
120
|
+
before { @klass = Person; @key = 'age' }
|
121
|
+
behaves_like "Basic slot"
|
122
|
+
it "Keeps the options in schema" do
|
123
|
+
Person.schema['age'][:default].should==18
|
124
|
+
Person.schema['age'][:type].should==:integer
|
125
|
+
end
|
126
|
+
it "Sets :type option to :string by default if not provided" do
|
127
|
+
Person.schema['name'][:type].should==:string
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
shared "Correctly typed" do
|
132
|
+
it "Has the correct type" do
|
133
|
+
@klass.schema[@key][:type].should==@type
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
shared "Image slot" do
|
138
|
+
describe "Reference slot" do
|
139
|
+
before { @type = :attachment }
|
140
|
+
behaves_like "Basic slot"
|
141
|
+
behaves_like "Correctly typed"
|
142
|
+
end
|
143
|
+
describe "Tooltip slot" do
|
144
|
+
before { @key = @key+'_tooltip'; @type = :string }
|
145
|
+
behaves_like "Basic slot"
|
146
|
+
behaves_like "Correctly typed"
|
147
|
+
end
|
148
|
+
describe "Alt text slot" do
|
149
|
+
before { @key = @key+'_alternative_text'; @type = :string }
|
150
|
+
behaves_like "Basic slot"
|
151
|
+
behaves_like "Correctly typed"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe ".image_slot" do
|
156
|
+
describe "Name provided" do
|
157
|
+
before { @klass = Person; @key = 'portrait' }
|
158
|
+
behaves_like "Image slot"
|
159
|
+
end
|
160
|
+
describe "Name not provided" do
|
161
|
+
before { @klass = Article; @key = 'image' }
|
162
|
+
behaves_like "Image slot"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# .slug_column
|
167
|
+
# .foreign_key_name
|
168
|
+
# .collection
|
169
|
+
# .find
|
170
|
+
# .find_one
|
171
|
+
# .count
|
172
|
+
# .sorting_order
|
173
|
+
# .sort
|
174
|
+
# .get
|
175
|
+
# .delete
|
176
|
+
# .is_unique
|
177
|
+
# .has_many
|
178
|
+
|
179
|
+
shared "Has error recipient" do
|
180
|
+
it "Has an empty recipent for errors" do
|
181
|
+
@inst.errors.should=={}
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "#initialize" do
|
186
|
+
describe "With fields" do
|
187
|
+
before { @inst = Person.new({'age'=>42, 'name'=>'Bozo', 'car'=>'Jaguar'}) }
|
188
|
+
it "Should be flagged as new if the doc has no _id yet" do
|
189
|
+
@inst.new?.should==true
|
190
|
+
end
|
191
|
+
it "Should not be flagged as new if the doc has an _id" do
|
192
|
+
@inst['_id'] = 'abc'
|
193
|
+
@inst.new?.should==false
|
194
|
+
end
|
195
|
+
it "Should pass all keys to the doc" do
|
196
|
+
@inst['name'].should=='Bozo'
|
197
|
+
@inst['car'].should=='Jaguar'
|
198
|
+
end
|
199
|
+
behaves_like "Has error recipient"
|
200
|
+
end
|
201
|
+
describe "Fresh new one" do
|
202
|
+
before { @inst = Person.new }
|
203
|
+
it "Should be flagged as new" do
|
204
|
+
@inst.new?.should==true
|
205
|
+
end
|
206
|
+
it "Has default values correctly set" do
|
207
|
+
@inst['age'].should==18 # direct value
|
208
|
+
@inst['subscribed_on'].class.should==Time # with proc
|
209
|
+
end
|
210
|
+
behaves_like "Has error recipient"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe "#model" do
|
215
|
+
it "Is a shortcut for self.class" do
|
216
|
+
Naked.new.model.should==Naked
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
describe '#to_label' do
|
221
|
+
it 'Uses a built-in list of slots to pick from for a label' do
|
222
|
+
Person.new({'age'=>42, 'name'=>'Bozo', 'surname'=>'Montana', 'car'=>'Jaguar'}).to_label.should=='Montana'
|
223
|
+
end
|
224
|
+
it 'Uses an other slot declared with label_column=' do
|
225
|
+
FeatureBox.new({'header'=>'Glamour'}).to_label.should=='Glamour'
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# #default_doc
|
230
|
+
# #id
|
231
|
+
# #[]
|
232
|
+
# #[]=
|
233
|
+
# #auto_slug
|
234
|
+
# #to_slug
|
235
|
+
# #to_param
|
236
|
+
# #field_id_for
|
237
|
+
# #resolve_class
|
238
|
+
# #parent
|
239
|
+
# #slot_children
|
240
|
+
# #first_slot_child
|
241
|
+
# #children
|
242
|
+
# #first_child
|
243
|
+
# #children_count
|
244
|
+
# #delete
|
245
|
+
# #new?
|
246
|
+
# #update_doc
|
247
|
+
# #errors_on
|
248
|
+
# #valid?
|
249
|
+
# Hooks
|
250
|
+
# Validation
|
251
|
+
# Fix types
|
252
|
+
# #save
|
253
|
+
|
254
|
+
describe 'CursorMutation' do
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|
258
|
+
|
259
|
+
MONGO.drop_database('test-mongo-mutation')
|
260
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: populate-me
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-04-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack-golem
|
@@ -94,6 +94,7 @@ files:
|
|
94
94
|
- lib/populate_me/mongo/plug.rb
|
95
95
|
- lib/populate_me/mongo/stash.rb
|
96
96
|
- populate-me.gemspec
|
97
|
+
- test/spec_mongo_mutation.rb
|
97
98
|
homepage: https://github.com/mig-hub/populate-me
|
98
99
|
licenses: []
|
99
100
|
post_install_message:
|