prmd 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/Gemfile.lock +3 -1
- data/Rakefile +1 -1
- data/bin/prmd +6 -3
- data/docs/schemata.md +4 -2
- data/lib/prmd.rb +1 -0
- data/lib/prmd/commands/combine.rb +12 -2
- data/lib/prmd/commands/render.rb +9 -1
- data/lib/prmd/commands/verify.rb +39 -75
- data/lib/prmd/schema.rb +8 -4
- data/lib/prmd/template.rb +19 -0
- data/lib/prmd/templates/schema.erb +13 -8
- data/lib/prmd/templates/schemata.erb +17 -146
- data/lib/prmd/templates/schemata/helper.erb +80 -0
- data/lib/prmd/templates/schemata/link.erb +58 -0
- data/lib/prmd/templates/schemata/link_curl_example.erb +25 -0
- data/lib/prmd/version.rb +1 -1
- data/prmd.gemspec +1 -0
- data/schemas/hyper-schema.json +168 -0
- data/schemas/interagent-hyper-schema.json +175 -0
- data/schemas/schema.json +150 -0
- data/test/commands/verify_test.rb +187 -0
- data/test/helpers.rb +1 -0
- metadata +25 -2
data/schemas/schema.json
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
{
|
2
|
+
"id": "http://json-schema.org/draft-04/schema#",
|
3
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
4
|
+
"description": "Core schema meta-schema",
|
5
|
+
"definitions": {
|
6
|
+
"schemaArray": {
|
7
|
+
"type": "array",
|
8
|
+
"minItems": 1,
|
9
|
+
"items": { "$ref": "#" }
|
10
|
+
},
|
11
|
+
"positiveInteger": {
|
12
|
+
"type": "integer",
|
13
|
+
"minimum": 0
|
14
|
+
},
|
15
|
+
"positiveIntegerDefault0": {
|
16
|
+
"allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
|
17
|
+
},
|
18
|
+
"simpleTypes": {
|
19
|
+
"enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
|
20
|
+
},
|
21
|
+
"stringArray": {
|
22
|
+
"type": "array",
|
23
|
+
"items": { "type": "string" },
|
24
|
+
"minItems": 1,
|
25
|
+
"uniqueItems": true
|
26
|
+
}
|
27
|
+
},
|
28
|
+
"type": "object",
|
29
|
+
"properties": {
|
30
|
+
"id": {
|
31
|
+
"type": "string",
|
32
|
+
"format": "uri"
|
33
|
+
},
|
34
|
+
"$schema": {
|
35
|
+
"type": "string",
|
36
|
+
"format": "uri"
|
37
|
+
},
|
38
|
+
"title": {
|
39
|
+
"type": "string"
|
40
|
+
},
|
41
|
+
"description": {
|
42
|
+
"type": "string"
|
43
|
+
},
|
44
|
+
"default": {},
|
45
|
+
"multipleOf": {
|
46
|
+
"type": "number",
|
47
|
+
"minimum": 0,
|
48
|
+
"exclusiveMinimum": true
|
49
|
+
},
|
50
|
+
"maximum": {
|
51
|
+
"type": "number"
|
52
|
+
},
|
53
|
+
"exclusiveMaximum": {
|
54
|
+
"type": "boolean",
|
55
|
+
"default": false
|
56
|
+
},
|
57
|
+
"minimum": {
|
58
|
+
"type": "number"
|
59
|
+
},
|
60
|
+
"exclusiveMinimum": {
|
61
|
+
"type": "boolean",
|
62
|
+
"default": false
|
63
|
+
},
|
64
|
+
"maxLength": { "$ref": "#/definitions/positiveInteger" },
|
65
|
+
"minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
66
|
+
"pattern": {
|
67
|
+
"type": "string",
|
68
|
+
"format": "regex"
|
69
|
+
},
|
70
|
+
"additionalItems": {
|
71
|
+
"anyOf": [
|
72
|
+
{ "type": "boolean" },
|
73
|
+
{ "$ref": "#" }
|
74
|
+
],
|
75
|
+
"default": {}
|
76
|
+
},
|
77
|
+
"items": {
|
78
|
+
"anyOf": [
|
79
|
+
{ "$ref": "#" },
|
80
|
+
{ "$ref": "#/definitions/schemaArray" }
|
81
|
+
],
|
82
|
+
"default": {}
|
83
|
+
},
|
84
|
+
"maxItems": { "$ref": "#/definitions/positiveInteger" },
|
85
|
+
"minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
86
|
+
"uniqueItems": {
|
87
|
+
"type": "boolean",
|
88
|
+
"default": false
|
89
|
+
},
|
90
|
+
"maxProperties": { "$ref": "#/definitions/positiveInteger" },
|
91
|
+
"minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
92
|
+
"required": { "$ref": "#/definitions/stringArray" },
|
93
|
+
"additionalProperties": {
|
94
|
+
"anyOf": [
|
95
|
+
{ "type": "boolean" },
|
96
|
+
{ "$ref": "#" }
|
97
|
+
],
|
98
|
+
"default": {}
|
99
|
+
},
|
100
|
+
"definitions": {
|
101
|
+
"type": "object",
|
102
|
+
"additionalProperties": { "$ref": "#" },
|
103
|
+
"default": {}
|
104
|
+
},
|
105
|
+
"properties": {
|
106
|
+
"type": "object",
|
107
|
+
"additionalProperties": { "$ref": "#" },
|
108
|
+
"default": {}
|
109
|
+
},
|
110
|
+
"patternProperties": {
|
111
|
+
"type": "object",
|
112
|
+
"additionalProperties": { "$ref": "#" },
|
113
|
+
"default": {}
|
114
|
+
},
|
115
|
+
"dependencies": {
|
116
|
+
"type": "object",
|
117
|
+
"additionalProperties": {
|
118
|
+
"anyOf": [
|
119
|
+
{ "$ref": "#" },
|
120
|
+
{ "$ref": "#/definitions/stringArray" }
|
121
|
+
]
|
122
|
+
}
|
123
|
+
},
|
124
|
+
"enum": {
|
125
|
+
"type": "array",
|
126
|
+
"minItems": 1,
|
127
|
+
"uniqueItems": true
|
128
|
+
},
|
129
|
+
"type": {
|
130
|
+
"anyOf": [
|
131
|
+
{ "$ref": "#/definitions/simpleTypes" },
|
132
|
+
{
|
133
|
+
"type": "array",
|
134
|
+
"items": { "$ref": "#/definitions/simpleTypes" },
|
135
|
+
"minItems": 1,
|
136
|
+
"uniqueItems": true
|
137
|
+
}
|
138
|
+
]
|
139
|
+
},
|
140
|
+
"allOf": { "$ref": "#/definitions/schemaArray" },
|
141
|
+
"anyOf": { "$ref": "#/definitions/schemaArray" },
|
142
|
+
"oneOf": { "$ref": "#/definitions/schemaArray" },
|
143
|
+
"not": { "$ref": "#" }
|
144
|
+
},
|
145
|
+
"dependencies": {
|
146
|
+
"exclusiveMaximum": [ "maximum" ],
|
147
|
+
"exclusiveMinimum": [ "minimum" ]
|
148
|
+
},
|
149
|
+
"default": {}
|
150
|
+
}
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helpers'))
|
2
|
+
|
3
|
+
require "json_pointer"
|
4
|
+
|
5
|
+
class InteragentHyperSchemaVerifyTest < Minitest::Test
|
6
|
+
def test_verifies
|
7
|
+
assert_equal [], verify
|
8
|
+
end
|
9
|
+
|
10
|
+
#
|
11
|
+
# api (root)
|
12
|
+
#
|
13
|
+
|
14
|
+
def test_api_required
|
15
|
+
data.delete("title")
|
16
|
+
errors = verify
|
17
|
+
assert_equal 1, errors.count
|
18
|
+
assert_match %r{^#: }, errors[0]
|
19
|
+
assert_match %r{Missing required keys "title" in object}, errors[0]
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_api_property_format
|
23
|
+
pointer("#/properties").merge!({
|
24
|
+
"app" => {}
|
25
|
+
})
|
26
|
+
errors = verify
|
27
|
+
assert_match %r{^#/properties/app: }, errors[0]
|
28
|
+
assert_match %r{Missing required keys "\$ref" in object}, errors[0]
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# resource
|
33
|
+
#
|
34
|
+
|
35
|
+
def test_resource_required
|
36
|
+
pointer("#/definitions/app").delete("title")
|
37
|
+
errors = verify
|
38
|
+
assert_equal 1, errors.count
|
39
|
+
assert_match %r{^#/definitions/app: }, errors[0]
|
40
|
+
assert_match %r{Missing required keys "title" in object}, errors[0]
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_resource_identity_format
|
44
|
+
pointer("#/definitions/app/definitions/identity").merge!({
|
45
|
+
"type" => "string"
|
46
|
+
})
|
47
|
+
errors = verify
|
48
|
+
assert_equal 1, errors.count
|
49
|
+
assert_match %r{^#/definitions/app/definitions/identity: }, errors[0]
|
50
|
+
assert_match %r{any subschema of "anyOf" condition.}, errors[0]
|
51
|
+
end
|
52
|
+
|
53
|
+
# an empty schema can be specified to bypass the identity check
|
54
|
+
def test_resource_identity_format_empty
|
55
|
+
pointer("#/definitions/app/definitions").merge!({
|
56
|
+
"identity" => {}
|
57
|
+
})
|
58
|
+
assert_equal [], verify
|
59
|
+
end
|
60
|
+
|
61
|
+
# "my-property" does match fit our regex of lowercase letters and underscores only
|
62
|
+
def test_resource_property_format
|
63
|
+
pointer("#/definitions/app/properties").merge!({
|
64
|
+
"my-property" => {}
|
65
|
+
})
|
66
|
+
errors = verify
|
67
|
+
assert_equal 1, errors.count
|
68
|
+
assert_match %r{^#/definitions/app/properties: }, errors[0]
|
69
|
+
assert_match %r{Extra keys in object: my-property}, errors[0]
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_resource_strict_properties
|
73
|
+
pointer("#/definitions/app").merge!({
|
74
|
+
"strictProperties" => false
|
75
|
+
})
|
76
|
+
errors = verify
|
77
|
+
assert_equal 1, errors.count
|
78
|
+
assert_match %r{^#/definitions/app/strictProperties: }, errors[0]
|
79
|
+
assert_match %r{to be a member of enum \[true\], value was: false}, errors[0]
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# resource definition
|
84
|
+
#
|
85
|
+
|
86
|
+
def test_resource_definition_no_links
|
87
|
+
pointer("#/definitions/app/definitions/name").merge!({
|
88
|
+
"links" => []
|
89
|
+
})
|
90
|
+
errors = verify
|
91
|
+
assert_equal 1, errors.count
|
92
|
+
assert_match %r{^#/definitions/app/definitions/name: }, errors[0]
|
93
|
+
assert_match %r{Data matched subschema of "not" condition}, errors[0]
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_resource_definition_required
|
97
|
+
pointer("#/definitions/app/definitions/name").delete("description")
|
98
|
+
errors = verify
|
99
|
+
assert_equal 1, errors.count
|
100
|
+
assert_match %r{^#/definitions/app/definitions/name: }, errors[0]
|
101
|
+
assert_match %r{Missing required keys "description" in object}, errors[0]
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# resource link
|
106
|
+
#
|
107
|
+
|
108
|
+
def test_resource_link_href_format
|
109
|
+
pointer("#/definitions/app/links/0").merge!({
|
110
|
+
"href" => "/my_apps"
|
111
|
+
})
|
112
|
+
errors = verify
|
113
|
+
assert_equal 1, errors.count
|
114
|
+
assert_match %r{^#/definitions/app/links/0/href: }, errors[0]
|
115
|
+
assert_match %r{Expected string to match pattern}, errors[0]
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_resource_link_required
|
119
|
+
pointer("#/definitions/app/links/0").delete("method")
|
120
|
+
errors = verify
|
121
|
+
assert_equal 1, errors.count
|
122
|
+
assert_match %r{^#/definitions/app/links/0: }, errors[0]
|
123
|
+
assert_match %r{Missing required keys "method" in object}, errors[0]
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def data
|
129
|
+
@data ||= {
|
130
|
+
"$schema" => "http://interagent.github.io/interagent-hyper-schema",
|
131
|
+
"description" => "My simple example API.",
|
132
|
+
"id" => "http://example.com/schema",
|
133
|
+
"title" => "Example API",
|
134
|
+
"definitions" => {
|
135
|
+
"app" => {
|
136
|
+
"description" => "An app in our PaaS ecosystem.",
|
137
|
+
"title" => "App",
|
138
|
+
"type" => "object",
|
139
|
+
"definitions" => {
|
140
|
+
"identity" => {
|
141
|
+
"anyOf" => [
|
142
|
+
{
|
143
|
+
"$ref" => "#/definitions/app/definitions/name"
|
144
|
+
}
|
145
|
+
]
|
146
|
+
},
|
147
|
+
"name" => {
|
148
|
+
"description" => "The app's name.",
|
149
|
+
"type" => "string"
|
150
|
+
}
|
151
|
+
},
|
152
|
+
"links" => [
|
153
|
+
{
|
154
|
+
"description" => "Create a new app.",
|
155
|
+
"href" => "/apps",
|
156
|
+
"method" => "POST",
|
157
|
+
"rel" => "create",
|
158
|
+
"title" => "Create App"
|
159
|
+
}
|
160
|
+
],
|
161
|
+
"properties" => {
|
162
|
+
}
|
163
|
+
}
|
164
|
+
},
|
165
|
+
"links" => [
|
166
|
+
{
|
167
|
+
"href" => "https://example.com",
|
168
|
+
"rel" => "self"
|
169
|
+
}
|
170
|
+
],
|
171
|
+
"properties" => {
|
172
|
+
"app" => {
|
173
|
+
"$ref" => "#/definitions/app"
|
174
|
+
}
|
175
|
+
},
|
176
|
+
"type" => "object"
|
177
|
+
}
|
178
|
+
end
|
179
|
+
|
180
|
+
def pointer(path)
|
181
|
+
JsonPointer.evaluate(data, path)
|
182
|
+
end
|
183
|
+
|
184
|
+
def verify
|
185
|
+
Prmd.verify(data)
|
186
|
+
end
|
187
|
+
end
|
data/test/helpers.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prmd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- geemus
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: erubis
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: json_schema
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.1'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,11 +106,19 @@ files:
|
|
92
106
|
- lib/prmd/commands/render.rb
|
93
107
|
- lib/prmd/commands/verify.rb
|
94
108
|
- lib/prmd/schema.rb
|
109
|
+
- lib/prmd/template.rb
|
95
110
|
- lib/prmd/templates/link_schema_properties.erb
|
96
111
|
- lib/prmd/templates/schema.erb
|
97
112
|
- lib/prmd/templates/schemata.erb
|
113
|
+
- lib/prmd/templates/schemata/helper.erb
|
114
|
+
- lib/prmd/templates/schemata/link.erb
|
115
|
+
- lib/prmd/templates/schemata/link_curl_example.erb
|
98
116
|
- lib/prmd/version.rb
|
99
117
|
- prmd.gemspec
|
118
|
+
- schemas/hyper-schema.json
|
119
|
+
- schemas/interagent-hyper-schema.json
|
120
|
+
- schemas/schema.json
|
121
|
+
- test/commands/verify_test.rb
|
100
122
|
- test/helpers.rb
|
101
123
|
- test/schema_test.rb
|
102
124
|
- test/schemata/input/meta.json
|
@@ -126,6 +148,7 @@ signing_key:
|
|
126
148
|
specification_version: 4
|
127
149
|
summary: JSON Schema tooling
|
128
150
|
test_files:
|
151
|
+
- test/commands/verify_test.rb
|
129
152
|
- test/helpers.rb
|
130
153
|
- test/schema_test.rb
|
131
154
|
- test/schemata/input/meta.json
|