respect 0.1.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.
Files changed (97) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +289 -0
  3. data/RELATED_WORK.md +40 -0
  4. data/RELEASE_NOTES.md +23 -0
  5. data/Rakefile +31 -0
  6. data/STATUS_MATRIX.html +137 -0
  7. data/lib/respect.rb +231 -0
  8. data/lib/respect/any_schema.rb +22 -0
  9. data/lib/respect/array_def.rb +28 -0
  10. data/lib/respect/array_schema.rb +203 -0
  11. data/lib/respect/boolean_schema.rb +32 -0
  12. data/lib/respect/composite_schema.rb +86 -0
  13. data/lib/respect/core_statements.rb +206 -0
  14. data/lib/respect/datetime_schema.rb +27 -0
  15. data/lib/respect/def_without_name.rb +6 -0
  16. data/lib/respect/divisible_by_validator.rb +20 -0
  17. data/lib/respect/doc_helper.rb +24 -0
  18. data/lib/respect/doc_parser.rb +37 -0
  19. data/lib/respect/dsl_dumper.rb +181 -0
  20. data/lib/respect/equal_to_validator.rb +20 -0
  21. data/lib/respect/fake_name_proxy.rb +116 -0
  22. data/lib/respect/float_schema.rb +27 -0
  23. data/lib/respect/format_validator.rb +136 -0
  24. data/lib/respect/global_def.rb +79 -0
  25. data/lib/respect/greater_than_or_equal_to_validator.rb +19 -0
  26. data/lib/respect/greater_than_validator.rb +19 -0
  27. data/lib/respect/has_constraints.rb +34 -0
  28. data/lib/respect/hash_def.rb +40 -0
  29. data/lib/respect/hash_schema.rb +218 -0
  30. data/lib/respect/in_validator.rb +19 -0
  31. data/lib/respect/integer_schema.rb +27 -0
  32. data/lib/respect/ip_addr_schema.rb +23 -0
  33. data/lib/respect/ipv4_addr_schema.rb +27 -0
  34. data/lib/respect/ipv6_addr_schema.rb +27 -0
  35. data/lib/respect/items_def.rb +21 -0
  36. data/lib/respect/json_schema_html_formatter.rb +143 -0
  37. data/lib/respect/less_than_or_equal_to_validator.rb +19 -0
  38. data/lib/respect/less_than_validator.rb +19 -0
  39. data/lib/respect/match_validator.rb +19 -0
  40. data/lib/respect/max_length_validator.rb +20 -0
  41. data/lib/respect/min_length_validator.rb +20 -0
  42. data/lib/respect/multiple_of_validator.rb +10 -0
  43. data/lib/respect/null_schema.rb +26 -0
  44. data/lib/respect/numeric_schema.rb +33 -0
  45. data/lib/respect/org3_dumper.rb +213 -0
  46. data/lib/respect/regexp_schema.rb +19 -0
  47. data/lib/respect/schema.rb +285 -0
  48. data/lib/respect/schema_def.rb +16 -0
  49. data/lib/respect/string_schema.rb +21 -0
  50. data/lib/respect/unit_test_helper.rb +37 -0
  51. data/lib/respect/uri_schema.rb +23 -0
  52. data/lib/respect/utc_time_schema.rb +17 -0
  53. data/lib/respect/validator.rb +51 -0
  54. data/lib/respect/version.rb +3 -0
  55. data/test/any_schema_test.rb +79 -0
  56. data/test/array_def_test.rb +113 -0
  57. data/test/array_schema_test.rb +487 -0
  58. data/test/boolean_schema_test.rb +89 -0
  59. data/test/composite_schema_test.rb +30 -0
  60. data/test/datetime_schema_test.rb +83 -0
  61. data/test/doc_helper_test.rb +34 -0
  62. data/test/doc_parser_test.rb +109 -0
  63. data/test/dsl_dumper_test.rb +395 -0
  64. data/test/fake_name_proxy_test.rb +138 -0
  65. data/test/float_schema_test.rb +146 -0
  66. data/test/format_validator_test.rb +224 -0
  67. data/test/hash_def_test.rb +126 -0
  68. data/test/hash_schema_test.rb +613 -0
  69. data/test/integer_schema_test.rb +142 -0
  70. data/test/ip_addr_schema_test.rb +78 -0
  71. data/test/ipv4_addr_schema_test.rb +71 -0
  72. data/test/ipv6_addr_schema_test.rb +71 -0
  73. data/test/json_schema_html_formatter_test.rb +214 -0
  74. data/test/null_schema_test.rb +46 -0
  75. data/test/numeric_schema_test.rb +294 -0
  76. data/test/org3_dumper_test.rb +784 -0
  77. data/test/regexp_schema_test.rb +54 -0
  78. data/test/respect_test.rb +108 -0
  79. data/test/schema_def_test.rb +405 -0
  80. data/test/schema_test.rb +290 -0
  81. data/test/string_schema_test.rb +209 -0
  82. data/test/support/circle.rb +11 -0
  83. data/test/support/color.rb +24 -0
  84. data/test/support/point.rb +11 -0
  85. data/test/support/respect/circle_schema.rb +16 -0
  86. data/test/support/respect/color_def.rb +19 -0
  87. data/test/support/respect/color_schema.rb +33 -0
  88. data/test/support/respect/point_schema.rb +19 -0
  89. data/test/support/respect/rgba_schema.rb +20 -0
  90. data/test/support/respect/universal_validator.rb +25 -0
  91. data/test/support/respect/user_macros.rb +12 -0
  92. data/test/support/rgba.rb +11 -0
  93. data/test/test_helper.rb +90 -0
  94. data/test/uri_schema_test.rb +54 -0
  95. data/test/utc_time_schema_test.rb +63 -0
  96. data/test/validator_test.rb +22 -0
  97. metadata +288 -0
