datoki 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
-