datoki 1.0.1 → 2.0.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.
data/specs/datoki.rb DELETED
@@ -1,556 +0,0 @@
1
-
2
- describe 'record_errors' do
3
-
4
- it "prevents failing with an exception" do
5
- r = Class.new {
6
- include Datoki
7
- record_errors
8
- field(:title) { varchar }
9
- }.create
10
-
11
- r.errors.should == {:title=>{:msg=>'Title is required.', :value=>nil}}
12
- end
13
-
14
- end # === describe record_errors ====================================
15
-
16
- describe 'No type' do
17
-
18
- it "requires type to be specified" do
19
- should.raise(RuntimeError) {
20
- Class.new {
21
- include Datoki
22
- field(:title) { }
23
- }
24
- }.message.should.match /Type not specified/
25
- end
26
-
27
- end # === describe 'No type' ========================================
28
-
29
- describe :varchar do # ================================================
30
-
31
- it "requires field by default" do
32
- should.raise(Datoki::Invalid) {
33
- Class.new {
34
- include Datoki
35
- field(:title) { varchar }
36
- }.create
37
- }.message.should.match /Title is required/i
38
- end
39
-
40
- it "raises RuntimeError if allow :null and :min = 0" do
41
- should.raise(RuntimeError) {
42
- Class.new {
43
- include Datoki
44
- field(:name) { varchar nil, 0, 50 }
45
- }
46
- }.message.should.match /varchar can't be both: allow :null && :min = 0/
47
- end
48
-
49
- it "fails when varchar is less than min: varchar x, y" do
50
- should.raise(Datoki::Invalid) {
51
- Class.new {
52
- include Datoki
53
- field(:title) { varchar 3, 255 }
54
- }.create :title => '1'
55
- }.message.should.match /Title must be between 3 and 255 characters/i
56
- end
57
-
58
- it "fails when varchar is longer than max" do
59
- should.raise(Datoki::Invalid) {
60
- Class.new {
61
- include Datoki
62
- field(:title) { varchar 0, 5 }
63
- }.create :title => '123456'
64
- }.message.should.match /Title must be between 0 and 5 characters/
65
- end
66
-
67
- it "fails when varchar does not match pattern: match /../" do
68
- should.raise(Datoki::Invalid) {
69
- Class.new {
70
- include Datoki
71
- field :title do
72
- varchar
73
- match /\A[a-zA-Z0-9]+\z/i, "Title must be only: alphanumeric"
74
- end
75
- }.create :title => '$! title'
76
- }.message.should.match /Title must be only: alphanumeric/
77
- end
78
-
79
- it "allows varchar to be nil" do
80
- r = Class.new {
81
- include Datoki
82
- field(:title) {
83
- varchar nil, 1, 123
84
- }
85
- }.create()
86
- r.clean_data[:title].should == nil
87
- end
88
-
89
- it "sets field to return value of :set_to" do
90
- Class.new {
91
- include Datoki
92
- field(:title) {
93
- varchar
94
- set_to :custom_error
95
- def custom_error
96
- 'Custom title'
97
- end
98
- }
99
- }.
100
- create(:title => 'My Title').
101
- clean_data[:title].should.match /Custom title/
102
- end
103
-
104
- it "strips varchars by default" do
105
- Class.new {
106
- include Datoki
107
- field(:title) { varchar }
108
- }.
109
- create(:title => ' my title ').
110
- clean_data[:title].should == 'my title'
111
- end
112
-
113
- it "can prevent varchar from being stripped" do
114
- Class.new {
115
- include Datoki
116
- field(:title) {
117
- varchar
118
- disable :strip
119
- }
120
- }.
121
- create(:title => ' my title ').
122
- clean_data[:title].should == ' my title '
123
- end
124
-
125
- end # === describe Datoki ===
126
-
127
- describe Numeric do
128
-
129
- it "fails if number is outside the range" do
130
- should.raise(Datoki::Invalid) {
131
- Class.new {
132
- include Datoki
133
- field(:age) { smallint 1, 150 }
134
- }.create :age=>0
135
- }.message.should.match /age must be between 1 and 150/i
136
- end
137
-
138
- it "raises an exception if value is a non-numeric varchar." do
139
- should.raise(Datoki::Invalid) {
140
- Class.new {
141
- include Datoki
142
- field(:age) { smallint 1, 150 }
143
- }.create :age=>'twenty-two'
144
- }.message.should.match /age must be numeric/i
145
- end
146
-
147
- it "allows nil" do
148
- Class.new {
149
- include Datoki
150
- field(:age) { smallint nil, 1, 99 }
151
- }.create(:age=>nil).
152
- clean_data[:age].should == nil
153
- end
154
-
155
- it "allows nil in an array" do
156
- Class.new {
157
- include Datoki
158
- field(:age) { smallint [nil, 1,2,3,4] }
159
- }.create(:age=>nil).
160
- clean_data[:age].should == nil
161
- end
162
-
163
- it "allows to specify an Array of possible values" do
164
- Class.new {
165
- include Datoki
166
- field(:age) { smallint [1,2,3,4] }
167
- }.create(:age=>2).
168
- clean_data[:age].should == 2
169
- end
170
-
171
- it "fails if value is not in Array of possible values" do
172
- should.raise(Datoki::Invalid) {
173
- Class.new {
174
- include Datoki
175
- field(:num) { smallint [1,2,3,4] }
176
- }.create :num=>0
177
- }.message.should.match /Num can only be: 1, 2, 3, 4/
178
- end
179
-
180
- end # === describe Numeric
181
-
182
- describe "on :create" do
183
-
184
- it "after all fields have been cleaned" do
185
- Class.new {
186
-
187
- include Datoki
188
-
189
- on :create, def collect_values
190
- clean_data[:values] = clean_data.values.join ', '
191
- end
192
-
193
- field(:title) { varchar }
194
-
195
- field(:body) { varchar }
196
-
197
- }.
198
- create(:title=>'my title', :body=>'my body').
199
- clean_data[:values].should == 'my title, my body'
200
- end
201
-
202
- it "runs after validation for a field" do
203
- Class.new {
204
- include Datoki
205
- field(:body) {
206
- on :create, def add_stuff
207
- clean_data[:body] << ' with new stuff'
208
- end
209
-
210
- varchar
211
- }
212
- }.
213
- create(:body=>'the body').
214
- clean_data[:body].should == 'the body with new stuff'
215
- end
216
-
217
- end # === describe on :create
218
-
219
- describe "on :update" do
220
-
221
- it "runs after data has been cleaned" do
222
- r = Class.new {
223
- include Datoki
224
- on :update, def do_something
225
- clean_data[:vals] = clean_data.values.join ' -- '
226
- end
227
-
228
- field(:title) { varchar }
229
- field(:body) { varchar }
230
- }.new(:title=>'old title')
231
- r.update title: ' new title ', :body=>' new body '
232
- r.clean_data[:vals].should == 'new title -- new body'
233
- end
234
-
235
- end # === describe on :update
236
-
237
- describe "Datoki.db" do
238
-
239
- before {
240
-
241
- CACHE[:datoki_db_test] ||= reset_db <<-EOF
242
- CREATE TABLE "datoki_test" (
243
- id serial NOT NULL PRIMARY KEY,
244
- title varchar(123) NOT NULL,
245
- body text DEFAULT 'hello'
246
- );
247
- EOF
248
-
249
- @klass = Class.new {
250
- include Datoki
251
- record_errors
252
- table "datoki_test"
253
- field(:id) { integer; primary_key }
254
- field(:title) { varchar 1, 123 }
255
- field(:body) { text nil, 1, 123 }
256
- }
257
- }
258
-
259
- it 'raises Schema_Conflict if a field is found that allows null, but not specifed to do so' do
260
- should.raise(Datoki::Schema_Conflict) {
261
- Class.new {
262
- include Datoki
263
- table :datoki_test
264
- field(:id) { integer; primary_key }
265
- field(:title) { varchar 1, 123 }
266
- field(:body) { text 1, 123 }
267
- }
268
- }.message.should.match /:allow_null: true != false/
269
- end
270
-
271
- it "requires field if value = null and default = null and :allow_null = false" do
272
- r = @klass.create :title=>nil, :body=>"hiya"
273
- r.errors.should == {:title=>{:msg=>'Title is required.', :value=>nil}}
274
- end
275
-
276
- it "requires a value if: :text field, value = (empty string), min = 1, allow null" do
277
- r = @klass.create :title=>"The title", :body=>' '
278
- r.errors.should == {:body=>{:msg=>'Body is required.', :value=>""}}
279
- end
280
-
281
- it "does not turn strip.empty? strings into nulls" do
282
- r = @klass.create :title=>"The title", :body=>' '
283
- r.clean_data[:body].should == ''
284
- end
285
-
286
- it "imports field names into class" do
287
- @klass.fields.keys.should == [:id, :title, :body]
288
- end
289
-
290
- it "imports field types into class" do
291
- @klass.fields.values.map { |meta| meta[:type] }.should == [:integer, :varchar, :text]
292
- end
293
-
294
- it "removes field from :clean_data if set to nil and database has a default value" do
295
- r = @klass.create :title=>'hello', :body=>nil
296
- r.clean_data.keys.should == [:title]
297
- end
298
-
299
- end # === describe Datoki.db
300
-
301
- describe "Datoki.db Schema_Conflict" do
302
-
303
- before {
304
- CACHE[:schema_conflict] ||= begin
305
- reset_db <<-EOF
306
- CREATE TABLE "datoki_test" (
307
- id serial NOT NULL PRIMARY KEY,
308
- title varchar(123),
309
- body varchar(255) NOT NULL,
310
- created_at timestamp with time zone NOT NULL DEFAULT timezone('UTC'::text, now())
311
- );
312
- EOF
313
- end
314
- }
315
-
316
- it "raises Schema_Conflict when specified to allow nil, but db doesn not" do
317
- should.raise(Datoki::Schema_Conflict) {
318
- Class.new {
319
- include Datoki
320
- table :datoki_test
321
- field(:body) { varchar nil, 1, 255 }
322
- }
323
- }.message.should.match /:allow_null: false != true/i
324
- end
325
-
326
- it "raises Schema_Conflict when there is a :max_length conflict" do
327
- should.raise(Datoki::Schema_Conflict) {
328
- Class.new {
329
- include Datoki
330
- table :datoki_test
331
- field(:title) { varchar nil, 1, 200 }
332
- }
333
- }.message.should.match /:max: 123 != 200/i
334
- end
335
-
336
- end # === describe Datoki.db
337
-
338
- describe "Datoki.db :varchar" do
339
-
340
- before {
341
- CACHE[:datoki_db_varchar] ||= reset_db <<-EOF
342
- CREATE TABLE "datoki_test" (
343
- id serial NOT NULL PRIMARY KEY,
344
- title varchar(123) NOT NULL,
345
- body text
346
- );
347
- EOF
348
- @klass = Class.new {
349
- include Datoki
350
- table "datoki_test"
351
- field(:id) { primary_key }
352
- field(:title) { varchar 1, 123 }
353
- field(:body) { text nil, 1, 3000 }
354
- }
355
- }
356
-
357
- it "imports max length" do
358
- @klass.fields[:title][:max].should == 123
359
- end
360
-
361
- it "sets :min = 1 (by default, during import, if NOT NULL)" do
362
- @klass.fields[:title][:min].should == 1
363
- end
364
-
365
- it "sets :min = 1 (by default, during import, if :allow_null = true)" do
366
- @klass.fields[:body][:min].should == 1
367
- end
368
-
369
- end # === describe Datoki.db :varchar
370
-
371
- describe 'Datoki.db number' do
372
-
373
- before {
374
- CACHE[:datoki_db_number] ||= begin
375
- reset_db <<-EOF
376
- CREATE TABLE "datoki_test" (
377
- id serial NOT NULL PRIMARY KEY,
378
- parent_id smallint NOT NULL,
379
- title varchar(123) NOT NULL,
380
- body text
381
- );
382
- EOF
383
- end
384
- }
385
-
386
- it "does not set :min = 1" do
387
- Class.new {
388
- include Datoki
389
- table "datoki_test"
390
- field(:parent_id) { smallint }
391
- }.
392
- fields[:parent_id][:min].should == nil
393
- end
394
-
395
- end # === Datoki.db number
396
-
397
- describe 'Datoki.db :new' do
398
-
399
- before {
400
- CACHE[:datoki_db_new] ||= begin
401
- reset_db <<-EOF
402
- CREATE TABLE "datoki_test" (
403
- id serial NOT NULL PRIMARY KEY,
404
- parent_id smallint NOT NULL,
405
- title varchar(123) NOT NULL,
406
- body text
407
- );
408
- EOF
409
- end
410
- }
411
-
412
- it "raises Schema_Conflict if field has not been defined, but exists in the db schema" do
413
- should.raise(Datoki::Schema_Conflict) {
414
- Class.new {
415
- include Datoki
416
- table :datoki_test
417
- field(:id) { primary_key }
418
- field(:parent_id) { smallint }
419
- field(:body) { text nil, 1, 222 }
420
- }.new
421
- }.message.should.match /:title has not been defined/
422
- end
423
-
424
- end # === describe Datoki.db :new
425
-
426
-
427
- describe :href do
428
-
429
- before {
430
- CACHE[:datoki_db_href] ||= begin
431
- reset_db <<-EOF
432
- CREATE TABLE "datoki_test" (
433
- id serial NOT NULL PRIMARY KEY,
434
- homepage varchar(255) NOT NULL
435
- );
436
- EOF
437
- end
438
-
439
- @klass = Class.new {
440
- include Datoki
441
- table :datoki_test
442
- field(:id) { primary_key }
443
- field(:homepage) { href }
444
- }
445
- }
446
-
447
- it "sets :type to :varchar" do
448
- @klass.fields[:homepage][:type].should == :varchar
449
- end
450
-
451
- it "sets :max to 255" do
452
- @klass.fields[:homepage][:max].should == 255
453
- end
454
-
455
- it "sets :min to 0" do
456
- @klass.fields[:homepage][:min].should == 0
457
- end
458
-
459
- it "sets allow :null to false" do
460
- @klass.fields[:homepage][:allow][:null].should == false
461
- end
462
-
463
- it "sets :html_escape to :href" do
464
- @klass.fields[:homepage][:html_escape].should == :href
465
- end
466
-
467
- it "accepts a :min and :max" do
468
- CACHE[:datoki_db_href] = nil
469
- reset_db <<-EOF
470
- CREATE TABLE "datoki_test" (
471
- id serial NOT NULL PRIMARY KEY,
472
- homepage varchar(123) NOT NULL
473
- );
474
- EOF
475
- k = Class.new {
476
- include Datoki
477
- table :datoki_test
478
- field(:id) { primary_key }
479
- field(:homepage) { href 5, 123 }
480
- }
481
- k.fields[:homepage][:min].should == 5
482
- k.fields[:homepage][:max].should == 123
483
- end
484
-
485
- it "sets :min = 1 when null is allowed." do
486
- CACHE[:datoki_db_href] = nil
487
- reset_db <<-EOF
488
- CREATE TABLE "datoki_test" (
489
- id serial NOT NULL PRIMARY KEY,
490
- homepage varchar(222)
491
- );
492
- EOF
493
- k = Class.new {
494
- include Datoki
495
- table :datoki_test
496
- field(:id) { primary_key }
497
- field(:homepage) { href nil }
498
- }
499
- k.fields[:homepage][:min].should == 1
500
- k.fields[:homepage][:max].should == 222
501
- end
502
-
503
- end # === describe :href
504
-
505
-
506
- describe :html_escape do
507
-
508
- before {
509
- CACHE[:datoki_db_escape] ||= begin
510
- reset_db <<-EOF
511
- CREATE TABLE "datoki_test" (
512
- id serial NOT NULL PRIMARY KEY,
513
- parent_id smallint NOT NULL,
514
- title varchar(123) NOT NULL,
515
- url varchar(255) NOT NULL,
516
- body text NOT NULL
517
- );
518
- EOF
519
- end
520
-
521
- @klass = Class.new {
522
- include Datoki
523
- table :datoki_test
524
- field(:id) { primary_key }
525
- field(:parent_id) { smallint }
526
- field(:title) { varchar 1, 123 }
527
- field(:url) { href }
528
- field(:body) { text 1, 244 }
529
- }
530
- }
531
-
532
- it "returns a hash of all defined fields" do
533
- @klass.html_escape.should == {
534
- :id => :number,
535
- :parent_id => :number,
536
- :title => :string,
537
- :url => :href,
538
- :body => :string
539
- }
540
- end
541
-
542
- it "sets :href for urls" do
543
- @klass.html_escape[:url].should == :href
544
- end
545
-
546
- end # === describe :html_escape
547
-
548
-
549
-
550
-
551
-
552
-
553
-
554
-
555
-
556
-