lluminary 0.2.0 → 0.2.2
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 +4 -4
- data/lib/lluminary/models/anthropic/claude_3_5_sonnet.rb +17 -0
- data/lib/lluminary/models/base.rb +11 -0
- data/lib/lluminary/providers/anthropic.rb +54 -0
- data/lib/lluminary/schema.rb +11 -7
- data/lib/lluminary/schema_model.rb +16 -2
- data/lib/lluminary/task.rb +40 -0
- data/lib/lluminary.rb +9 -3
- data/spec/lluminary/models/base_spec.rb +32 -0
- data/spec/lluminary/providers/anthropic_spec.rb +104 -0
- data/spec/lluminary/schema_model_spec.rb +259 -0
- data/spec/lluminary/schema_spec.rb +80 -241
- data/spec/lluminary/task_custom_validation_spec.rb +262 -0
- data/spec/lluminary/task_spec.rb +18 -0
- data/spec/spec_helper.rb +3 -0
- metadata +34 -2
@@ -169,4 +169,263 @@ RSpec.describe Lluminary::SchemaModel do
|
|
169
169
|
)
|
170
170
|
end
|
171
171
|
end
|
172
|
+
|
173
|
+
describe "boolean field validation" do
|
174
|
+
let(:fields) do
|
175
|
+
{ active: { type: :boolean, description: "Whether the item is active" } }
|
176
|
+
end
|
177
|
+
let(:model_class) { described_class.build(fields: fields, validations: []) }
|
178
|
+
|
179
|
+
it "accepts true values" do
|
180
|
+
instance = model_class.new(active: true)
|
181
|
+
expect(instance.valid?).to be true
|
182
|
+
expect(instance.errors.full_messages).to be_empty
|
183
|
+
end
|
184
|
+
|
185
|
+
it "accepts false values" do
|
186
|
+
instance = model_class.new(active: false)
|
187
|
+
expect(instance.valid?).to be true
|
188
|
+
expect(instance.errors.full_messages).to be_empty
|
189
|
+
end
|
190
|
+
|
191
|
+
it "accepts nil values" do
|
192
|
+
instance = model_class.new(active: nil)
|
193
|
+
expect(instance.valid?).to be true
|
194
|
+
expect(instance.errors.full_messages).to be_empty
|
195
|
+
end
|
196
|
+
|
197
|
+
it "returns errors for non-boolean values" do
|
198
|
+
instance = model_class.new(active: "true")
|
199
|
+
expect(instance.valid?).to be false
|
200
|
+
expect(instance.errors.full_messages).to contain_exactly(
|
201
|
+
"Active must be true or false"
|
202
|
+
)
|
203
|
+
|
204
|
+
instance = model_class.new(active: 1)
|
205
|
+
expect(instance.valid?).to be false
|
206
|
+
expect(instance.errors.full_messages).to contain_exactly(
|
207
|
+
"Active must be true or false"
|
208
|
+
)
|
209
|
+
end
|
210
|
+
|
211
|
+
it "can be required using presence validation" do
|
212
|
+
validations = [[[:active], { presence: true }]]
|
213
|
+
model_class_with_presence =
|
214
|
+
described_class.build(fields: fields, validations: validations)
|
215
|
+
instance = model_class_with_presence.new(active: nil)
|
216
|
+
expect(instance.valid?).to be false
|
217
|
+
expect(instance.errors.full_messages).to contain_exactly(
|
218
|
+
"Active can't be blank"
|
219
|
+
)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
describe "hash field with array validation" do
|
224
|
+
let(:fields) do
|
225
|
+
{
|
226
|
+
config: {
|
227
|
+
type: :hash,
|
228
|
+
description: "Configuration",
|
229
|
+
fields: {
|
230
|
+
name: {
|
231
|
+
type: :string,
|
232
|
+
description: nil
|
233
|
+
},
|
234
|
+
tags: {
|
235
|
+
type: :array,
|
236
|
+
description: nil,
|
237
|
+
element_type: {
|
238
|
+
type: :string,
|
239
|
+
description: nil
|
240
|
+
}
|
241
|
+
}
|
242
|
+
}
|
243
|
+
}
|
244
|
+
}
|
245
|
+
end
|
246
|
+
let(:model_class) { described_class.build(fields: fields, validations: []) }
|
247
|
+
|
248
|
+
it "validates arrays inside hashes" do
|
249
|
+
instance =
|
250
|
+
model_class.new(
|
251
|
+
config: {
|
252
|
+
name: "test",
|
253
|
+
tags: ["valid", 123, "also valid"]
|
254
|
+
}
|
255
|
+
)
|
256
|
+
expect(instance.valid?).to be false
|
257
|
+
expect(instance.errors.full_messages).to contain_exactly(
|
258
|
+
"Config[tags][1] must be a String"
|
259
|
+
)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe "nested hash validation" do
|
264
|
+
let(:fields) do
|
265
|
+
{
|
266
|
+
config: {
|
267
|
+
type: :hash,
|
268
|
+
description: nil,
|
269
|
+
fields: {
|
270
|
+
name: {
|
271
|
+
type: :string,
|
272
|
+
description: nil
|
273
|
+
},
|
274
|
+
database: {
|
275
|
+
type: :hash,
|
276
|
+
description: nil,
|
277
|
+
fields: {
|
278
|
+
host: {
|
279
|
+
type: :string,
|
280
|
+
description: nil
|
281
|
+
},
|
282
|
+
port: {
|
283
|
+
type: :integer,
|
284
|
+
description: nil
|
285
|
+
},
|
286
|
+
credentials: {
|
287
|
+
type: :hash,
|
288
|
+
description: nil,
|
289
|
+
fields: {
|
290
|
+
username: {
|
291
|
+
type: :string,
|
292
|
+
description: nil
|
293
|
+
},
|
294
|
+
password: {
|
295
|
+
type: :string,
|
296
|
+
description: nil
|
297
|
+
}
|
298
|
+
}
|
299
|
+
}
|
300
|
+
}
|
301
|
+
}
|
302
|
+
}
|
303
|
+
}
|
304
|
+
}
|
305
|
+
end
|
306
|
+
let(:model_class) { described_class.build(fields: fields, validations: []) }
|
307
|
+
|
308
|
+
it "validates nested hashes" do
|
309
|
+
instance =
|
310
|
+
model_class.new(
|
311
|
+
config: {
|
312
|
+
name: "test",
|
313
|
+
database: {
|
314
|
+
host: 123, # should be string
|
315
|
+
port: "80", # should be integer
|
316
|
+
credentials: {
|
317
|
+
username: 456, # should be string
|
318
|
+
password: 789 # should be string
|
319
|
+
}
|
320
|
+
}
|
321
|
+
}
|
322
|
+
)
|
323
|
+
expect(instance.valid?).to be false
|
324
|
+
expect(instance.errors.full_messages).to contain_exactly(
|
325
|
+
"Config[database][host] must be a String",
|
326
|
+
"Config[database][port] must be an Integer",
|
327
|
+
"Config[database][credentials][username] must be a String",
|
328
|
+
"Config[database][credentials][password] must be a String"
|
329
|
+
)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
describe "hash type enforcement" do
|
334
|
+
let(:fields) do
|
335
|
+
{
|
336
|
+
config: {
|
337
|
+
type: :hash,
|
338
|
+
description: nil,
|
339
|
+
fields: {
|
340
|
+
host: {
|
341
|
+
type: :string,
|
342
|
+
description: nil
|
343
|
+
}
|
344
|
+
}
|
345
|
+
}
|
346
|
+
}
|
347
|
+
end
|
348
|
+
let(:model_class) { described_class.build(fields: fields, validations: []) }
|
349
|
+
|
350
|
+
it "validates that value is a hash" do
|
351
|
+
instance = model_class.new(config: "not a hash")
|
352
|
+
expect(instance.valid?).to be false
|
353
|
+
expect(instance.errors.full_messages).to contain_exactly(
|
354
|
+
"Config must be a Hash"
|
355
|
+
)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
describe "array of hashes validation" do
|
360
|
+
let(:fields) do
|
361
|
+
{
|
362
|
+
users: {
|
363
|
+
type: :array,
|
364
|
+
description: nil,
|
365
|
+
element_type: {
|
366
|
+
type: :hash,
|
367
|
+
description: nil,
|
368
|
+
fields: {
|
369
|
+
name: {
|
370
|
+
type: :string,
|
371
|
+
description: nil
|
372
|
+
},
|
373
|
+
age: {
|
374
|
+
type: :integer,
|
375
|
+
description: nil
|
376
|
+
}
|
377
|
+
}
|
378
|
+
}
|
379
|
+
}
|
380
|
+
}
|
381
|
+
end
|
382
|
+
let(:model_class) { described_class.build(fields: fields, validations: []) }
|
383
|
+
|
384
|
+
it "validates hashes inside arrays" do
|
385
|
+
instance =
|
386
|
+
model_class.new(
|
387
|
+
users: [
|
388
|
+
{ name: "Alice", age: 30 },
|
389
|
+
{ name: 123, age: "invalid" }, # name should be string, age should be integer
|
390
|
+
{ name: "Bob", age: 25 }
|
391
|
+
]
|
392
|
+
)
|
393
|
+
expect(instance.valid?).to be false
|
394
|
+
expect(instance.errors.full_messages).to contain_exactly(
|
395
|
+
"Users[1][name] must be a String",
|
396
|
+
"Users[1][age] must be an Integer"
|
397
|
+
)
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
describe "float field validation" do
|
402
|
+
let(:fields) { { score: { type: :float, description: "The score" } } }
|
403
|
+
let(:model_class) { described_class.build(fields: fields, validations: []) }
|
404
|
+
|
405
|
+
it "accepts float values" do
|
406
|
+
instance = model_class.new(score: 3.14)
|
407
|
+
expect(instance.valid?).to be true
|
408
|
+
expect(instance.errors.full_messages).to be_empty
|
409
|
+
end
|
410
|
+
|
411
|
+
it "accepts nil values" do
|
412
|
+
instance = model_class.new(score: nil)
|
413
|
+
expect(instance.valid?).to be true
|
414
|
+
expect(instance.errors.full_messages).to be_empty
|
415
|
+
end
|
416
|
+
|
417
|
+
it "returns errors for non-float values" do
|
418
|
+
instance = model_class.new(score: "not a float")
|
419
|
+
expect(instance.valid?).to be false
|
420
|
+
expect(instance.errors.full_messages).to contain_exactly(
|
421
|
+
"Score must be a float"
|
422
|
+
)
|
423
|
+
|
424
|
+
instance = model_class.new(score: 42)
|
425
|
+
expect(instance.valid?).to be false
|
426
|
+
expect(instance.errors.full_messages).to contain_exactly(
|
427
|
+
"Score must be a float"
|
428
|
+
)
|
429
|
+
end
|
430
|
+
end
|
172
431
|
end
|
@@ -10,6 +10,58 @@ RSpec.describe Lluminary::Schema do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
describe "#validate" do
|
14
|
+
it "registers a custom validation method" do
|
15
|
+
schema.validate(:validate_something)
|
16
|
+
expect(schema.custom_validations).to eq(
|
17
|
+
[{ method: :validate_something, description: nil }]
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can register multiple validation methods" do
|
22
|
+
schema.validate(:validate_something)
|
23
|
+
schema.validate(:validate_something_else)
|
24
|
+
expect(schema.custom_validations).to eq(
|
25
|
+
[
|
26
|
+
{ method: :validate_something, description: nil },
|
27
|
+
{ method: :validate_something_else, description: nil }
|
28
|
+
]
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "registers a custom validation method with a description" do
|
33
|
+
schema.validate(
|
34
|
+
:validate_score_range,
|
35
|
+
description: "Score must be between 0 and 100"
|
36
|
+
)
|
37
|
+
expect(schema.custom_validations).to eq(
|
38
|
+
[
|
39
|
+
{
|
40
|
+
method: :validate_score_range,
|
41
|
+
description: "Score must be between 0 and 100"
|
42
|
+
}
|
43
|
+
]
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "registers multiple custom validations with and without descriptions" do
|
48
|
+
schema.validate(
|
49
|
+
:validate_score_range,
|
50
|
+
description: "Score must be between 0 and 100"
|
51
|
+
)
|
52
|
+
schema.validate(:validate_score_parity)
|
53
|
+
expect(schema.custom_validations).to eq(
|
54
|
+
[
|
55
|
+
{
|
56
|
+
method: :validate_score_range,
|
57
|
+
description: "Score must be between 0 and 100"
|
58
|
+
},
|
59
|
+
{ method: :validate_score_parity, description: nil }
|
60
|
+
]
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
13
65
|
describe "#string" do
|
14
66
|
it "adds a string field to the schema" do
|
15
67
|
schema.string(:name)
|
@@ -213,12 +265,6 @@ RSpec.describe Lluminary::Schema do
|
|
213
265
|
)
|
214
266
|
end
|
215
267
|
|
216
|
-
it "validates array elements" do
|
217
|
-
schema.array(:numbers) { integer }
|
218
|
-
errors = schema.validate(numbers: [1, "2", 3])
|
219
|
-
expect(errors).to contain_exactly("Numbers[1] must be an Integer")
|
220
|
-
end
|
221
|
-
|
222
268
|
it "supports hashes inside arrays" do
|
223
269
|
schema.array(:users) do
|
224
270
|
hash do
|
@@ -248,29 +294,6 @@ RSpec.describe Lluminary::Schema do
|
|
248
294
|
}
|
249
295
|
)
|
250
296
|
end
|
251
|
-
|
252
|
-
it "validates hashes inside arrays" do
|
253
|
-
schema.array(:users) do
|
254
|
-
hash do
|
255
|
-
string :name
|
256
|
-
integer :age
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
errors =
|
261
|
-
schema.validate(
|
262
|
-
users: [
|
263
|
-
{ name: "Alice", age: 30 },
|
264
|
-
{ name: 123, age: "invalid" }, # name should be string, age should be integer
|
265
|
-
{ name: "Bob", age: 25 }
|
266
|
-
]
|
267
|
-
)
|
268
|
-
|
269
|
-
expect(errors).to contain_exactly(
|
270
|
-
"Users[1][name] must be a String",
|
271
|
-
"Users[1][age] must be an Integer"
|
272
|
-
)
|
273
|
-
end
|
274
297
|
end
|
275
298
|
|
276
299
|
describe "#hash" do
|
@@ -307,33 +330,6 @@ RSpec.describe Lluminary::Schema do
|
|
307
330
|
)
|
308
331
|
end
|
309
332
|
|
310
|
-
it "validates hash values" do
|
311
|
-
schema.hash(:config) do
|
312
|
-
string :host
|
313
|
-
integer :port
|
314
|
-
end
|
315
|
-
|
316
|
-
errors =
|
317
|
-
schema.validate(
|
318
|
-
config: {
|
319
|
-
host: 123, # should be string
|
320
|
-
port: "80" # should be integer
|
321
|
-
}
|
322
|
-
)
|
323
|
-
|
324
|
-
expect(errors).to contain_exactly(
|
325
|
-
"Config[host] must be a String",
|
326
|
-
"Config[port] must be an Integer"
|
327
|
-
)
|
328
|
-
end
|
329
|
-
|
330
|
-
it "validates that value is a hash" do
|
331
|
-
schema.hash(:config) { string :host }
|
332
|
-
|
333
|
-
errors = schema.validate(config: "not a hash")
|
334
|
-
expect(errors).to contain_exactly("Config must be a Hash")
|
335
|
-
end
|
336
|
-
|
337
333
|
it "supports nested hashes" do
|
338
334
|
schema.hash(:config) do
|
339
335
|
string :name
|
@@ -389,42 +385,6 @@ RSpec.describe Lluminary::Schema do
|
|
389
385
|
)
|
390
386
|
end
|
391
387
|
|
392
|
-
it "validates nested hashes" do
|
393
|
-
schema.hash(:config) do
|
394
|
-
string :name
|
395
|
-
hash :database do
|
396
|
-
string :host
|
397
|
-
integer :port
|
398
|
-
hash :credentials do
|
399
|
-
string :username
|
400
|
-
string :password
|
401
|
-
end
|
402
|
-
end
|
403
|
-
end
|
404
|
-
|
405
|
-
errors =
|
406
|
-
schema.validate(
|
407
|
-
config: {
|
408
|
-
name: "test",
|
409
|
-
database: {
|
410
|
-
host: 123, # should be string
|
411
|
-
port: "80", # should be integer
|
412
|
-
credentials: {
|
413
|
-
username: 456, # should be string
|
414
|
-
password: 789 # should be string
|
415
|
-
}
|
416
|
-
}
|
417
|
-
}
|
418
|
-
)
|
419
|
-
|
420
|
-
expect(errors).to contain_exactly(
|
421
|
-
"Config[database][host] must be a String",
|
422
|
-
"Config[database][port] must be an Integer",
|
423
|
-
"Config[database][credentials][username] must be a String",
|
424
|
-
"Config[database][credentials][password] must be a String"
|
425
|
-
)
|
426
|
-
end
|
427
|
-
|
428
388
|
it "supports arrays inside hashes" do
|
429
389
|
schema.hash(:config) do
|
430
390
|
string :name
|
@@ -454,25 +414,6 @@ RSpec.describe Lluminary::Schema do
|
|
454
414
|
}
|
455
415
|
)
|
456
416
|
end
|
457
|
-
|
458
|
-
it "validates arrays inside hashes" do
|
459
|
-
schema.hash(:config) do
|
460
|
-
string :name
|
461
|
-
array :tags do
|
462
|
-
string
|
463
|
-
end
|
464
|
-
end
|
465
|
-
|
466
|
-
errors =
|
467
|
-
schema.validate(
|
468
|
-
config: {
|
469
|
-
name: "test",
|
470
|
-
tags: ["valid", 123, "also valid"] # second element should be string
|
471
|
-
}
|
472
|
-
)
|
473
|
-
|
474
|
-
expect(errors).to contain_exactly("Config[tags][1] must be a String")
|
475
|
-
end
|
476
417
|
end
|
477
418
|
|
478
419
|
describe "primitive types" do
|
@@ -509,136 +450,6 @@ RSpec.describe Lluminary::Schema do
|
|
509
450
|
second_call = schema.fields
|
510
451
|
expect(first_call).to be(second_call)
|
511
452
|
end
|
512
|
-
|
513
|
-
context "with datetime fields" do
|
514
|
-
let(:schema) { described_class.new.tap { |s| s.datetime(:start_time) } }
|
515
|
-
|
516
|
-
it "accepts DateTime values" do
|
517
|
-
errors = schema.validate(start_time: DateTime.now)
|
518
|
-
expect(errors).to be_empty
|
519
|
-
end
|
520
|
-
|
521
|
-
it "accepts nil values" do
|
522
|
-
errors = schema.validate(start_time: nil)
|
523
|
-
expect(errors).to be_empty
|
524
|
-
end
|
525
|
-
|
526
|
-
it "returns errors for non-DateTime values" do
|
527
|
-
errors = schema.validate(start_time: "2024-01-01")
|
528
|
-
expect(errors).to contain_exactly("Start time must be a DateTime")
|
529
|
-
end
|
530
|
-
|
531
|
-
it "can be required using presence validation" do
|
532
|
-
schema.validates :start_time, presence: true
|
533
|
-
errors = schema.validate(start_time: nil)
|
534
|
-
expect(errors).to contain_exactly("Start time can't be blank")
|
535
|
-
end
|
536
|
-
end
|
537
|
-
end
|
538
|
-
|
539
|
-
describe "#validate" do
|
540
|
-
let(:schema) do
|
541
|
-
described_class.new.tap do |s|
|
542
|
-
s.string(:name)
|
543
|
-
s.integer(:age)
|
544
|
-
end
|
545
|
-
end
|
546
|
-
|
547
|
-
it "returns no errors when all values match their field types" do
|
548
|
-
errors = schema.validate(name: "John", age: 30)
|
549
|
-
expect(errors).to be_empty
|
550
|
-
end
|
551
|
-
|
552
|
-
it "returns errors for type mismatches" do
|
553
|
-
errors = schema.validate(name: 123, age: "30")
|
554
|
-
expect(errors).to contain_exactly(
|
555
|
-
"Name must be a String",
|
556
|
-
"Age must be an Integer"
|
557
|
-
)
|
558
|
-
end
|
559
|
-
|
560
|
-
context "with boolean fields" do
|
561
|
-
let(:schema) { described_class.new.tap { |s| s.boolean(:active) } }
|
562
|
-
|
563
|
-
it "accepts true values" do
|
564
|
-
errors = schema.validate(active: true)
|
565
|
-
expect(errors).to be_empty
|
566
|
-
end
|
567
|
-
|
568
|
-
it "accepts false values" do
|
569
|
-
errors = schema.validate(active: false)
|
570
|
-
expect(errors).to be_empty
|
571
|
-
end
|
572
|
-
|
573
|
-
it "accepts nil values" do
|
574
|
-
errors = schema.validate(active: nil)
|
575
|
-
expect(errors).to be_empty
|
576
|
-
end
|
577
|
-
|
578
|
-
it "returns errors for non-boolean values" do
|
579
|
-
errors = schema.validate(active: "true")
|
580
|
-
expect(errors).to contain_exactly("Active must be true or false")
|
581
|
-
|
582
|
-
errors = schema.validate(active: 1)
|
583
|
-
expect(errors).to contain_exactly("Active must be true or false")
|
584
|
-
end
|
585
|
-
|
586
|
-
it "can be required using presence validation" do
|
587
|
-
schema.validates :active, presence: true
|
588
|
-
errors = schema.validate(active: nil)
|
589
|
-
expect(errors).to contain_exactly("Active can't be blank")
|
590
|
-
end
|
591
|
-
end
|
592
|
-
|
593
|
-
context "with string fields" do
|
594
|
-
let(:schema) { described_class.new.tap { |s| s.string(:name) } }
|
595
|
-
|
596
|
-
it "accepts string values" do
|
597
|
-
errors = schema.validate(name: "John")
|
598
|
-
expect(errors).to be_empty
|
599
|
-
end
|
600
|
-
|
601
|
-
it "accepts nil values" do
|
602
|
-
errors = schema.validate(name: nil)
|
603
|
-
expect(errors).to be_empty
|
604
|
-
end
|
605
|
-
|
606
|
-
it "returns errors for non-string values" do
|
607
|
-
errors = schema.validate(name: 123)
|
608
|
-
expect(errors).to contain_exactly("Name must be a String")
|
609
|
-
end
|
610
|
-
|
611
|
-
it "can be required using presence validation" do
|
612
|
-
schema.validates :name, presence: true
|
613
|
-
errors = schema.validate(name: nil)
|
614
|
-
expect(errors).to contain_exactly("Name can't be blank")
|
615
|
-
end
|
616
|
-
end
|
617
|
-
|
618
|
-
context "with integer fields" do
|
619
|
-
let(:schema) { described_class.new.tap { |s| s.integer(:age) } }
|
620
|
-
|
621
|
-
it "accepts integer values" do
|
622
|
-
errors = schema.validate(age: 30)
|
623
|
-
expect(errors).to be_empty
|
624
|
-
end
|
625
|
-
|
626
|
-
it "accepts nil values" do
|
627
|
-
errors = schema.validate(age: nil)
|
628
|
-
expect(errors).to be_empty
|
629
|
-
end
|
630
|
-
|
631
|
-
it "returns errors for non-integer values" do
|
632
|
-
errors = schema.validate(age: "30")
|
633
|
-
expect(errors).to contain_exactly("Age must be an Integer")
|
634
|
-
end
|
635
|
-
|
636
|
-
it "can be required using presence validation" do
|
637
|
-
schema.validates :age, presence: true
|
638
|
-
errors = schema.validate(age: nil)
|
639
|
-
expect(errors).to contain_exactly("Age can't be blank")
|
640
|
-
end
|
641
|
-
end
|
642
453
|
end
|
643
454
|
|
644
455
|
describe "ActiveModel validations" do
|
@@ -688,4 +499,32 @@ RSpec.describe Lluminary::Schema do
|
|
688
499
|
expect(instance.valid?).to be true
|
689
500
|
end
|
690
501
|
end
|
502
|
+
|
503
|
+
describe "custom method validations" do
|
504
|
+
it "passes custom validations to schema model" do
|
505
|
+
schema = described_class.new
|
506
|
+
schema.integer(:score)
|
507
|
+
schema.validate(:validate_score_range)
|
508
|
+
|
509
|
+
model_class = schema.schema_model
|
510
|
+
method_names =
|
511
|
+
model_class.custom_validation_methods.map { |v| v[:method] }
|
512
|
+
expect(method_names).to contain_exactly(:validate_score_range)
|
513
|
+
end
|
514
|
+
|
515
|
+
it "accepts multiple custom validations" do
|
516
|
+
schema = described_class.new
|
517
|
+
schema.integer(:score)
|
518
|
+
schema.validate(:validate_score_range)
|
519
|
+
schema.validate(:validate_score_parity)
|
520
|
+
|
521
|
+
model_class = schema.schema_model
|
522
|
+
method_names =
|
523
|
+
model_class.custom_validation_methods.map { |v| v[:method] }
|
524
|
+
expect(method_names).to contain_exactly(
|
525
|
+
:validate_score_range,
|
526
|
+
:validate_score_parity
|
527
|
+
)
|
528
|
+
end
|
529
|
+
end
|
691
530
|
end
|