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,142 @@
1
+ require "test_helper"
2
+
3
+ class IntegerSchemaTest < Test::Unit::TestCase
4
+ def test_expected_value_are_not_converted
5
+ s = Respect::IntegerSchema.new(equal_to: "42")
6
+ assert_raise(Respect::ValidationError) do
7
+ s.validate(42)
8
+ end
9
+ end
10
+
11
+ def test_malformed_string_value_raise_exception
12
+ s = Respect::IntegerSchema.new
13
+ [
14
+ "s42",
15
+ "4s2",
16
+ "42s",
17
+ "4-2",
18
+ "42-",
19
+ "-+42",
20
+ "+-42",
21
+ "42.5",
22
+ "0.5",
23
+ ].each do |test_value|
24
+ assert_raise(Respect::ValidationError) do
25
+ s.validate_type(test_value)
26
+ end
27
+ end
28
+ end
29
+
30
+ def test_string_value_get_converted
31
+ [
32
+ [ "-42", -42 ],
33
+ [ "+42", 42 ],
34
+ [ "42", 42 ],
35
+ ].each do |test_data|
36
+ s = Respect::IntegerSchema.new
37
+ assert_equal test_data[1], s.validate_type(test_data[0])
38
+ assert_nil s.sanitized_object
39
+ s.validate(test_data[0])
40
+ assert_equal test_data[1], s.sanitized_object
41
+ end
42
+ end
43
+
44
+ def test_integer_accept_equal_to_constraint
45
+ s = Respect::IntegerSchema.new(equal_to: 41)
46
+ assert_schema_validate s, 41
47
+ assert_schema_invalidate s, 52
48
+ end
49
+
50
+ def test_greater_than_constraint_works
51
+ s = Respect::IntegerSchema.new(greater_than: 0)
52
+ assert s.validate(42)
53
+ [ 0, -42 ].each do |test_value|
54
+ assert_raise(Respect::ValidationError) do
55
+ s.validate(test_value)
56
+ end
57
+ end
58
+ end
59
+
60
+ def test_greater_than_or_equal_to_constraint_works
61
+ s = Respect::IntegerSchema.new(greater_than_or_equal_to: 0)
62
+ assert s.validate(42)
63
+ assert s.validate(0)
64
+ assert_raise(Respect::ValidationError) do
65
+ s.validate(-42)
66
+ end
67
+ end
68
+
69
+ def test_less_than_constraint_works
70
+ s = Respect::IntegerSchema.new(less_than: 0)
71
+ assert s.validate(-1)
72
+ [ 0, 1 ].each do |test_value|
73
+ assert_raise(Respect::ValidationError) do
74
+ s.validate(test_value)
75
+ end
76
+ end
77
+ end
78
+
79
+ def test_less_than_or_equal_to_constraint_works
80
+ s = Respect::IntegerSchema.new(less_than_or_equal_to: 0)
81
+ assert s.validate(-1)
82
+ assert s.validate(0)
83
+ assert_raise(Respect::ValidationError) do
84
+ s.validate(1)
85
+ end
86
+ end
87
+
88
+ def test_integer_value_is_in_set
89
+ s = Respect::IntegerSchema.new(in: [42, 51])
90
+ assert_schema_validate s, 42
91
+ assert_schema_validate s, 51
92
+ assert_schema_invalidate s, 1664
93
+ end
94
+
95
+ def test_integer_value_is_in_range
96
+ s = Respect::IntegerSchema.new(in: 1..4)
97
+ assert_schema_invalidate s, 0
98
+ assert_schema_validate s, 1
99
+ assert_schema_validate s, 2
100
+ assert_schema_validate s, 3
101
+ assert_schema_validate s, 4
102
+ assert_schema_invalidate s, 5
103
+
104
+ s = Respect::IntegerSchema.new(in: 1...4)
105
+ assert_schema_invalidate s, 0
106
+ assert_schema_validate s, 1
107
+ assert_schema_validate s, 2
108
+ assert_schema_validate s, 3
109
+ assert_schema_invalidate s, 4
110
+ assert_schema_invalidate s, 5
111
+ end
112
+
113
+ def test_failed_validation_reset_sanitized_object
114
+ s = Respect::IntegerSchema.define equal_to: 42
115
+ assert_schema_validate(s, 42)
116
+ assert_equal(42, s.sanitized_object)
117
+ assert_schema_invalidate(s, 51)
118
+ assert_equal(nil, s.sanitized_object)
119
+ end
120
+
121
+ def test_allow_nil
122
+ s = Respect::IntegerSchema.new(allow_nil: true)
123
+ assert_schema_validate s, nil
124
+ assert_equal(nil, s.sanitized_object)
125
+ assert_schema_validate s, 42
126
+ assert_equal(42, s.sanitized_object)
127
+ assert_schema_validate s, "42"
128
+ assert_equal(42, s.sanitized_object)
129
+ end
130
+
131
+ def test_disallow_nil
132
+ s = Respect::IntegerSchema.new
133
+ assert !s.allow_nil?
134
+ exception = assert_exception(Respect::ValidationError) { s.validate(nil) }
135
+ assert_match exception.message, /\bIntegerSchema\b/
136
+ assert_equal(nil, s.sanitized_object)
137
+ assert_schema_validate s, 42
138
+ assert_equal(42, s.sanitized_object)
139
+ assert_schema_validate s, "42"
140
+ assert_equal(42, s.sanitized_object)
141
+ end
142
+ end
@@ -0,0 +1,78 @@
1
+ require "test_helper"
2
+
3
+ class IPAddrSchemaTest < Test::Unit::TestCase
4
+
5
+ def test_ip_addr_schema_creates_ipaddr_object
6
+ s = Respect::IPAddrSchema.new
7
+ assert_nil s.sanitized_object
8
+ # IPv4
9
+ assert_schema_validate s, "192.168.0.2"
10
+ assert s.sanitized_object.is_a?(IPAddr)
11
+ assert s.sanitized_object.ipv4?
12
+ assert_equal("192.168.0.2", s.sanitized_object.to_s)
13
+ # IPv6
14
+ assert_schema_validate s, "3ffe:505:2::1"
15
+ assert s.sanitized_object.is_a?(IPAddr)
16
+ assert s.sanitized_object.ipv6?
17
+ assert_equal("3ffe:505:2::1", s.sanitized_object.to_s)
18
+ end
19
+
20
+ def test_ip_addr_schema_relies_on_format_validator
21
+ doc = "192.168.0.2"
22
+ Respect::FormatValidator.any_instance.stubs(:validate_ip_addr).with(doc).at_least_once
23
+ Respect::IPAddrSchema.new.validate(doc)
24
+ end
25
+
26
+ def test_failed_validation_reset_sanitized_object
27
+ s = Respect::IPAddrSchema.new
28
+ assert_schema_validate(s, "192.168.0.2")
29
+ assert_not_nil(s.sanitized_object)
30
+ assert_schema_invalidate(s, "wrong")
31
+ assert_nil(s.sanitized_object)
32
+ end
33
+
34
+ def test_allow_nil
35
+ s = Respect::IPAddrSchema.new(allow_nil: true)
36
+ assert s.allow_nil?
37
+ assert_schema_validate s, nil
38
+ assert_equal(nil, s.sanitized_object)
39
+ assert_schema_validate s, "192.168.0.2"
40
+ assert_not_nil(s.sanitized_object)
41
+ assert_schema_invalidate(s, "wrong")
42
+ assert_nil(s.sanitized_object)
43
+ end
44
+
45
+ def test_disallow_nil
46
+ s = Respect::IPAddrSchema.new
47
+ assert !s.allow_nil?
48
+ exception = assert_exception(Respect::ValidationError) { s.validate(nil) }
49
+ assert_match exception.message, /\bIPAddrSchema\b/
50
+ assert_equal(nil, s.sanitized_object)
51
+ assert_schema_validate s, "192.168.0.2"
52
+ assert_not_nil(s.sanitized_object)
53
+ assert_schema_invalidate(s, "wrong")
54
+ assert_nil(s.sanitized_object)
55
+ end
56
+
57
+ def test_validate_ip_addr_object_with_ipv4_value
58
+ s = Respect::IPAddrSchema.new
59
+ ip = IPAddr.new("192.168.0.2")
60
+ assert_equal(IPAddr, ip.class)
61
+ assert ip.ipv4?
62
+ assert_schema_validate s, ip
63
+ assert_equal IPAddr, s.sanitized_object.class
64
+ assert_equal ip, s.sanitized_object
65
+ assert s.sanitized_object.ipv4?
66
+ end
67
+
68
+ def test_validate_ip_addr_object_with_ipv6_value
69
+ s = Respect::IPAddrSchema.new
70
+ ip = IPAddr.new("3ffe:505:2::1")
71
+ assert_equal(IPAddr, ip.class)
72
+ assert ip.ipv6?
73
+ assert_schema_validate s, ip
74
+ assert_equal IPAddr, s.sanitized_object.class
75
+ assert_equal ip, s.sanitized_object
76
+ assert s.sanitized_object.ipv6?
77
+ end
78
+ end
@@ -0,0 +1,71 @@
1
+ require "test_helper"
2
+
3
+ class Ipv4AddrSchemaTest < Test::Unit::TestCase
4
+
5
+ def test_ipv4_addr_schema_creates_ipaddr_object
6
+ s = Respect::Ipv4AddrSchema.new
7
+ assert_nil s.sanitized_object
8
+ assert_schema_validate s, "192.168.0.2"
9
+ assert s.sanitized_object.is_a?(IPAddr)
10
+ assert s.sanitized_object.ipv4?
11
+ assert_equal("192.168.0.2", s.sanitized_object.to_s)
12
+ end
13
+
14
+ def test_ipv4_addr_schema_relies_on_format_validator
15
+ doc = "192.168.0.2"
16
+ Respect::FormatValidator.any_instance.stubs(:validate_ipv4_addr).with(doc).at_least_once
17
+ Respect::Ipv4AddrSchema.new.validate(doc)
18
+ end
19
+
20
+ def test_failed_validation_reset_sanitized_object
21
+ s = Respect::Ipv4AddrSchema.new
22
+ assert_schema_validate(s, "192.168.0.2")
23
+ assert_not_nil(s.sanitized_object)
24
+ assert_schema_invalidate(s, "wrong")
25
+ assert_nil(s.sanitized_object)
26
+ end
27
+
28
+ def test_allow_nil
29
+ s = Respect::Ipv4AddrSchema.new(allow_nil: true)
30
+ assert s.allow_nil?
31
+ assert_schema_validate s, nil
32
+ assert_equal(nil, s.sanitized_object)
33
+ assert_schema_validate s, "192.168.0.2"
34
+ assert_not_nil(s.sanitized_object)
35
+ assert_schema_invalidate(s, "wrong")
36
+ assert_nil(s.sanitized_object)
37
+ end
38
+
39
+ def test_disallow_nil
40
+ s = Respect::Ipv4AddrSchema.new
41
+ assert !s.allow_nil?
42
+ exception = assert_exception(Respect::ValidationError) { s.validate(nil) }
43
+ assert_match exception.message, /\bIpv4AddrSchema\b/
44
+ assert_equal(nil, s.sanitized_object)
45
+ assert_schema_validate s, "192.168.0.2"
46
+ assert_not_nil(s.sanitized_object)
47
+ assert_schema_invalidate(s, "wrong")
48
+ assert_nil(s.sanitized_object)
49
+ end
50
+
51
+ def test_validate_ip_addr_object_with_ipv4_value
52
+ s = Respect::Ipv4AddrSchema.new
53
+ ip = IPAddr.new("192.168.0.2")
54
+ assert_equal(IPAddr, ip.class)
55
+ assert ip.ipv4?
56
+ assert_schema_validate s, ip
57
+ assert_equal IPAddr, s.sanitized_object.class
58
+ assert_equal ip, s.sanitized_object
59
+ assert s.sanitized_object.ipv4?
60
+ end
61
+
62
+ def test_invalidate_ip_addr_object_with_ipv6_value
63
+ s = Respect::Ipv4AddrSchema.new
64
+ ip = IPAddr.new("3ffe:505:2::1")
65
+ assert_kind_of IPAddr, ip
66
+ assert ip.ipv6?
67
+ exception = assert_exception(Respect::ValidationError) { s.validate(ip) }
68
+ assert_match exception.message, /\b#{ip}\b/
69
+ assert_match exception.message, /not IPv4/
70
+ end
71
+ end
@@ -0,0 +1,71 @@
1
+ require "test_helper"
2
+
3
+ class Ipv6AddrSchemaTest < Test::Unit::TestCase
4
+
5
+ def test_ipv6_addr_schema_creates_ipaddr_object
6
+ s = Respect::Ipv6AddrSchema.new
7
+ assert_nil s.sanitized_object
8
+ assert_schema_validate s, "3ffe:505:2::1"
9
+ assert s.sanitized_object.is_a?(IPAddr)
10
+ assert s.sanitized_object.ipv6?
11
+ assert_equal("3ffe:505:2::1", s.sanitized_object.to_s)
12
+ end
13
+
14
+ def test_ipv6_addr_schema_relies_on_format_validator
15
+ doc = "3ffe:505:2::1"
16
+ Respect::FormatValidator.any_instance.stubs(:validate_ipv6_addr).with(doc).at_least_once
17
+ Respect::Ipv6AddrSchema.new.validate(doc)
18
+ end
19
+
20
+ def test_failed_validation_reset_sanitized_object
21
+ s = Respect::Ipv6AddrSchema.new
22
+ assert_schema_validate(s, "3ffe:505:2::1")
23
+ assert_not_nil(s.sanitized_object)
24
+ assert_schema_invalidate(s, "wrong")
25
+ assert_nil(s.sanitized_object)
26
+ end
27
+
28
+ def test_allow_nil
29
+ s = Respect::Ipv6AddrSchema.new(allow_nil: true)
30
+ assert s.allow_nil?
31
+ assert_schema_validate s, nil
32
+ assert_equal(nil, s.sanitized_object)
33
+ assert_schema_validate s, "3ffe:505:2::1"
34
+ assert_not_nil(s.sanitized_object)
35
+ assert_schema_invalidate(s, "wrong")
36
+ assert_nil(s.sanitized_object)
37
+ end
38
+
39
+ def test_disallow_nil
40
+ s = Respect::Ipv6AddrSchema.new
41
+ assert !s.allow_nil?
42
+ exception = assert_exception(Respect::ValidationError) { s.validate(nil) }
43
+ assert_match exception.message, /\bIpv6AddrSchema\b/
44
+ assert_equal(nil, s.sanitized_object)
45
+ assert_schema_validate s, "3ffe:505:2::1"
46
+ assert_not_nil(s.sanitized_object)
47
+ assert_schema_invalidate(s, "wrong")
48
+ assert_nil(s.sanitized_object)
49
+ end
50
+
51
+ def test_invalidate_ip_addr_object_with_ipv4_value
52
+ s = Respect::Ipv6AddrSchema.new
53
+ ip = IPAddr.new("192.168.0.2")
54
+ assert_equal(IPAddr, ip.class)
55
+ assert ip.ipv4?
56
+ exception = assert_exception(Respect::ValidationError) { s.validate(ip) }
57
+ assert_match exception.message, /\b#{ip}\b/
58
+ assert_match exception.message, /not IPv6/
59
+ end
60
+
61
+ def test_validate_ip_addr_object_with_ipv6_value
62
+ s = Respect::Ipv6AddrSchema.new
63
+ ip = IPAddr.new("3ffe:505:2::1")
64
+ assert_equal(IPAddr, ip.class)
65
+ assert ip.ipv6?
66
+ assert_schema_validate s, ip
67
+ assert_equal IPAddr, s.sanitized_object.class
68
+ assert_equal ip, s.sanitized_object
69
+ assert s.sanitized_object.ipv6?
70
+ end
71
+ end
@@ -0,0 +1,214 @@
1
+ require "test_helper"
2
+
3
+ class JSONSchemaHTMLFormatterTest < Test::Unit::TestCase
4
+ def test_dump_simple_hash
5
+ json_schema = {
6
+ "type" => "integer",
7
+ "required" => false,
8
+ }
9
+ output = ""
10
+ Respect::JSONSchemaHTMLFormatter.new(json_schema).dump(output)
11
+ expected = <<-EOS.strip_heredoc
12
+ <div class=\"json_highlight\"><pre><span class=\"plain\">{</span>
13
+ <span class=\"key\">\"type\"</span><span class=\"plain\">:</span> <span class=\"string\">\"integer\"</span><span class=\"plain\">,</span>
14
+ <span class=\"key\">\"required\"</span><span class=\"plain\">:</span> <span class=\"keyword\">false</span>
15
+ <span class=\"plain\">}</span></pre></div>
16
+ EOS
17
+ assert_equal expected, output
18
+ end
19
+
20
+ def test_dump_nested_hash
21
+ json_schema = {
22
+ "type" => "object",
23
+ "properties" => {
24
+ "circle" => {
25
+ "type" => "object",
26
+ "required" => true,
27
+ "properties" => {
28
+ "center" => {
29
+ "type" => "object",
30
+ "required" => true,
31
+ "properties" => {
32
+ "x" => {
33
+ "type" => "number",
34
+ "required" => true
35
+ },
36
+ "y" => {
37
+ "type" => "number",
38
+ "required" => true
39
+ }
40
+ }
41
+ },
42
+ "radius" => {
43
+ "type" => "number",
44
+ "required" => true,
45
+ "minimum" => 0.0,
46
+ "exclusiveMinimum" => true
47
+ }
48
+ }
49
+ },
50
+ },
51
+ }
52
+ output = ""
53
+ Respect::JSONSchemaHTMLFormatter.new(json_schema).dump(output)
54
+ expected = <<-EOS.strip_heredoc
55
+ <div class=\"json_highlight\"><pre><span class=\"plain\">{</span>
56
+ <span class=\"key\">\"type\"</span><span class=\"plain\">:</span> <span class=\"string\">\"object\"</span><span class=\"plain\">,</span>
57
+ <span class=\"key\">\"properties\"</span><span class=\"plain\">:</span> <span class=\"plain\">{</span>
58
+ <span class=\"key\">\"circle\"</span><span class=\"plain\">:</span> <span class=\"plain\">{</span>
59
+ <span class=\"key\">\"type\"</span><span class=\"plain\">:</span> <span class=\"string\">\"object\"</span><span class=\"plain\">,</span>
60
+ <span class=\"key\">\"required\"</span><span class=\"plain\">:</span> <span class=\"keyword\">true</span><span class=\"plain\">,</span>
61
+ <span class=\"key\">\"properties\"</span><span class=\"plain\">:</span> <span class=\"plain\">{</span>
62
+ <span class=\"key\">\"center\"</span><span class=\"plain\">:</span> <span class=\"plain\">{</span>
63
+ <span class=\"key\">\"type\"</span><span class=\"plain\">:</span> <span class=\"string\">\"object\"</span><span class=\"plain\">,</span>
64
+ <span class=\"key\">\"required\"</span><span class=\"plain\">:</span> <span class=\"keyword\">true</span><span class=\"plain\">,</span>
65
+ <span class=\"key\">\"properties\"</span><span class=\"plain\">:</span> <span class=\"plain\">{</span>
66
+ <span class=\"key\">\"x\"</span><span class=\"plain\">:</span> <span class=\"plain\">{</span>
67
+ <span class=\"key\">\"type\"</span><span class=\"plain\">:</span> <span class=\"string\">\"number\"</span><span class=\"plain\">,</span>
68
+ <span class=\"key\">\"required\"</span><span class=\"plain\">:</span> <span class=\"keyword\">true</span>
69
+ <span class=\"plain\">}</span><span class=\"plain\">,</span>
70
+ <span class=\"key\">\"y\"</span><span class=\"plain\">:</span> <span class=\"plain\">{</span>
71
+ <span class=\"key\">\"type\"</span><span class=\"plain\">:</span> <span class=\"string\">\"number\"</span><span class=\"plain\">,</span>
72
+ <span class=\"key\">\"required\"</span><span class=\"plain\">:</span> <span class=\"keyword\">true</span>
73
+ <span class=\"plain\">}</span>
74
+ <span class=\"plain\">}</span>
75
+ <span class=\"plain\">}</span><span class=\"plain\">,</span>
76
+ <span class=\"key\">\"radius\"</span><span class=\"plain\">:</span> <span class=\"plain\">{</span>
77
+ <span class=\"key\">\"type\"</span><span class=\"plain\">:</span> <span class=\"string\">\"number\"</span><span class=\"plain\">,</span>
78
+ <span class=\"key\">\"required\"</span><span class=\"plain\">:</span> <span class=\"keyword\">true</span><span class=\"plain\">,</span>
79
+ <span class=\"key\">\"minimum\"</span><span class=\"plain\">:</span> <span class=\"numeric\">0.0</span><span class=\"plain\">,</span>
80
+ <span class=\"key\">\"exclusiveMinimum\"</span><span class=\"plain\">:</span> <span class=\"keyword\">true</span>
81
+ <span class=\"plain\">}</span>
82
+ <span class=\"plain\">}</span>
83
+ <span class=\"plain\">}</span>
84
+ <span class=\"plain\">}</span>
85
+ <span class=\"plain\">}</span></pre></div>
86
+ EOS
87
+ assert_equal expected, output
88
+ end
89
+
90
+ def test_dump_nested_array
91
+ json_schema = {
92
+ "type" => "array",
93
+ "required" => true,
94
+ "items" => [
95
+ {
96
+ "type" => "array",
97
+ "items" => [
98
+ { "type" => "number", },
99
+ { "type" => "number", },
100
+ ],
101
+ },
102
+ ]
103
+ }
104
+ output = ""
105
+ Respect::JSONSchemaHTMLFormatter.new(json_schema).dump(output)
106
+ expected = <<-EOS.strip_heredoc
107
+ <div class=\"json_highlight\"><pre><span class=\"plain\">{</span>
108
+ <span class=\"key\">\"type\"</span><span class=\"plain\">:</span> <span class=\"string\">\"array\"</span><span class=\"plain\">,</span>
109
+ <span class=\"key\">\"required\"</span><span class=\"plain\">:</span> <span class=\"keyword\">true</span><span class=\"plain\">,</span>
110
+ <span class=\"key\">\"items\"</span><span class=\"plain\">:</span> <span class=\"plain\">[</span>
111
+ <span class=\"plain\">{</span>
112
+ <span class=\"key\">\"type\"</span><span class=\"plain\">:</span> <span class=\"string\">\"array\"</span><span class=\"plain\">,</span>
113
+ <span class=\"key\">\"items\"</span><span class=\"plain\">:</span> <span class=\"plain\">[</span>
114
+ <span class=\"plain\">{</span>
115
+ <span class=\"key\">\"type\"</span><span class=\"plain\">:</span> <span class=\"string\">\"number\"</span>
116
+ <span class=\"plain\">}</span><span class=\"plain\">,</span>
117
+ <span class=\"plain\">{</span>
118
+ <span class=\"key\">\"type\"</span><span class=\"plain\">:</span> <span class=\"string\">\"number\"</span>
119
+ <span class=\"plain\">}</span>
120
+ <span class=\"plain\">]</span>
121
+ <span class=\"plain\">}</span>
122
+ <span class=\"plain\">]</span>
123
+ <span class=\"plain\">}</span></pre></div>
124
+ EOS
125
+ assert_equal expected, output
126
+ end
127
+
128
+ def test_doc_extraction
129
+ json_schema = {
130
+ "type" => "object",
131
+ "properties" => {
132
+ "param1" => {
133
+ "type" => "integer",
134
+ "title" => "A parameter",
135
+ "description" => "An important parameter that should be equal to 42.\nYes really!.",
136
+ "required" => true,
137
+ "enum" => [
138
+ 42
139
+ ]
140
+ }
141
+ }
142
+ }
143
+ output = ""
144
+ Respect::JSONSchemaHTMLFormatter.new(json_schema).dump(output)
145
+ expected = <<-EOS.strip_heredoc
146
+ <div class=\"json_highlight\"><pre><span class=\"plain\">{</span>
147
+ <span class=\"key\">\"type\"</span><span class=\"plain\">:</span> <span class=\"string\">\"object\"</span><span class=\"plain\">,</span>
148
+ <span class=\"key\">\"properties\"</span><span class=\"plain\">:</span> <span class=\"plain\">{</span>
149
+ <span class=\"comment\">// A parameter
150
+ //
151
+ // An important parameter that should be equal to 42.
152
+ // Yes really!.</span>
153
+ <span class=\"key\">\"param1\"</span><span class=\"plain\">:</span> <span class=\"plain\">{</span>
154
+ <span class=\"key\">\"type\"</span><span class=\"plain\">:</span> <span class=\"string\">\"integer\"</span><span class=\"plain\">,</span>
155
+ <span class=\"key\">\"required\"</span><span class=\"plain\">:</span> <span class=\"keyword\">true</span><span class=\"plain\">,</span>
156
+ <span class=\"key\">\"enum\"</span><span class=\"plain\">:</span> <span class=\"plain\">[</span>
157
+ <span class=\"numeric\">42</span>
158
+ <span class=\"plain\">]</span>
159
+ <span class=\"plain\">}</span>
160
+ <span class=\"plain\">}</span>
161
+ <span class=\"plain\">}</span></pre></div>
162
+ EOS
163
+ assert_equal expected, output
164
+ end
165
+
166
+ def test_custom_css_class
167
+ json_schema = {
168
+ "type" => "object",
169
+ "properties" => {
170
+ "param1" => {
171
+ "type" => "integer",
172
+ "title" => "A parameter",
173
+ "description" => "An important parameter that should be equal to 42.\nYes really!.",
174
+ "required" => true,
175
+ "enum" => [
176
+ 42
177
+ ]
178
+ }
179
+ }
180
+ }
181
+ output = ""
182
+ f = Respect::JSONSchemaHTMLFormatter.new(json_schema)
183
+ f.css_class = {
184
+ json_highlight: "h_class",
185
+ plain: "p_class",
186
+ key: "k_class",
187
+ keyword: "kw_class",
188
+ string: "s_class",
189
+ numeric: "n_class",
190
+ comment: "c_class",
191
+ }
192
+ f.dump(output)
193
+ expected = <<-EOS.strip_heredoc
194
+ <div class=\"h_class\"><pre><span class=\"p_class\">{</span>
195
+ <span class=\"k_class\">\"type\"</span><span class=\"p_class\">:</span> <span class=\"s_class\">\"object\"</span><span class=\"p_class\">,</span>
196
+ <span class=\"k_class\">\"properties\"</span><span class=\"p_class\">:</span> <span class=\"p_class\">{</span>
197
+ <span class=\"c_class\">// A parameter
198
+ //
199
+ // An important parameter that should be equal to 42.
200
+ // Yes really!.</span>
201
+ <span class=\"k_class\">\"param1\"</span><span class=\"p_class\">:</span> <span class=\"p_class\">{</span>
202
+ <span class=\"k_class\">\"type\"</span><span class=\"p_class\">:</span> <span class=\"s_class\">\"integer\"</span><span class=\"p_class\">,</span>
203
+ <span class=\"k_class\">\"required\"</span><span class=\"p_class\">:</span> <span class=\"kw_class\">true</span><span class=\"p_class\">,</span>
204
+ <span class=\"k_class\">\"enum\"</span><span class=\"p_class\">:</span> <span class=\"p_class\">[</span>
205
+ <span class=\"n_class\">42</span>
206
+ <span class=\"p_class\">]</span>
207
+ <span class=\"p_class\">}</span>
208
+ <span class=\"p_class\">}</span>
209
+ <span class=\"p_class\">}</span></pre></div>
210
+ EOS
211
+ assert_equal expected, output
212
+ end
213
+
214
+ end