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,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