respect 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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