@@ -0,0 +1,54 @@
1
+ require "test_helper"
2
+
3
+ class RegexpSchemaTest < Test::Unit::TestCase
4
+
5
+ def test_regexp_schema_creates_uri_object
6
+ s = Respect::RegexpSchema.new
7
+ assert_nil s.sanitized_object
8
+ assert_schema_validate s, "a*b*"
9
+ assert s.sanitized_object.is_a?(Regexp)
10
+ assert_equal(/a*b*/, s.sanitized_object)
11
+ end
12
+
13
+ def test_regexp_schema_relies_on_format_validator
14
+ doc = "a*b*"
15
+ Respect::FormatValidator.any_instance.stubs(:validate_regexp).with(doc).at_least_once
16
+ Respect::RegexpSchema.new.validate(doc)
17
+ end
18
+
19
+ def test_failed_validation_reset_sanitized_object
20
+ s = Respect::RegexpSchema.new
21
+ assert_schema_validate(s, "a*b*")
22
+ assert_not_nil(s.sanitized_object)
23
+ assert_schema_invalidate(s, "*")
24
+ assert_nil(s.sanitized_object)
25
+ end
26
+
27
+ def test_allow_nil
28
+ s = Respect::RegexpSchema.new(allow_nil: true)
29
+ assert s.allow_nil?
30
+ assert_schema_validate s, nil
31
+ assert_equal(nil, s.sanitized_object)
32
+ assert_schema_validate s, "a*b*"
33
+ assert_not_nil(s.sanitized_object)
34
+ assert_schema_invalidate(s, "*")
35
+ assert_nil(s.sanitized_object)
36
+ end
37
+
38
+ def test_disallow_nil
39
+ s = Respect::RegexpSchema.new
40
+ assert !s.allow_nil?
41
+ exception = assert_exception(Respect::ValidationError) { s.validate(nil) }
42
+ assert_match exception.message, /\bRegexpSchema\b/
43
+ assert_equal(nil, s.sanitized_object)
44
+ assert_schema_validate s, "a*b*"
45
+ assert_not_nil(s.sanitized_object)
46
+ assert_schema_invalidate(s, "*")
47
+ assert_nil(s.sanitized_object)
48
+ end
49
+
50
+ def test_validate_regexp_object
51
+ s = Respect::RegexpSchema.new
52
+ assert_schema_validate s, /a/
53
+ end
54
+ end
@@ -0,0 +1,108 @@
1
+ require 'test_helper'
2
+
3
+ class RespectTest < Test::Unit::TestCase
4
+ def test_schema_name_for
5
+ [
6
+ [ "foo", "Respect::FooSchema" ],
7
+ [ "foo_bar", "Respect::FooBarSchema" ],
8
+ [ "equal_to", "Respect::EqualToSchema", "regular" ],
9
+ [ "a_b", "Respect::ABSchema", "two single letter menmonics" ],
10
+ [ "a_b_", "Respect::ABSchema", "trailing underscore" ],
11
+ [ "_a_b", "Respect::ABSchema", "leading underscore" ],
12
+ [ "schema", "Respect::Schema", "special 'schema' case" ],
13
+ [ :schema, "Respect::Schema", "special 'schema' case (symbol)" ],
14
+ [ :string, "Respect::StringSchema", "string schema" ],
15
+ [ :any, "Respect::AnySchema", "any schema" ],
16
+ [ :circle, "Respect::CircleSchema", "user defined schema" ],
17
+ [ :does_not_exist, "Respect::DoesNotExistSchema", "undefined schema" ],
18
+ [ :request, "Respect::RequestSchema", "well named class but not a candidate" ],
19
+ ].each do |data|
20
+ assert_equal data[1], Respect.schema_name_for(data[0]), data[2]
21
+ end
22
+ end
23
+
24
+ def test_schema_name_for_invalid_statement_names_raise_error
25
+ assert_raises(ArgumentError) do
26
+ Respect.schema_name_for("[]=")
27
+ end
28
+ end
29
+
30
+ def test_schema_for
31
+ {
32
+ # root schema
33
+ schema: nil,
34
+ # internal schema definition
35
+ string: Respect::StringSchema,
36
+ integer: Respect::IntegerSchema,
37
+ numeric: Respect::NumericSchema,
38
+ float: Respect::FloatSchema,
39
+ any: Respect::AnySchema,
40
+ uri: Respect::URISchema,
41
+ # user defined schema definition in support/respect
42
+ circle: Respect::CircleSchema,
43
+ point: Respect::PointSchema,
44
+ rgba: Respect::RgbaSchema,
45
+ # valid class but with no statement
46
+ request: nil, # not a Schema sub-class
47
+ composite: nil, # abstract
48
+ undefined_schema: nil, # undefined
49
+ }.each do |statement, schema_class|
50
+ klass = nil
51
+ assert_nothing_raised("nothing raised for '#{statement}'") do
52
+ klass = Respect.schema_for(statement)
53
+ end
54
+ assert_equal schema_class, klass, "correct class for '#{statement}'"
55
+ end
56
+ end
57
+
58
+ def test_schema_for_calls_schema_name_for
59
+ statement_name = "string"
60
+ schema_name = "Respect::StringSchema"
61
+ Respect.expects(:schema_name_for).with(statement_name).returns(schema_name).once
62
+ assert_equal Respect::StringSchema, Respect.schema_for(statement_name)
63
+ end
64
+
65
+ def test_schema_defined_for
66
+ assert_equal true, Respect.schema_defined_for?("string")
67
+ assert_equal false, Respect.schema_defined_for?("request"), "not a schema"
68
+ assert_equal false, Respect.schema_defined_for?("composite"), "abstract"
69
+ assert_equal false, Respect.schema_defined_for?("schema"), "root"
70
+ assert_equal false, Respect.schema_defined_for?("undefined"), "undefined"
71
+ assert_equal true, Respect.schema_defined_for?("hash"), "hash"
72
+ assert_equal false, Respect.schema_defined_for?("object"), "object"
73
+ end
74
+
75
+ def test_validator_name_for
76
+ [
77
+ [ "equal_to", "Respect::EqualToValidator", "regular" ],
78
+ [ "a_b", "Respect::ABValidator", "two single letter menmonics" ],
79
+ [ "a_b_", "Respect::ABValidator", "trailing underscore" ],
80
+ [ "_a_b", "Respect::ABValidator", "leading underscore" ],
81
+ ].each do |data|
82
+ assert_equal data[1], Respect.validator_name_for(data[0]), data[2]
83
+ end
84
+ end
85
+
86
+ def test_validator_for
87
+ {
88
+ equal_to: Respect::EqualToValidator,
89
+ format: Respect::FormatValidator,
90
+ greater_than_or_equal_to: Respect::GreaterThanOrEqualToValidator,
91
+ undefined_validator: nil # undefined
92
+ }.each do |constraint, validator_class|
93
+ klass = nil
94
+ assert_nothing_raised("nothing raised for '#{constraint}'") do
95
+ klass = Respect.validator_for(constraint)
96
+ end
97
+ assert_equal validator_class, klass, "correct class for '#{constraint}'"
98
+ end
99
+ end
100
+
101
+ def test_validator_defined_for
102
+ assert Respect.validator_defined_for?(:equal_to)
103
+ assert Respect.validator_defined_for?(:format)
104
+ assert Respect.validator_defined_for?(:greater_than_or_equal_to)
105
+ assert !Respect.validator_defined_for?(:undefined_validator)
106
+ end
107
+
108
+ end
@@ -0,0 +1,405 @@
1
+ require "test_helper"
2
+
3
+ class SchemaDefTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @title = "This is a title."
7
+ @description = <<-EOS.strip_heredoc
8
+ This a long description...
9
+
10
+ ...with blank line.
11
+ EOS
12
+ @doc = "#@title\n\n#@description"
13
+ end
14
+
15
+ def test_schema_definition_accept_string_with_no_option
16
+ s = Respect::Schema.define do |s|
17
+ s.string
18
+ end
19
+ assert_schema_validate s, "foo"
20
+ end
21
+
22
+ def test_schema_definition_accept_integer
23
+ s = Respect::Schema.define do |s|
24
+ s.integer equal_to: 15
25
+ end
26
+ assert_schema_validate s, "15"
27
+ assert_schema_validate s, 15
28
+ end
29
+
30
+ def test_schema_definition_accept_integer_with_no_option
31
+ s = Respect::Schema.define do |s|
32
+ s.integer
33
+ end
34
+ assert_schema_validate s, 42
35
+ end
36
+
37
+ def test_schema_definition_accept_null
38
+ s = Respect::Schema.define do |s|
39
+ s.null
40
+ end
41
+ assert_schema_validate s, "null"
42
+ end
43
+
44
+ def test_schema_definition_accept_float
45
+ s = Respect::Schema.define do |s|
46
+ s.float equal_to: 1.5
47
+ end
48
+ assert_schema_validate s, "1.5"
49
+ assert_schema_validate s, 1.5
50
+ end
51
+
52
+ def test_schema_definition_accept_float_with_no_option
53
+ s = Respect::Schema.define do |s|
54
+ s.float
55
+ end
56
+ assert_schema_validate s, 42.5
57
+ end
58
+
59
+ def test_schema_definition_accept_boolean
60
+ s = Respect::Schema.define do |s|
61
+ s.boolean equal_to: true
62
+ end
63
+ assert_schema_validate s, "true"
64
+ assert_schema_validate s, true
65
+ end
66
+
67
+ def test_schema_definition_accept_boolean_with_no_option
68
+ s = Respect::Schema.define do |s|
69
+ s.boolean
70
+ end
71
+ assert_schema_validate s, true
72
+ assert_schema_validate s, false
73
+ end
74
+
75
+ def test_schema_definition_accept_array
76
+ s = Respect::Schema.define do |s|
77
+ s.array do |s|
78
+ s.integer
79
+ end
80
+ end
81
+ assert_schema_validate s, [1]
82
+ end
83
+
84
+ def test_schema_definition_accept_array_with_no_option
85
+ s = Respect::Schema.define do |s|
86
+ s.array
87
+ end
88
+ assert_schema_validate s, [1]
89
+ end
90
+
91
+ def test_can_factor_hash_definition
92
+ hash_def = Proc.new do |s|
93
+ s.numeric "n", equal_to: 42
94
+ end
95
+ s1 = Respect::HashSchema.define do |s|
96
+ s.eval(&hash_def)
97
+ end
98
+ s2 = Respect::HashSchema.define do |s|
99
+ s.eval(&hash_def)
100
+ end
101
+ assert_schema_validate s1, { "n" => 42 }
102
+ assert_schema_validate s2, { "n" => 42 }
103
+ end
104
+
105
+ def test_can_factor_array_definition
106
+ array_def = Proc.new do |s|
107
+ s.numeric equal_to: 42
108
+ end
109
+ s1 = Respect::ArraySchema.define do |s|
110
+ s.eval(&array_def)
111
+ end
112
+ s2 = Respect::ArraySchema.define do |s|
113
+ s.eval(&array_def)
114
+ end
115
+ assert_schema_validate s1, [ 42 ]
116
+ assert_schema_validate s2, [ 42 ]
117
+ end
118
+
119
+ def test_can_factor_options
120
+ options = { equal_to: 42 }
121
+ s = Respect::HashSchema.define do |s|
122
+ s.integer "int", options
123
+ s.numeric "num", options
124
+ end
125
+ assert_schema_validate s, { "int" => 42, "num" => 42.0 }
126
+ end
127
+
128
+ def test_method_missing_is_raised_in_dsl
129
+ for_each_context do |s|
130
+ assert_raise(NoMethodError,
131
+ "unknown method raises NoMethodError in #{s.target.class}") do
132
+ s.unknown_method
133
+ end
134
+ end
135
+ end
136
+
137
+ def test_can_use_object_methods_in_dsl_evaluator
138
+ for_each_context do |s|
139
+ assert_nothing_raised("can call Object method from DSL evaluator in #{s.target.class}") do
140
+ s.class
141
+ end
142
+ end
143
+ end
144
+
145
+ def test_cannot_use_kernel_methods_in_dsl_evaluator
146
+ for_each_context do |s|
147
+ assert_nothing_raised("can call Kernel method from DSL evaluator in #{s.target.class}") do
148
+ s.send(:String, "foo")
149
+ end
150
+ end
151
+ end
152
+
153
+ def test_helper_can_use_kernel_features
154
+ for_each_context do |s|
155
+ assert_nothing_raised("call to Kernel method works in #{s.target.class}") do
156
+ s.call_to_kernel
157
+ end
158
+ end
159
+ end
160
+
161
+ def test_helper_can_use_object_features
162
+ for_each_context do |s|
163
+ assert_nothing_raised("call to Object method works in #{s.target.class}") do
164
+ s.call_to_object
165
+ end
166
+ end
167
+ end
168
+
169
+ def test_dsl_accept_basic_statements_with_no_option
170
+ BASIC_STATEMENTS_LIST.each do |statement|
171
+ for_each_context do |s|
172
+ assert_nothing_raised("'#{statement}' method accepted in #{s.target.class}") do
173
+ send_statement_in_context(s, statement, "fake name")
174
+ end
175
+ end
176
+ end
177
+ end
178
+
179
+ def test_can_extend_dsl_with_custom_module
180
+ # See DSL extension module defined in test_helper.rb.
181
+ s = Respect::HashSchema.define do |s|
182
+ s.id
183
+ s.id "table_id"
184
+ s.array "array" do |s|
185
+ s.id
186
+ end
187
+ end
188
+ assert_schema_validate s, { "id" => 42, "table_id" => 12, "array" => [ 1, 2 ]}
189
+ assert_schema_invalidate s, { "id" => 42, "table_id" => 12, "array" => [ -1, 2 ]}
190
+ assert_schema_invalidate s, { "id" => 0, "table_id" => 12, "array" => [ 1, 2 ]}
191
+ assert_schema_invalidate s, { "id" => 42, "table_id" => 12, "array" => [ 1, -2 ]}
192
+ assert_schema_invalidate s, { "id" => 42, "table_id" => 0, "array" => [ 1, 2 ]}
193
+ end
194
+
195
+ def test_can_convert_doc_to_custom_type
196
+ # See DSL extension module defined in test_helper.rb.
197
+ s = Respect::HashSchema.define do |s|
198
+ s.point "origin"
199
+ s.array "polygon" do |s|
200
+ s.point
201
+ end
202
+ end
203
+ # Check validation works.
204
+ assert_schema_validate s, { "origin" => { "x" => 1.0, "y" => 0.0 },
205
+ "polygon" => [ { "x" => 2.0, "y" => 3.0 } ] }
206
+ assert_schema_invalidate s, { "origin" => { "x" => 1.0 },
207
+ "polygon" => [ { "x" => 2.0, "y" => 3.0 } ] }
208
+ assert_schema_invalidate s, { "origin" => { "x" => 1.0, "y" => 0.0 },
209
+ "polygon" => [ { "x" => 2.0 } ] }
210
+ # Check conversion works.
211
+ doc = { "origin" => { "x" => 1.0, "y" => 0.0 }, "polygon" => [ { "x" => 2.0, "y" => 3.0 } ] }
212
+ assert_schema_validate s, doc
213
+ assert_equal({ "origin" => Point.new(1.0, 0.0), "polygon" => [ Point.new(2.0, 3.0) ]},
214
+ s.sanitized_object)
215
+ end
216
+
217
+ def test_format_helper_statement_create_string_schema
218
+ FORMAT_HELPER_STATEMENTS_LIST.each do |statement|
219
+ for_each_context do |s|
220
+ schema = send_statement_in_context(s, statement, "an_statement", equal_to: "expected_value")
221
+ assert schema.is_a?(Respect::StringSchema), "is a StringSchema for #{statement} in #{s.target.class}"
222
+ assert_equal statement, schema.options[:format], "format is :#{statement} in #{s.target.class}"
223
+ assert_equal "expected_value", schema.options[:equal_to], "equal_to works for #{statement} in #{s.target.class}"
224
+ end
225
+ end
226
+ end
227
+
228
+ def test_statement_return_created_schema
229
+ BASIC_STATEMENTS_LIST.each do |statement|
230
+ for_each_context do |s|
231
+ schema = send_statement_in_context(s, statement, "fake name")
232
+ assert schema.is_a?(Respect::Schema), "'#{statement}' returns a schema in #{s.target.class}"
233
+ end
234
+ end
235
+ end
236
+
237
+ def test_uri_statement_create_uri_schema
238
+ for_each_context do |s|
239
+ schema = send_statement_in_context(s, :uri, "an_uri", equal_to: "expected_value")
240
+ assert schema.is_a?(Respect::URISchema), "is a URISchema in #{s.target.class}"
241
+ assert_equal "expected_value", schema.options[:equal_to], "equal_to works in #{s.target.class}"
242
+ end
243
+ end
244
+
245
+ def test_regexp_statement_create_regexp_schema
246
+ for_each_context do |s|
247
+ schema = send_statement_in_context(s, :regexp, "a_regexp", equal_to: "expected_value")
248
+ assert schema.is_a?(Respect::RegexpSchema), "is a RegexpSchema in #{s.target.class}"
249
+ assert_equal "expected_value", schema.options[:equal_to], "equal_to works in #{s.target.class}"
250
+ end
251
+ end
252
+
253
+ def test_datetime_statement_create_datetime_schema
254
+ for_each_context do |s|
255
+ schema = send_statement_in_context(s, :datetime, "a_datetime", equal_to: "expected_value")
256
+ assert schema.is_a?(Respect::DatetimeSchema), "is a DatetimeSchema in #{s.target.class}"
257
+ assert_equal "expected_value", schema.options[:equal_to], "equal_to works in #{s.target.class}"
258
+ end
259
+ end
260
+
261
+ def test_ip_addr_statement_create_ipaddr_schema
262
+ for_each_context do |s|
263
+ schema = send_statement_in_context(s, :ip_addr, "a_ip_addr", equal_to: "expected_value")
264
+ assert schema.is_a?(Respect::IPAddrSchema), "is a IPAddrSchema in #{s.target.class}"
265
+ assert_equal "expected_value", schema.options[:equal_to], "equal_to works in #{s.target.class}"
266
+ end
267
+ end
268
+
269
+ def test_ipv4_addr_statement_create_ipv4addr_schema
270
+ for_each_context do |s|
271
+ schema = send_statement_in_context(s, :ipv4_addr, "a_ipv4_addr", equal_to: "expected_value")
272
+ assert schema.is_a?(Respect::Ipv4AddrSchema), "is a Ipv4AddrSchema in #{s.target.class}"
273
+ assert_equal "expected_value", schema.options[:equal_to], "equal_to works in #{s.target.class}"
274
+ end
275
+ end
276
+
277
+ def test_ipv6_addr_statement_create_ipv6addr_schema
278
+ for_each_context do |s|
279
+ schema = send_statement_in_context(s, :ipv6_addr, "a_ipv6_addr", equal_to: "expected_value")
280
+ assert schema.is_a?(Respect::Ipv6AddrSchema), "is a Ipv6AddrSchema in #{s.target.class}"
281
+ assert_equal "expected_value", schema.options[:equal_to], "equal_to works in #{s.target.class}"
282
+ end
283
+ end
284
+
285
+ def test_utc_time_statement_create_utc_time_schema
286
+ for_each_context do |s|
287
+ schema = send_statement_in_context(s, :utc_time, "a_utc_time", equal_to: "expected_value")
288
+ assert schema.is_a?(Respect::UTCTimeSchema), "is a UTCTimeSchema in #{s.target.class}"
289
+ assert_equal "expected_value", schema.options[:equal_to], "equal_to works in #{s.target.class}"
290
+ end
291
+ end
292
+
293
+ def test_statements_have_doc_option
294
+ BASIC_STATEMENTS_LIST.each do |statement|
295
+ for_each_context do |s|
296
+ schema = send_statement_in_context(s, statement, "a_name", doc: @doc)
297
+ assert_equal @title, schema.title, "title set by #{statement} in #{s.target.class}"
298
+ assert_equal @description, schema.description, "description set by #{statement} in #{s.target.class}"
299
+ assert_equal @doc, schema.doc, "doc set by #{statement} in #{s.target.class}"
300
+ end
301
+ end
302
+ end
303
+
304
+ def test_doc_statement_assign_every_statements
305
+ BASIC_STATEMENTS_LIST.each do |statement|
306
+ for_each_context do |s|
307
+ title = "#@title for '#{statement}' in #{s.target.class}"
308
+ description = "#@description for '#{statement}' in #{s.target.class}"
309
+ doc = "#{title}\n\n#{description}"
310
+ s.doc doc
311
+ schema = send_statement_in_context(s, statement, "a_name")
312
+ assert_equal title, schema.title, "title set by #{statement} in #{s.target.class}"
313
+ assert_equal description, schema.description, "description set by #{statement} in #{s.target.class}"
314
+ assert_equal doc, schema.doc, "doc set by #{statement} in #{s.target.class}"
315
+ end
316
+ end
317
+ end
318
+
319
+ def test_abstract_schema_class_have_no_dynamic_statement
320
+ for_each_context do |s|
321
+ assert_raise(NoMethodError,
322
+ "abstract class have no dynamic statement in #{s.target.class}") do
323
+ s.__send__(:composite)
324
+ end
325
+ end
326
+ end
327
+
328
+ def test_eval_in_fake_name_proxy
329
+ for_each_context do |s|
330
+ assert(s.__id__ != s.target.__id__, "proxy present in #{s.target.class}")
331
+ assert(s.class == s.target.class, "proxy present in #{s.target.class}")
332
+ end
333
+ end
334
+
335
+ def test_can_define_user_def_class
336
+ s = Respect::Schema.define do |s|
337
+ s.color do |s|
338
+ s.red 255
339
+ end
340
+ end
341
+ assert_schema_validate(s, "#ff000000")
342
+ end
343
+
344
+ def test_color_def_reject_core_statement
345
+ Respect::ColorSchema.define do |s|
346
+ assert_raises(NoMethodError) do
347
+ s.string
348
+ end
349
+ end
350
+ end
351
+
352
+ def test_core_def_has_core_statements
353
+ core_def = Respect::CoreDef.new
354
+ assert_respond_to core_def, :string, "from CoreStatements"
355
+ assert_respond_to core_def, :color_channel, "from UserMacros"
356
+ assert_respond_to core_def, :id, "from EndUserDSLStatement"
357
+ end
358
+
359
+ private
360
+
361
+ # Run the given block in each context of the DSL.
362
+ # It passes the context as first argument to the block.
363
+ def for_each_context(&block)
364
+ # In root context.
365
+ Respect::Schema.define {|s| instance_exec(s, &block) }
366
+ # In all contexts.
367
+ {
368
+ :hash => [
369
+ nil,
370
+ :extra,
371
+ ],
372
+ :array => [
373
+ nil,
374
+ :items,
375
+ :extra_items,
376
+ ]
377
+ }.each do |ctxt, sub_ctxts|
378
+ sub_ctxts.each do |sub_ctxt|
379
+ Respect::Schema.define do |s|
380
+ s.__send__(ctxt) do |s|
381
+ if sub_ctxt
382
+ s.__send__(sub_ctxt) do |s|
383
+ instance_exec(s, &block)
384
+ end
385
+ else
386
+ instance_exec(s, &block)
387
+ end
388
+ end
389
+ end
390
+ end
391
+ end
392
+ end
393
+
394
+ # Send the given _statement_ to the given _dsl_def_ context. Name is passed
395
+ # if the context accept a name. All the rest of the arguments and the block
396
+ # are always passed.
397
+ def send_statement_in_context(dsl_def, statement, name, *args, &block)
398
+ if dsl_def.target.class.accept_name?
399
+ dsl_def.__send__(statement, name, *args, &block)
400
+ else
401
+ dsl_def.__send__(statement, *args, &block)
402
+ end
403
+ end
404
+
405
+ end