trafaret 1.1.0 → 1.5.1
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/trafaret.rb +43 -22
- data/lib/trafaret/base.rb +63 -37
- data/lib/trafaret/constructor.rb +39 -0
- data/lib/trafaret/errors.rb +4 -0
- data/lib/trafaret/numeric.rb +45 -0
- data/lib/trafaret/validator.rb +31 -3
- data/lib/trafaret/validators.rb +102 -6
- data/lib/trafaret/version.rb +1 -1
- data/spec/trafaret_spec.rb +100 -19
- metadata +12 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3da287d80b08ce05b13b14cc3a273319a73dd20
|
4
|
+
data.tar.gz: 8dbec245e7f84988b0c6686182b7039ac4fb5e72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dece3132f430f9f0bf9a7d70fc903033bbacd78566bf7eb4465ea3fe4fdc8aeef89d46888102810e8a865810837c08ff71e58a91857e8e481edae9f33249f722
|
7
|
+
data.tar.gz: 2d639254921bca95796de8d776b54bc713d637a5076b85643a5eb70c81442a8104c86894c35e29ac5470b3c9ae2894bd6429cf9812e7a1465ccf335890a13937
|
data/lib/trafaret.rb
CHANGED
@@ -3,35 +3,56 @@ require 'trafaret/version'
|
|
3
3
|
require 'trafaret/errors'
|
4
4
|
require 'trafaret/validator'
|
5
5
|
require 'trafaret/validators'
|
6
|
+
require 'trafaret/numeric'
|
6
7
|
require 'trafaret/base'
|
8
|
+
require 'trafaret/constructor'
|
7
9
|
|
8
10
|
module Trafaret
|
9
|
-
|
10
|
-
if validator.is_a? Symbol
|
11
|
-
class_name = validator.to_s.classify
|
12
|
-
validator = Trafaret.const_get(class_name) rescue nil
|
13
|
-
validator ||= Kernel.const_get(class_name)
|
14
|
-
else
|
15
|
-
validator
|
16
|
-
end
|
11
|
+
module NoValue
|
17
12
|
end
|
18
13
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
14
|
+
class << self
|
15
|
+
def get_validator(validator)
|
16
|
+
if validator.is_a? ::Symbol
|
17
|
+
class_name = validator.to_s.classify
|
18
|
+
validator = Trafaret.const_get(class_name) rescue nil
|
19
|
+
validator ||= Kernel.const_get(class_name)
|
20
|
+
else
|
21
|
+
validator
|
22
|
+
end
|
23
|
+
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
def get_instantiated_validator(validator, options = {})
|
26
|
+
val = self.get_validator(validator)
|
27
|
+
val = val.new(options) if val.is_a? Class
|
28
|
+
val
|
29
|
+
end
|
30
|
+
|
31
|
+
def [](validator, options = {})
|
32
|
+
return self.get_instantiated_validator(validator, options)
|
33
|
+
end
|
28
34
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
+
def method_missing(meth, *args, &blk)
|
36
|
+
cls = self.get_validator(meth)
|
37
|
+
if cls
|
38
|
+
cls.new(*args, &blk)
|
39
|
+
else
|
40
|
+
super
|
41
|
+
end
|
35
42
|
end
|
43
|
+
|
44
|
+
def proc(*args, &blk)
|
45
|
+
Trafaret::Proc.new *args, &blk
|
46
|
+
end
|
47
|
+
|
48
|
+
def failure(msg)
|
49
|
+
Trafaret::Error.new msg
|
50
|
+
end
|
51
|
+
|
52
|
+
def construct(from)
|
53
|
+
Trafaret::Constructor.construct_from(from)
|
54
|
+
end
|
55
|
+
|
56
|
+
alias :f :failure
|
36
57
|
end
|
37
58
|
end
|
data/lib/trafaret/base.rb
CHANGED
@@ -2,69 +2,95 @@ module Trafaret
|
|
2
2
|
class Key
|
3
3
|
def initialize(name, validator, options = {}, &blk)
|
4
4
|
@name = name
|
5
|
-
@
|
5
|
+
@sname = name.to_s
|
6
|
+
|
7
|
+
@optional = options.delete(:optional)
|
8
|
+
@default = options.delete(:default)
|
9
|
+
@to_name = options.delete(:to_name) || name
|
6
10
|
@options = options
|
7
|
-
@blk = blk
|
8
|
-
end
|
9
11
|
|
10
|
-
|
11
|
-
return @blk.call obj if @blk
|
12
|
-
data = begin
|
13
|
-
extractors[@name].call(obj) if extractors[@name]
|
14
|
-
rescue NoMethodError
|
15
|
-
nil
|
16
|
-
end
|
17
|
-
data ||= begin
|
18
|
-
obj.send(@name)
|
19
|
-
rescue NameError
|
20
|
-
nil
|
21
|
-
end
|
22
|
-
data ||= begin
|
23
|
-
obj[@name] || obj[@name.to_s]
|
24
|
-
rescue NoMethodError, TypeError
|
25
|
-
nil
|
26
|
-
end
|
12
|
+
set_validator(validator, options, &blk)
|
27
13
|
end
|
28
14
|
|
29
|
-
def
|
30
|
-
|
15
|
+
def set_validator(validator, options = {}, &blk)
|
16
|
+
validator = Trafaret.get_validator(validator)
|
17
|
+
@validator = if validator.is_a?(Class) then validator.new(options) else validator end
|
18
|
+
@validator.add(blk) if blk
|
31
19
|
end
|
32
|
-
end
|
33
20
|
|
34
|
-
|
35
|
-
|
36
|
-
|
21
|
+
def get(obj)
|
22
|
+
# data = obj.send(@name) if data.respond_to? @name
|
23
|
+
if obj.include? @name
|
24
|
+
obj[@name]
|
25
|
+
elsif obj.include? @sname
|
26
|
+
obj[@sname]
|
27
|
+
else
|
28
|
+
NoValue
|
29
|
+
end
|
37
30
|
end
|
38
31
|
|
39
32
|
def call(data)
|
40
|
-
|
33
|
+
value = get(data)
|
34
|
+
if value == NoValue
|
35
|
+
if @default
|
36
|
+
value = @default
|
37
|
+
elsif @optional
|
38
|
+
return
|
39
|
+
else
|
40
|
+
return [@name, Trafaret::Error.new("#{@name} is required")]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
value = @validator.call(value, &@blk)
|
44
|
+
if value.is_a? Trafaret::Error
|
45
|
+
[@name, value]
|
46
|
+
else
|
47
|
+
[@to_name, value]
|
48
|
+
end
|
41
49
|
end
|
42
50
|
end
|
43
51
|
|
44
52
|
class Base < Validator
|
45
53
|
module ClassMethods
|
46
|
-
attr_accessor :keys
|
54
|
+
attr_accessor :keys
|
47
55
|
def inherited(base)
|
48
56
|
base.keys = (keys || []).dup
|
49
|
-
base.extractors = (extractors || {}).dup
|
50
57
|
end
|
51
58
|
|
52
59
|
def key(name, validator, options = {}, &blk)
|
53
|
-
@keys << Key.new(name,
|
54
|
-
end
|
55
|
-
|
56
|
-
def extract(name, &blk)
|
57
|
-
@extractors[name] = Extractor.new(&blk)
|
60
|
+
@keys << Key.new(name, validator, options, &blk)
|
58
61
|
end
|
59
62
|
end
|
60
63
|
extend ClassMethods
|
61
64
|
|
65
|
+
attr_accessor :keys
|
66
|
+
|
67
|
+
def prepare
|
68
|
+
@keys = @options[:keys] || []
|
69
|
+
@keys.concat(self.class.keys || [])
|
70
|
+
end
|
71
|
+
|
72
|
+
def key(name, validator, options = {}, &blk)
|
73
|
+
@keys << Key.new(name, validator, options, &blk)
|
74
|
+
end
|
75
|
+
|
62
76
|
def validate(data)
|
77
|
+
return failure('Not a Hash') unless data.is_a?(::Hash)
|
63
78
|
res = []
|
64
|
-
|
65
|
-
|
79
|
+
fails = []
|
80
|
+
@keys.each do |key|
|
81
|
+
vdata = key.call(data)
|
82
|
+
next unless vdata
|
83
|
+
if vdata[1].is_a? Trafaret::Error
|
84
|
+
fails << vdata
|
85
|
+
else
|
86
|
+
res << vdata
|
87
|
+
end
|
88
|
+
end
|
89
|
+
if fails.blank?
|
90
|
+
Hash[res]
|
91
|
+
else
|
92
|
+
failure(Hash[fails])
|
66
93
|
end
|
67
|
-
Hash[res]
|
68
94
|
end
|
69
95
|
end
|
70
96
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Trafaret
|
2
|
+
class Constructor
|
3
|
+
class << self
|
4
|
+
def construct_from(from)
|
5
|
+
case from
|
6
|
+
when ::Hash
|
7
|
+
from_hash(from)
|
8
|
+
when ::Array
|
9
|
+
from_array(from)
|
10
|
+
when ::Symbol
|
11
|
+
Trafaret.get_validator from
|
12
|
+
when Trafaret::Validator
|
13
|
+
from
|
14
|
+
else
|
15
|
+
raise 'Wrong parameter'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def from_hash(params)
|
20
|
+
keys = []
|
21
|
+
params.each do |k, v|
|
22
|
+
v = Trafaret::Constructor.construct_from v
|
23
|
+
if k.is_a? ::Symbol
|
24
|
+
keys << Key.new(k, v)
|
25
|
+
elsif k.is_a? Trafaret::Key
|
26
|
+
k.set_validator(v)
|
27
|
+
keys << k
|
28
|
+
end
|
29
|
+
end
|
30
|
+
Trafaret::Base.new keys: keys
|
31
|
+
end
|
32
|
+
|
33
|
+
def from_array(params)
|
34
|
+
raise 'Wrong argument for array construction' if params.size != 1
|
35
|
+
Trafaret::Array.new validator: Trafaret::Constructor.construct_from(params[0])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/trafaret/errors.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Trafaret
|
2
|
+
class Numeric < Validator
|
3
|
+
UNDEFINED = 'Undefined'.freeze
|
4
|
+
INTEGER = 'Integer'.freeze
|
5
|
+
FLOAT = 'Float'.freeze
|
6
|
+
|
7
|
+
def try_convert(arg)
|
8
|
+
raise 'type method need to be implemented'
|
9
|
+
end
|
10
|
+
|
11
|
+
def num_class_name
|
12
|
+
UNDEFINED
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate(data)
|
16
|
+
val = try_convert(data)
|
17
|
+
return failure("Not an #{num_class_name}") unless val
|
18
|
+
return failure('Too big') if @options[:lt] && val >= @options[:lt]
|
19
|
+
return failure('Too big') if @options[:lte] && val > @options[:lte]
|
20
|
+
return failure('Too small') if @options[:gt] && val <= @options[:gt]
|
21
|
+
return failure('Too small') if @options[:gte] && val < @options[:gte]
|
22
|
+
data
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Integer < Numeric
|
27
|
+
def try_convert(arg)
|
28
|
+
Integer(arg) rescue nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def num_class_name
|
32
|
+
INTEGER
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Float < Numeric
|
37
|
+
def try_convert(arg)
|
38
|
+
Float(arg) rescue nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def num_class_name
|
42
|
+
FLOAT
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/trafaret/validator.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
class Trafaret::Validator
|
2
|
-
def initialize(
|
3
|
-
@options =
|
2
|
+
def initialize(*args, &blk)
|
3
|
+
@options = (args.pop if args.last.is_a? Hash) || {}
|
4
|
+
@args = args
|
5
|
+
@converters = []
|
6
|
+
@converters << blk if blk
|
7
|
+
|
8
|
+
prepare
|
9
|
+
end
|
10
|
+
|
11
|
+
def prepare
|
4
12
|
end
|
5
13
|
|
6
14
|
def validate(data)
|
@@ -11,21 +19,41 @@ class Trafaret::Validator
|
|
11
19
|
data
|
12
20
|
end
|
13
21
|
|
22
|
+
def perform_convert(data)
|
23
|
+
if @converters.blank?
|
24
|
+
convert(data)
|
25
|
+
else
|
26
|
+
@converters.each do |c|
|
27
|
+
data = c.call(data)
|
28
|
+
break if data.is_a? Trafaret::Error
|
29
|
+
end
|
30
|
+
data
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
14
34
|
def call(data)
|
15
35
|
val = validate(data)
|
16
36
|
return val if val.is_a? Trafaret::Error
|
17
37
|
if block_given?
|
18
38
|
yield val
|
19
39
|
else
|
20
|
-
|
40
|
+
perform_convert(val)
|
21
41
|
end
|
22
42
|
end
|
23
43
|
|
44
|
+
def add(blk)
|
45
|
+
@converters << blk
|
46
|
+
end
|
47
|
+
|
24
48
|
# ADT
|
25
49
|
def |(other)
|
26
50
|
Trafaret::Or.new(self, other)
|
27
51
|
end
|
28
52
|
|
53
|
+
def &(other)
|
54
|
+
Trafaret::Chain.new(self, other)
|
55
|
+
end
|
56
|
+
|
29
57
|
# Helpers
|
30
58
|
def failure(msg)
|
31
59
|
Trafaret::Error.new msg
|
data/lib/trafaret/validators.rb
CHANGED
@@ -2,14 +2,16 @@ module Trafaret
|
|
2
2
|
class Any < Validator
|
3
3
|
end
|
4
4
|
|
5
|
-
class
|
5
|
+
class ADT < Validator
|
6
6
|
attr_reader :validators
|
7
7
|
|
8
8
|
def initialize(*args)
|
9
9
|
args = args.first if args.first.is_a? ::Array
|
10
10
|
@validators = args.map { |v| Trafaret.get_instantiated_validator(v) }
|
11
11
|
end
|
12
|
+
end
|
12
13
|
|
14
|
+
class Or < ADT
|
13
15
|
def validate(data)
|
14
16
|
errors = []
|
15
17
|
@validators.each do |v|
|
@@ -28,6 +30,26 @@ module Trafaret
|
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
33
|
+
class Chain < ADT
|
34
|
+
def validate(data)
|
35
|
+
@validators.each do |v|
|
36
|
+
data = v.call(data)
|
37
|
+
return data if data.is_a? Trafaret::Error
|
38
|
+
end
|
39
|
+
data
|
40
|
+
end
|
41
|
+
|
42
|
+
def &(other)
|
43
|
+
Trafaret::Chain.new(*validators, other)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Nil < Validator
|
48
|
+
def validate(data)
|
49
|
+
failure('Value must be nil') unless data.nil?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
31
53
|
class String < Validator
|
32
54
|
def validate(data)
|
33
55
|
return failure('Not a String') unless data.is_a? ::String
|
@@ -41,25 +63,99 @@ module Trafaret
|
|
41
63
|
end
|
42
64
|
data
|
43
65
|
end
|
66
|
+
|
67
|
+
def convert(data)
|
68
|
+
if data.is_a? MatchData
|
69
|
+
data.string
|
70
|
+
else
|
71
|
+
data
|
72
|
+
end
|
73
|
+
end
|
44
74
|
end
|
45
75
|
|
46
|
-
class
|
76
|
+
class Symbol < Validator
|
77
|
+
def prepare
|
78
|
+
@sym = @args.first.to_sym
|
79
|
+
@str = @args.first.to_s.freeze
|
80
|
+
end
|
81
|
+
|
47
82
|
def validate(data)
|
48
|
-
data
|
83
|
+
case data
|
84
|
+
when ::String
|
85
|
+
@str == data ? @sym : failure('Not equal')
|
86
|
+
when ::Symbol
|
87
|
+
@sym == data ? @sym : failure('Not equal')
|
88
|
+
else
|
89
|
+
failure('Not a String or a Symbol')
|
90
|
+
end
|
49
91
|
end
|
50
92
|
end
|
51
93
|
|
52
94
|
class Array < Validator
|
95
|
+
def prepare
|
96
|
+
val = Trafaret.get_validator(@options[:validator])
|
97
|
+
if val.is_a? ::Class
|
98
|
+
@cls = Trafaret.get_validator(@options[:validator]).new @options
|
99
|
+
else
|
100
|
+
@cls = val
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
53
104
|
def self.[](validator, options = {})
|
54
105
|
self.new(options.merge(validator: validator))
|
55
106
|
end
|
56
107
|
|
57
108
|
def validate(data)
|
58
109
|
return failure('Not an Array') unless data.is_a? ::Array
|
59
|
-
|
60
|
-
data.map do |elem|
|
61
|
-
cls.call elem
|
110
|
+
fails = {}
|
111
|
+
res = data.map.with_index do |elem, index|
|
112
|
+
val = @cls.call elem
|
113
|
+
fails[index] = val if val.is_a? Trafaret::Error
|
114
|
+
val
|
115
|
+
end
|
116
|
+
if fails.blank?
|
117
|
+
return res
|
118
|
+
else
|
119
|
+
return failure(fails)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class Mapping < Validator
|
125
|
+
def prepare
|
126
|
+
@key_validator = @args.first
|
127
|
+
@value_validator = @args[1]
|
128
|
+
end
|
129
|
+
|
130
|
+
def validate(data)
|
131
|
+
return failure('Not a Hash') unless data.is_a? ::Hash
|
132
|
+
fails = []
|
133
|
+
pairs = []
|
134
|
+
data.each do |k, v|
|
135
|
+
kv = @key_validator.call(k)
|
136
|
+
vv = @value_validator.call(v)
|
137
|
+
if (kv.is_a? Trafaret::Error) || (vv.is_a? Trafaret::Error)
|
138
|
+
fails << [k, [kv, vv]]
|
139
|
+
else
|
140
|
+
pairs << [kv, vv]
|
141
|
+
end
|
62
142
|
end
|
143
|
+
if fails.blank?
|
144
|
+
Hash[pairs]
|
145
|
+
else
|
146
|
+
failure(Hash[fails])
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
class Proc < Validator
|
152
|
+
def prepare
|
153
|
+
raise 'Need to call with block' if @converters.blank?
|
154
|
+
@blk = @converters.pop
|
155
|
+
end
|
156
|
+
|
157
|
+
def validate(data)
|
158
|
+
@blk.call(data)
|
63
159
|
end
|
64
160
|
end
|
65
161
|
end
|
data/lib/trafaret/version.rb
CHANGED
data/spec/trafaret_spec.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
require 'trafaret'
|
3
3
|
|
4
|
-
|
5
|
-
key :url, Trafaret::String, min_length: 3, max_length: 50
|
6
|
-
end
|
4
|
+
T = Trafaret
|
7
5
|
|
8
6
|
class FacebookResponseTrafaret < Trafaret::Base
|
9
|
-
key :name, :
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
key :name, T.string(min_length: 2), optional: true
|
8
|
+
key :oa, T.mapping(T.string,
|
9
|
+
T.mapping(T.string,
|
10
|
+
T.base(keys: [T.key(:url, T.string)])
|
11
|
+
)
|
12
|
+
), to_name: :providers do |data| # so we have response that matches our assumptions, then we can convert it
|
13
|
+
data.flat_map { |p_n, accs| accs.map { |uuid, data| data } }
|
14
14
|
end
|
15
|
-
key :
|
15
|
+
key :dwarf, :string, default: 'Sniffer'
|
16
|
+
key :optional_key, :string, optional: true
|
16
17
|
end
|
17
18
|
|
18
19
|
describe Trafaret::Base do
|
@@ -27,35 +28,115 @@ describe Trafaret::Base do
|
|
27
28
|
}
|
28
29
|
end
|
29
30
|
it 'should work' do
|
30
|
-
FacebookResponseTrafaret.new.call(raw).should == ({name: "kuku", providers: [{url: "http://ya.ru"}, {url: "http://www.ru"}]})
|
31
|
+
FacebookResponseTrafaret.new.call(raw).should == ({name: "kuku", providers: [{url: "http://ya.ru"}, {url: "http://www.ru"}], dwarf: 'Sniffer'})
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should work with hash' do
|
35
|
+
t = T.construct({
|
36
|
+
kuku: :integer,
|
37
|
+
T.key(:krkr, nil, to_name: :id) => :string,
|
38
|
+
argh: {
|
39
|
+
karma: :integer
|
40
|
+
},
|
41
|
+
arr: [{id: :integer}]
|
42
|
+
})
|
43
|
+
res = t.call({kuku: 123, krkr: 'karma', argh: {karma: 234}, arr: [{id: 123}, {id: 234}]})
|
44
|
+
res[:id].should == 'karma'
|
45
|
+
res[:argh][:karma].should == 234
|
31
46
|
end
|
32
47
|
end
|
33
48
|
|
34
49
|
describe Trafaret::String do
|
35
50
|
it 'should check errors' do
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
51
|
+
T.string.call('').message.should == 'Should not be blank'
|
52
|
+
T.string(min_length: 10).call('abc').message.should == 'Too short'
|
53
|
+
T.string(max_length: 1).call('abc').message.should == 'Too long'
|
54
|
+
T.string(regex: /abc/).call('bca').message.should == 'Does not match'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe Trafaret::Integer do
|
59
|
+
it 'should check errors' do
|
60
|
+
T.integer.call('blabla').message.should == 'Not an Integer'
|
61
|
+
T.integer(lt: 5).call(5).message.should == 'Too big'
|
62
|
+
T.integer(lte: 5).call(6).message.should == 'Too big'
|
63
|
+
T.integer(gt: 5).call(5).message.should == 'Too small'
|
64
|
+
T.integer(gte: 5).call(4).message.should == 'Too small'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe Trafaret::Validator do
|
69
|
+
it 'should work with block' do
|
70
|
+
blk = proc { |data| if data.present? then data else T::Error.new('Empty data') end }
|
71
|
+
T::Validator.new(&blk).call('argh').should == 'argh'
|
72
|
+
T::Validator.new(&blk).call('').message.should == 'Empty data'
|
73
|
+
T.proc(&blk).call('').message.should == 'Empty data'
|
40
74
|
end
|
41
75
|
end
|
42
76
|
|
43
77
|
describe Trafaret::Array do
|
44
78
|
it 'should check' do
|
45
|
-
|
79
|
+
T::Array[:string].call(['a', 'b', 'c']).should == ['a', 'b', 'c']
|
80
|
+
T::Array[:string].call(['a', 'b', nil]).should.is_a? Trafaret::Error
|
46
81
|
end
|
47
82
|
end
|
48
83
|
|
49
84
|
describe Trafaret::Or do
|
50
85
|
it 'should return value' do
|
51
|
-
|
86
|
+
T[:or, [:string, :integer]].call('krukatuka').should == 'krukatuka'
|
52
87
|
|
53
|
-
(
|
88
|
+
(T[:string] | T[:integer]).call('krukatuka').should == 'krukatuka'
|
54
89
|
|
55
|
-
(
|
90
|
+
(T.string | T.integer).call('krukatuka').should == 'krukatuka'
|
56
91
|
end
|
57
92
|
|
58
93
|
it 'should return errors' do
|
59
|
-
|
94
|
+
T[:or, T[:array, validator: :string]].call('krukatuka').message.first.message.should == 'Not an Array'
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should properly chained' do
|
98
|
+
(T.string(min_length: 100) | T.integer | T.string(regex: /aaa/)).call('aaa').should == 'aaa'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe Trafaret::Chain do
|
103
|
+
it 'should work with callables' do
|
104
|
+
trafaret = T.integer & proc { |d| d == 123? d : T.f('not equal') }
|
105
|
+
trafaret.call(123).should == 123
|
106
|
+
trafaret.call(321).message.should == 'not equal'
|
107
|
+
trafaret = T.integer & proc { |d| d }
|
108
|
+
trafaret.call('abc').message.should == 'Not an Integer'
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
describe Trafaret::Key do
|
114
|
+
it 'should extract and check value' do
|
115
|
+
T.key(:name, :string).call({name: 'cow'}).should == [:name, 'cow']
|
116
|
+
T.key(:name, :string, default: 'Elephant').call({}).should == [:name, 'Elephant']
|
117
|
+
T.key(:name, :string, optional: true).call({}).should == nil
|
118
|
+
# to name test
|
119
|
+
T.key(:name, :string, to_name: :id).call({name: '123'}).should == [:id, '123']
|
120
|
+
T.key(:name, :string, to_name: :id).call({name: 123})[0].should == :name
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe Trafaret::Symbol do
|
125
|
+
it 'should check equality' do
|
126
|
+
T.symbol(:name).call('name').should == :name
|
127
|
+
T.symbol(:name).call(:name).should == :name
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should fail' do
|
131
|
+
T.symbol(:name).call('pame').message.should == 'Not equal'
|
132
|
+
T.symbol(:name).call(123).message.should == 'Not a String or a Symbol'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe Trafaret::Nil do
|
137
|
+
it 'should check for nil' do
|
138
|
+
n = T::Nil.new
|
139
|
+
n.call(123).message.should == 'Value must be nil'
|
140
|
+
n.call(nil).should == nil
|
60
141
|
end
|
61
142
|
end
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trafaret
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1
|
4
|
+
version: 1.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mikhail Krivushin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.5'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
description: |-
|
@@ -47,14 +47,16 @@ executables: []
|
|
47
47
|
extensions: []
|
48
48
|
extra_rdoc_files: []
|
49
49
|
files:
|
50
|
-
- .gitignore
|
50
|
+
- ".gitignore"
|
51
51
|
- Gemfile
|
52
52
|
- LICENSE.txt
|
53
53
|
- README.md
|
54
54
|
- Rakefile
|
55
55
|
- lib/trafaret.rb
|
56
56
|
- lib/trafaret/base.rb
|
57
|
+
- lib/trafaret/constructor.rb
|
57
58
|
- lib/trafaret/errors.rb
|
59
|
+
- lib/trafaret/numeric.rb
|
58
60
|
- lib/trafaret/validator.rb
|
59
61
|
- lib/trafaret/validators.rb
|
60
62
|
- lib/trafaret/version.rb
|
@@ -70,17 +72,17 @@ require_paths:
|
|
70
72
|
- lib
|
71
73
|
required_ruby_version: !ruby/object:Gem::Requirement
|
72
74
|
requirements:
|
73
|
-
- -
|
75
|
+
- - ">="
|
74
76
|
- !ruby/object:Gem::Version
|
75
77
|
version: '0'
|
76
78
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
79
|
requirements:
|
78
|
-
- -
|
80
|
+
- - ">="
|
79
81
|
- !ruby/object:Gem::Version
|
80
82
|
version: '0'
|
81
83
|
requirements: []
|
82
84
|
rubyforge_project:
|
83
|
-
rubygems_version: 2.
|
85
|
+
rubygems_version: 2.2.2
|
84
86
|
signing_key:
|
85
87
|
specification_version: 4
|
86
88
|
summary: Convert data structures. Like a RABL.
|