data_model 0.4.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -2
- data/.solargraph.yml +22 -0
- data/Gemfile.lock +71 -29
- data/Rakefile +0 -6
- data/Steepfile +27 -0
- data/data_model.gemspec +1 -2
- data/lib/data_model/boolean.rb +0 -2
- data/lib/data_model/builtin/array.rb +32 -25
- data/lib/data_model/builtin/big_decimal.rb +15 -14
- data/lib/data_model/builtin/boolean.rb +10 -7
- data/lib/data_model/builtin/date.rb +15 -12
- data/lib/data_model/builtin/float.rb +14 -13
- data/lib/data_model/builtin/hash.rb +109 -36
- data/lib/data_model/builtin/integer.rb +14 -13
- data/lib/data_model/builtin/numeric.rb +35 -0
- data/lib/data_model/builtin/object.rb +28 -0
- data/lib/data_model/builtin/or.rb +73 -0
- data/lib/data_model/builtin/string.rb +15 -16
- data/lib/data_model/builtin/symbol.rb +14 -13
- data/lib/data_model/builtin/time.rb +17 -14
- data/lib/data_model/builtin.rb +9 -9
- data/lib/data_model/error.rb +30 -18
- data/lib/data_model/errors.rb +79 -55
- data/lib/data_model/fixtures/array.rb +22 -9
- data/lib/data_model/fixtures/big_decimal.rb +9 -7
- data/lib/data_model/fixtures/boolean.rb +5 -5
- data/lib/data_model/fixtures/date.rb +13 -11
- data/lib/data_model/fixtures/example.rb +7 -7
- data/lib/data_model/fixtures/float.rb +9 -7
- data/lib/data_model/fixtures/hash.rb +22 -10
- data/lib/data_model/fixtures/integer.rb +9 -7
- data/lib/data_model/fixtures/numeric.rb +31 -0
- data/lib/data_model/fixtures/object.rb +27 -0
- data/lib/data_model/fixtures/or.rb +29 -0
- data/lib/data_model/fixtures/string.rb +15 -32
- data/lib/data_model/fixtures/symbol.rb +9 -7
- data/lib/data_model/fixtures/time.rb +13 -11
- data/lib/data_model/logging.rb +5 -8
- data/lib/data_model/model.rb +11 -8
- data/lib/data_model/registry.rb +37 -22
- data/lib/data_model/scanner.rb +23 -28
- data/lib/data_model/struct.rb +116 -0
- data/lib/data_model/testing/minitest.rb +33 -9
- data/lib/data_model/testing.rb +0 -2
- data/lib/data_model/type.rb +38 -22
- data/lib/data_model/version.rb +1 -3
- data/lib/data_model.rb +8 -17
- metadata +13 -26
- data/sorbet/config +0 -4
- data/sorbet/rbi/annotations/rainbow.rbi +0 -269
- data/sorbet/rbi/gems/minitest@5.18.0.rbi +0 -1491
- data/sorbet/rbi/gems/zeitwerk.rbi +0 -196
- data/sorbet/rbi/gems/zeitwerk@2.6.7.rbi +0 -966
- data/sorbet/rbi/todo.rbi +0 -5
- data/sorbet/tapioca/config.yml +0 -13
- data/sorbet/tapioca/require.rb +0 -4
data/lib/data_model/error.rb
CHANGED
@@ -1,34 +1,37 @@
|
|
1
|
-
# typed: strict
|
2
|
-
|
3
1
|
module DataModel
|
4
|
-
# Error is a class that holds errors.
|
2
|
+
# Error is a class that holds errors. Errors are a tuple of [name, ctx]
|
3
|
+
# - name is a symbol that identifies the error
|
4
|
+
# - ctx is contextual information about the error which can be used to build an error message
|
5
|
+
#
|
6
|
+
# The error object is a structured way to store, modify, and add errors in that intermediary format.
|
7
|
+
# To turn an error into a human readable message, use #to_messages, which delegates to a registry
|
8
|
+
#
|
9
|
+
# Base errors are errors that are related to the object as a whole, and not to any specific child
|
10
|
+
# Child errors are errors that are related to a specific child of the object, which may or may not apply depending on the type
|
5
11
|
class Error
|
6
|
-
extend T::Sig
|
7
12
|
include Errors
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
sig { void }
|
14
|
+
# Create a new error Object
|
15
|
+
# @return [Error] the new error object
|
13
16
|
def initialize
|
14
|
-
@base =
|
15
|
-
@children =
|
17
|
+
@base = []
|
18
|
+
@children = {}
|
16
19
|
end
|
17
20
|
|
18
21
|
# errors related to the object as a whole
|
19
|
-
|
22
|
+
# @return [Array<Array(Symbol, untyped)>] the base errors
|
20
23
|
def base
|
21
24
|
return @base
|
22
25
|
end
|
23
26
|
|
24
27
|
# errors related children
|
25
|
-
|
28
|
+
# @return [Hash{Symbol => Array<Array(Symbol, untyped)>}] the child errors
|
26
29
|
def children
|
27
30
|
return @children
|
28
31
|
end
|
29
32
|
|
30
33
|
# all errors
|
31
|
-
|
34
|
+
# @return [Hash{Symbol => Array<Array(Symbol, untyped)>}] all errors
|
32
35
|
def all
|
33
36
|
return children.merge(base:)
|
34
37
|
end
|
@@ -36,7 +39,8 @@ module DataModel
|
|
36
39
|
alias to_h all
|
37
40
|
|
38
41
|
# Returns true if any errors are present.
|
39
|
-
|
42
|
+
# @param blk [Proc] an optional block to filter errors, takes an Array(Symbol, untyped) and returns boolean
|
43
|
+
# @return [Boolean] true if any errors are present
|
40
44
|
def any?(&blk)
|
41
45
|
if !blk
|
42
46
|
return !@base.empty? || !@children.empty?
|
@@ -54,13 +58,16 @@ module DataModel
|
|
54
58
|
return any
|
55
59
|
end
|
56
60
|
|
57
|
-
|
61
|
+
# Returns true if no errors are present.
|
62
|
+
# @return [Boolean] true if no errors are present
|
58
63
|
def empty?
|
59
64
|
!any?
|
60
65
|
end
|
61
66
|
|
62
67
|
# Add an error to the error list.
|
63
|
-
|
68
|
+
# @param err [Array(Symbol, untyped)] the error to add
|
69
|
+
# @param child [Symbol, Array(Symbol)] the child to add the error to. child can be an array of symbols to specify a path if nested
|
70
|
+
# @return [void]
|
64
71
|
def add(err, child: nil)
|
65
72
|
if child.is_a?(Array)
|
66
73
|
child = child.join(".").to_sym
|
@@ -74,7 +81,10 @@ module DataModel
|
|
74
81
|
errs.push(err)
|
75
82
|
end
|
76
83
|
|
77
|
-
|
84
|
+
# Merge another error object into this one for child Errors
|
85
|
+
# @param name [Symbol] the name of the child
|
86
|
+
# @param child [Error] the child error object
|
87
|
+
# @return [void]
|
78
88
|
def merge_child(name, child)
|
79
89
|
if !child.any?
|
80
90
|
return
|
@@ -87,7 +97,9 @@ module DataModel
|
|
87
97
|
end
|
88
98
|
end
|
89
99
|
|
90
|
-
|
100
|
+
# Get human readable error messages from error tuples
|
101
|
+
# @param registry [Registry] the registry to use to get error messages
|
102
|
+
# @return [Hash{Symbol => Array[String]}] the error messages
|
91
103
|
def to_messages(registry: Registry.instance)
|
92
104
|
return registry.error_messages(self)
|
93
105
|
end
|
data/lib/data_model/errors.rb
CHANGED
@@ -1,84 +1,96 @@
|
|
1
|
-
# typed: strict
|
2
|
-
|
3
1
|
module DataModel
|
4
2
|
# Provide Error building functionality as a mixin
|
5
3
|
module Errors
|
6
|
-
include Kernel
|
7
|
-
extend T::Sig
|
8
4
|
extend self
|
9
5
|
|
10
|
-
TTemporal = T.type_alias { T.any(::Date, ::Time, ::DateTime) }
|
11
|
-
|
12
6
|
## Constructors
|
13
7
|
|
14
8
|
# Type error applies when a value is not of the expected type
|
15
|
-
|
9
|
+
# @param cls [String, Array(String)] the expected class
|
10
|
+
# @param value [Object] the value that failed
|
11
|
+
# @return [Array(Symbol, untyped)] the error
|
16
12
|
def type_error(cls, value)
|
17
13
|
[:type, [cls, value]]
|
18
14
|
end
|
19
15
|
|
20
16
|
# Coerce error applies when a value cannot be coerced to the expected type
|
21
|
-
|
17
|
+
# @param cls [String] the expected class
|
18
|
+
# @param value [Object] the value that failed
|
19
|
+
# @return [Array(Symbol, untyped)] the error
|
22
20
|
def coerce_error(cls, value)
|
23
21
|
[:coerce, [cls, value]]
|
24
22
|
end
|
25
23
|
|
26
24
|
# Missing error applies when a value is missing
|
27
|
-
|
25
|
+
# @param cls [String, Array<String>] the expected class
|
26
|
+
# @return [Array(Symbol, untyped)] the error
|
28
27
|
def missing_error(cls)
|
29
28
|
[:missing, cls]
|
30
29
|
end
|
31
30
|
|
32
31
|
# Inclusion error applies when a value is not in a set of allowed values
|
33
|
-
|
32
|
+
# @param set [Array<Symbol, String>] the set of allowed values
|
33
|
+
# @return [Array(Symbol, untyped)] the error
|
34
34
|
def inclusion_error(set)
|
35
35
|
[:inclusion, set]
|
36
36
|
end
|
37
37
|
|
38
38
|
# Exclusive error applies when a value is in a set of disallowed values
|
39
|
-
|
39
|
+
# @param set [Array<Symbol, String>] the set of disallowed values
|
40
|
+
# @return [Array(Symbol, untyped)] the error
|
40
41
|
def exclusion_error(set)
|
41
42
|
[:exclusion, set]
|
42
43
|
end
|
43
44
|
|
44
45
|
# Blank error applies when a value is blank
|
45
|
-
|
46
|
+
# @return [Array(Symbol, untyped)] the error
|
46
47
|
def blank_error
|
47
48
|
[:blank, nil]
|
48
49
|
end
|
49
50
|
|
50
51
|
# Extra keys error applies when a hash has extra keys
|
51
|
-
|
52
|
+
# @param keys [Array<Symbol>] the extra keys
|
53
|
+
# @return [Array(Symbol, untyped)] the error
|
52
54
|
def extra_keys_error(keys)
|
53
55
|
[:extra_keys, keys]
|
54
56
|
end
|
55
57
|
|
56
58
|
# Min applies when value is less then the minimum
|
57
|
-
|
59
|
+
# @param min [Numeric] the minimum value
|
60
|
+
# @param val [Numeric] the value that failed
|
61
|
+
# @return [Array(Symbol, untyped)] the error
|
58
62
|
def min_error(min, val)
|
59
63
|
[:min, [min, val]]
|
60
64
|
end
|
61
65
|
|
62
66
|
# Max applies when value is less then the minimum
|
63
|
-
|
67
|
+
# @param min [Numeric] the minimum value
|
68
|
+
# @param val [Numeric] the value that failed
|
69
|
+
# @return [Array(Symbol, untyped)] the error
|
64
70
|
def max_error(min, val)
|
65
71
|
[:max, [min, val]]
|
66
72
|
end
|
67
73
|
|
68
74
|
# Earliest applies when value is earlier then earliest
|
69
|
-
|
75
|
+
# @param earliest [Date, Time] the earliest value
|
76
|
+
# @param val [Date, Time] the value that failed
|
77
|
+
# @return [Array(Symbol, untyped)] the error
|
70
78
|
def earliest_error(earliest, val)
|
71
79
|
[:earliest, [earliest, val]]
|
72
80
|
end
|
73
81
|
|
74
82
|
# Latest applies when value is earlier then earliest
|
75
|
-
|
83
|
+
# @param latest [Date, Time] the latest value
|
84
|
+
# @param val [Date, Time] the value that failed
|
85
|
+
# @return [Array(Symbol, untyped)] the error
|
76
86
|
def latest_error(latest, val)
|
77
87
|
[:latest, [latest, val]]
|
78
88
|
end
|
79
89
|
|
80
90
|
# Format applies when value does not match a format
|
81
|
-
|
91
|
+
# @param format [Object] the format
|
92
|
+
# @param val [String] the value that failed
|
93
|
+
# @return [Array(Symbol, untyped)] the error
|
82
94
|
def format_error(format, val)
|
83
95
|
[:format, [format, val]]
|
84
96
|
end
|
@@ -86,139 +98,151 @@ module DataModel
|
|
86
98
|
## Messages
|
87
99
|
|
88
100
|
# Generate a message for a type error
|
89
|
-
|
101
|
+
# @param cls [String] the expected class
|
102
|
+
# @param value [Object] the value that failed
|
103
|
+
# @return [String] the message
|
90
104
|
def type_error_message(cls, value)
|
91
|
-
|
105
|
+
names = Array(cls).join(" or ")
|
106
|
+
"#{value.inspect} is not a #{names}, it is a #{value.class.name}"
|
92
107
|
end
|
93
108
|
|
94
109
|
# Generate a message for a coerce error
|
95
|
-
|
110
|
+
# @param cls [String] the expected class
|
111
|
+
# @param value [Object] the value that failed
|
112
|
+
# @return [String] the message
|
96
113
|
def coerce_error_message(cls, value)
|
97
|
-
|
114
|
+
names = Array(cls).join(" or ")
|
115
|
+
"cannot be coerced to #{names}, it is a #{value.class.name}"
|
98
116
|
end
|
99
117
|
|
100
118
|
# Generate a message for a missing error
|
101
|
-
|
119
|
+
# @param cls [String, Array<String>] the expected class
|
120
|
+
# @return [String] the message
|
102
121
|
def missing_error_message(cls)
|
103
|
-
|
122
|
+
names = Array(cls).join(" or ")
|
123
|
+
"missing value, expected a #{names}"
|
104
124
|
end
|
105
125
|
|
106
126
|
# Generate a message for an inclusion error
|
107
|
-
|
127
|
+
# @param set [Array<Symbol, String>] the set of allowed values
|
128
|
+
# @return [String] the message
|
108
129
|
def inclusion_error_message(set)
|
109
130
|
"must be one of #{set.join(', ')}"
|
110
131
|
end
|
111
132
|
|
112
133
|
# Generate a message for an exclusion error
|
113
|
-
|
134
|
+
# @param set [Array<Symbol, String>] the set of disallowed values
|
135
|
+
# @return [String] the message
|
114
136
|
def exclusion_error_message(set)
|
115
137
|
"must not be one of #{set.join(', ')}"
|
116
138
|
end
|
117
139
|
|
118
140
|
# Generate a message for a blank error
|
119
|
-
|
141
|
+
# @return [String] the message
|
120
142
|
def blank_error_message
|
121
143
|
"cannot be blank"
|
122
144
|
end
|
123
145
|
|
124
146
|
# Generate a message for an extra keys error
|
125
|
-
|
147
|
+
# @param keys [Array<Symbol>] the extra keys
|
148
|
+
# @return [String] the message
|
126
149
|
def extra_keys_error_message(keys)
|
127
150
|
"more elements found in closed hash then specified children: #{keys.join(', ')}"
|
128
151
|
end
|
129
152
|
|
130
153
|
# Generate a message for a min error
|
131
|
-
|
154
|
+
# @param min [Numeric] the minimum value
|
155
|
+
# @param val [Numeric] the value that failed
|
156
|
+
# @return [String] the message
|
132
157
|
def min_error_message(min, val)
|
133
158
|
"value is less than the minimum of #{min}, it is #{val}"
|
134
159
|
end
|
135
160
|
|
136
161
|
# Generate a message for a min error
|
137
|
-
|
162
|
+
# @param max [Numeric] the maximum value
|
163
|
+
# @param val [Numeric] the value that failed
|
164
|
+
# @return [String] the message
|
138
165
|
def max_error_message(max, val)
|
139
166
|
"value is more than the maximum of #{max}, it is #{val}"
|
140
167
|
end
|
141
168
|
|
142
169
|
# Generate a message for a value that occurs earlier then the specified earliest point
|
143
|
-
|
170
|
+
# @param earliest [Date, Time] the earliest value
|
171
|
+
# @param val [Date, Time] the value that failed
|
172
|
+
# @return [String] the message
|
144
173
|
def early_error_message(earliest, val)
|
145
174
|
"value #{val} is before #{earliest}"
|
146
175
|
end
|
147
176
|
|
148
177
|
# Generate a message for a value that occurs later then the specified latest point
|
149
|
-
|
178
|
+
# @param latest [Date, Time] the latest value
|
179
|
+
# @param val [Date, Time] the value that failed
|
180
|
+
# @return [String] the message
|
150
181
|
def late_error_message(latest, val)
|
151
182
|
"value #{val} is after #{latest}"
|
152
183
|
end
|
153
184
|
|
154
185
|
# Generate a message for a value that does not match the format
|
155
|
-
|
186
|
+
# @param format [Object] the format
|
187
|
+
# @param val [String] the value that failed
|
188
|
+
# @return [String] the message
|
156
189
|
def format_error_message(format, val)
|
157
190
|
"value #{val} does not match format #{format}"
|
158
191
|
end
|
159
192
|
|
160
193
|
# Builders
|
161
194
|
|
162
|
-
TErrorMessageBuilder = T.type_alias { T.proc.params(ctx: T.untyped).returns(String) }
|
163
|
-
TErrorMessages = T.type_alias { T::Hash[Symbol, TErrorMessageBuilder] }
|
164
|
-
TClassValueCtx = T.type_alias { [T.class_of(Object), Object] }
|
165
|
-
TClassCtx = T.type_alias { T.class_of(Object) }
|
166
|
-
TSetCtx = T.type_alias { T::Array[Symbol] }
|
167
|
-
TWithinCtx = T.type_alias { [Numeric, Numeric] }
|
168
|
-
TWithinTemporalCtx = T.type_alias { [Errors::TTemporal, Errors::TTemporal] }
|
169
|
-
TFormatCtx = T.type_alias { [Object, String] }
|
170
|
-
|
171
195
|
# Get the error message builders
|
172
|
-
|
173
|
-
def
|
196
|
+
# @return [Hash{Symbol => Proc}] the error message builders
|
197
|
+
def error_messages
|
174
198
|
return {
|
175
199
|
type: lambda do |ctx|
|
176
|
-
cls, val =
|
200
|
+
cls, val = ctx
|
177
201
|
type_error_message(cls, val)
|
178
202
|
end,
|
179
203
|
|
180
204
|
coerce: lambda do |ctx|
|
181
|
-
cls, val =
|
205
|
+
cls, val = ctx
|
182
206
|
type_error_message(cls, val)
|
183
207
|
end,
|
184
208
|
|
185
209
|
missing: lambda do |ctx|
|
186
|
-
cls =
|
210
|
+
cls = ctx
|
187
211
|
missing_error_message(cls)
|
188
212
|
end,
|
189
213
|
|
190
214
|
inclusion: lambda do |ctx|
|
191
|
-
set =
|
215
|
+
set = ctx
|
192
216
|
inclusion_error_message(set)
|
193
217
|
end,
|
194
218
|
|
195
219
|
exclusion: lambda do |ctx|
|
196
|
-
set =
|
220
|
+
set = ctx
|
197
221
|
exclusion_error_message(set)
|
198
222
|
end,
|
199
223
|
|
200
224
|
extra_keys: lambda do |ctx|
|
201
|
-
set =
|
225
|
+
set = ctx
|
202
226
|
extra_keys_error_message(set)
|
203
227
|
end,
|
204
228
|
|
205
229
|
min: lambda do |ctx|
|
206
|
-
min, val =
|
230
|
+
min, val = ctx
|
207
231
|
min_error_message(min, val)
|
208
232
|
end,
|
209
233
|
|
210
234
|
max: lambda do |ctx|
|
211
|
-
max, val =
|
235
|
+
max, val = ctx
|
212
236
|
max_error_message(max, val)
|
213
237
|
end,
|
214
238
|
|
215
239
|
earliest: lambda do |ctx|
|
216
|
-
earliest, val =
|
240
|
+
earliest, val = ctx
|
217
241
|
early_error_message(earliest, val)
|
218
242
|
end,
|
219
243
|
|
220
244
|
latest: lambda do |ctx|
|
221
|
-
latest, val =
|
245
|
+
latest, val = ctx
|
222
246
|
late_error_message(latest, val)
|
223
247
|
end,
|
224
248
|
|
@@ -227,7 +251,7 @@ module DataModel
|
|
227
251
|
end,
|
228
252
|
|
229
253
|
format: lambda do |ctx|
|
230
|
-
format, val =
|
254
|
+
format, val = ctx
|
231
255
|
format_error_message(format, val)
|
232
256
|
end
|
233
257
|
}
|
@@ -1,12 +1,22 @@
|
|
1
|
-
# typed: strict
|
2
|
-
|
3
1
|
module DataModel
|
2
|
+
# test fixtures for array type
|
4
3
|
module Fixtures::Array
|
5
4
|
extend self
|
6
|
-
extend T::Sig
|
7
5
|
include Fixtures
|
8
6
|
|
9
|
-
|
7
|
+
# a simple array of any types
|
8
|
+
# @return [Example] the example
|
9
|
+
def any_array
|
10
|
+
Example.new(
|
11
|
+
[:array],
|
12
|
+
variants: {
|
13
|
+
mixed: ["a", 2, [], ::Object.new]
|
14
|
+
},
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
# a simple array of strings example
|
19
|
+
# @return [Example] the example
|
10
20
|
def string_array
|
11
21
|
Example.new(
|
12
22
|
[:array, :string],
|
@@ -16,12 +26,13 @@ module DataModel
|
|
16
26
|
number: [1, ["1"]],
|
17
27
|
missing: nil,
|
18
28
|
numbers: [[1, 2, 3], ["1", "2", "3"]],
|
19
|
-
other_type: Object.new
|
29
|
+
other_type: ::Object.new
|
20
30
|
},
|
21
31
|
)
|
22
32
|
end
|
23
33
|
|
24
|
-
|
34
|
+
# a simple array of strings that wraps single values
|
35
|
+
# @return [Example] the example
|
25
36
|
def wrapping_string_array
|
26
37
|
Example.new(
|
27
38
|
[:array, { wrap_single_value: true }, :string],
|
@@ -31,12 +42,13 @@ module DataModel
|
|
31
42
|
number: [1, ["1"]],
|
32
43
|
missing: nil,
|
33
44
|
numbers: [[1, 2, 3], ["1", "2", "3"]],
|
34
|
-
other_type: Object.new
|
45
|
+
other_type: ::Object.new
|
35
46
|
},
|
36
47
|
)
|
37
48
|
end
|
38
49
|
|
39
|
-
|
50
|
+
# an optional example
|
51
|
+
# @return [Example] the example
|
40
52
|
def optional_string_array
|
41
53
|
Example.new(
|
42
54
|
[:array, { optional: true }, :string],
|
@@ -47,7 +59,8 @@ module DataModel
|
|
47
59
|
)
|
48
60
|
end
|
49
61
|
|
50
|
-
|
62
|
+
# an array of optional strings
|
63
|
+
# @return [Example] the example
|
51
64
|
def array_optional_string
|
52
65
|
Example.new(
|
53
66
|
[:array, [:string, { optional: true }]],
|
@@ -1,14 +1,13 @@
|
|
1
|
-
# typed: strict
|
2
|
-
|
3
1
|
require "bigdecimal/util"
|
4
2
|
|
5
3
|
module DataModel
|
4
|
+
# test fixtures for BigDecimal
|
6
5
|
module Fixtures::BigDecimal
|
7
6
|
include Fixtures
|
8
|
-
extend T::Sig
|
9
7
|
extend self
|
10
8
|
|
11
|
-
|
9
|
+
# a simple decimal example
|
10
|
+
# @return [Example] the example
|
12
11
|
def simple
|
13
12
|
Example.new(
|
14
13
|
[:decimal],
|
@@ -20,7 +19,8 @@ module DataModel
|
|
20
19
|
)
|
21
20
|
end
|
22
21
|
|
23
|
-
|
22
|
+
# a decimal example that is optional
|
23
|
+
# @return [Example] the example
|
24
24
|
def optional
|
25
25
|
Example.new(
|
26
26
|
[:decimal, { optional: true }],
|
@@ -30,7 +30,8 @@ module DataModel
|
|
30
30
|
)
|
31
31
|
end
|
32
32
|
|
33
|
-
|
33
|
+
# a decimal example that has a restriction on the minimum value
|
34
|
+
# @return [Example] the example
|
34
35
|
def min
|
35
36
|
Example.new(
|
36
37
|
[:decimal, { min: 5 }],
|
@@ -41,7 +42,8 @@ module DataModel
|
|
41
42
|
)
|
42
43
|
end
|
43
44
|
|
44
|
-
|
45
|
+
# a decimal example that has a restriction on the maximum value
|
46
|
+
# @return [Example] the example
|
45
47
|
def max
|
46
48
|
Example.new(
|
47
49
|
[:decimal, { max: 5 }],
|
@@ -1,12 +1,11 @@
|
|
1
|
-
# typed: strict
|
2
|
-
|
3
1
|
module DataModel
|
2
|
+
# test fixtures for boolean type
|
4
3
|
module Fixtures::Boolean
|
5
|
-
extend T::Sig
|
6
4
|
extend self
|
7
5
|
include Fixtures
|
8
6
|
|
9
|
-
|
7
|
+
# a simple boolean example
|
8
|
+
# @return [Example] the example
|
10
9
|
def simple
|
11
10
|
Example.new(
|
12
11
|
[:boolean],
|
@@ -19,7 +18,8 @@ module DataModel
|
|
19
18
|
)
|
20
19
|
end
|
21
20
|
|
22
|
-
|
21
|
+
# a boolean example that is optional
|
22
|
+
# @return [Example] the example
|
23
23
|
def optional
|
24
24
|
Example.new(
|
25
25
|
[:boolean, { optional: true }],
|
@@ -1,22 +1,20 @@
|
|
1
|
-
# typed: strict
|
2
|
-
|
3
1
|
module DataModel
|
2
|
+
# Provides fixtures for testing date types
|
4
3
|
module Fixtures::Date
|
5
|
-
extend T::Sig
|
6
|
-
extend self
|
7
4
|
include Fixtures
|
5
|
+
extend self
|
8
6
|
|
9
|
-
|
7
|
+
# @return [Date] a date that is used by the #earliest example
|
10
8
|
def earliest_date
|
11
9
|
return ::Date.today - 1
|
12
10
|
end
|
13
11
|
|
14
|
-
|
12
|
+
# @return [Date] a date that is used by the #latest example
|
15
13
|
def latest_date
|
16
14
|
return ::Date.today + 1
|
17
15
|
end
|
18
16
|
|
19
|
-
|
17
|
+
# @return [Hash{Symbol => untyped}] the variants used by each example
|
20
18
|
def variants
|
21
19
|
today = ::Date.today
|
22
20
|
|
@@ -30,22 +28,26 @@ module DataModel
|
|
30
28
|
}
|
31
29
|
end
|
32
30
|
|
33
|
-
|
31
|
+
# A simple date schema
|
32
|
+
# @return [Example] the example
|
34
33
|
def simple
|
35
34
|
Example.new([:date], variants:)
|
36
35
|
end
|
37
36
|
|
38
|
-
|
37
|
+
# A date schema that is optional
|
38
|
+
# @return [Example] the example
|
39
39
|
def optional
|
40
40
|
Example.new([:date, { optional: true }], variants:)
|
41
41
|
end
|
42
42
|
|
43
|
-
|
43
|
+
# A date schema that has a restriction on the earliest date
|
44
|
+
# @return [Example] the example
|
44
45
|
def earliest
|
45
46
|
Example.new([:date, { earliest: earliest_date }], variants:)
|
46
47
|
end
|
47
48
|
|
48
|
-
|
49
|
+
# A date schema that has a restriction on the latest date
|
50
|
+
# @return [Example] the example
|
49
51
|
def latest
|
50
52
|
Example.new([:date, { latest: latest_date }], variants:)
|
51
53
|
end
|
@@ -1,21 +1,21 @@
|
|
1
|
-
# typed: strict
|
2
|
-
|
3
1
|
module DataModel
|
2
|
+
# A simple abstraction to handle test data
|
4
3
|
class Fixtures::Example
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
# @param schema [Array] the schema
|
5
|
+
# @param variants [Hash{Symbol => untyped}] the variants used by each example
|
6
|
+
# @return [Schema] the schema
|
8
7
|
def initialize(schema, variants:)
|
9
8
|
@schema = schema
|
10
9
|
@variants = variants
|
11
10
|
end
|
12
11
|
|
13
|
-
|
12
|
+
# @return [Model] the model
|
14
13
|
def model
|
15
14
|
DataModel.define(@schema)
|
16
15
|
end
|
17
16
|
|
18
|
-
|
17
|
+
# @param type [Symbol] the variant to use
|
18
|
+
# @return [Array(Model, untyped)] a tuple of [model, variant]
|
19
19
|
def [](type)
|
20
20
|
if !@variants.key?(type)
|
21
21
|
raise "#{type} is not a defined variant: #{@variants}"
|