data_model 0.4.0 → 0.6.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.
- 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}"
|