apiary_blueprint_convertor 0.1.1
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 +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +14 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +47 -0
- data/LICENSE +22 -0
- data/README.md +40 -0
- data/Rakefile +21 -0
- data/apiary_blueprint_convertor.gemspec +26 -0
- data/bin/apiary_blueprint_convertor +3 -0
- data/features/convert.feature +321 -0
- data/features/step_definitions/file_content_step.rb +8 -0
- data/features/support/setup.rb +1 -0
- data/lib/apiary_blueprint_convertor/cli.rb +65 -0
- data/lib/apiary_blueprint_convertor/convertor.rb +319 -0
- data/lib/apiary_blueprint_convertor/version.rb +3 -0
- data/lib/apiary_blueprint_convertor.rb +5 -0
- data/lib/object.rb +14 -0
- data/test/convertor_test.rb +241 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 848054e783c9a61d69e0a2be0dbdb0eef16a7388
|
4
|
+
data.tar.gz: 963c51bb0f6b0ec32a8dd973d3f613973acc2741
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6060f1dc3dad96ce6af4b5bac882272496cb59d4b27f440806f676a278ce95a77100eaa4bc102c2f3d3dc397d6a3d11bc5b0e4e46b829bef447a8cb127215db6
|
7
|
+
data.tar.gz: 7be67e76e709b687ca30cfe4754f15f5f30ff37c1f50b71a796f24e230c558b99b0cf70f673bbcc0c002f42aff5bcd3336712f25ed397738ce5f6ffa991cfc0f
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 1.9.3
|
4
|
+
- 2.1.0
|
5
|
+
before_install: gem update bundler
|
6
|
+
notifications:
|
7
|
+
email:
|
8
|
+
recipients:
|
9
|
+
- z@apiary.io
|
10
|
+
on_success: change
|
11
|
+
on_failure: always
|
12
|
+
hipchat:
|
13
|
+
secure: "JT63QEBAHHbcM9MiLheYGfpztUCnzwcDuOXmn9A96J9DqMvinOlEhLW2sl0aGr9YsF8mXY9zB03KglpSeP9yLZyroAPjIqNGh2+eLFy+v/ELpDBW4EA1XwBNwz1CvHSReJWupujTSHiV9r4+WPPIb0+KIsqPsOvbh1sGPMhulkA="
|
14
|
+
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/cucumber/aruba.git
|
3
|
+
revision: 99d8e6a5992af17b014783e775409bc3fd422273
|
4
|
+
specs:
|
5
|
+
aruba (0.5.4)
|
6
|
+
childprocess (>= 0.3.6)
|
7
|
+
cucumber (>= 1.1.1)
|
8
|
+
rspec-expectations (>= 2.7.0)
|
9
|
+
|
10
|
+
PATH
|
11
|
+
remote: .
|
12
|
+
specs:
|
13
|
+
apiary_blueprint_convertor (0.1.1)
|
14
|
+
|
15
|
+
GEM
|
16
|
+
remote: https://rubygems.org/
|
17
|
+
specs:
|
18
|
+
builder (3.2.2)
|
19
|
+
childprocess (0.3.9)
|
20
|
+
ffi (~> 1.0, >= 1.0.11)
|
21
|
+
cucumber (1.3.10)
|
22
|
+
builder (>= 2.1.2)
|
23
|
+
diff-lcs (>= 1.1.3)
|
24
|
+
gherkin (~> 2.12)
|
25
|
+
multi_json (>= 1.7.5, < 2.0)
|
26
|
+
multi_test (>= 0.0.2)
|
27
|
+
diff-lcs (1.2.5)
|
28
|
+
ffi (1.9.3)
|
29
|
+
gherkin (2.12.2)
|
30
|
+
multi_json (~> 1.3)
|
31
|
+
minitest (5.2.1)
|
32
|
+
multi_json (1.8.4)
|
33
|
+
multi_test (0.0.3)
|
34
|
+
rake (10.1.1)
|
35
|
+
rspec-expectations (2.14.4)
|
36
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
37
|
+
|
38
|
+
PLATFORMS
|
39
|
+
ruby
|
40
|
+
|
41
|
+
DEPENDENCIES
|
42
|
+
apiary_blueprint_convertor!
|
43
|
+
aruba!
|
44
|
+
bundler (~> 1.5)
|
45
|
+
cucumber
|
46
|
+
minitest
|
47
|
+
rake
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Apiary Inc. <support@apiary.io>.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Apiary Blueprint AST Convertor [](https://travis-ci.org/apiaryio/apiary_blueprint_convertor)
|
2
|
+
A migration tool for legacy [Apiary Blueprint](https://github.com/apiaryio/blueprint-parser) AST into [API Blueprint](http://apiblueprint.org) AST. Converts Apiary Blueprint AST serialized into a JSON file to [API Blueprint AST](https://github.com/apiaryio/snowcrash/wiki/API-Blueprint-AST-Media-Types) JSON representation (`vnd.apiblueprint.ast.raw+json; version=1.0`).
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
Add this line to your application's Gemfile:
|
6
|
+
|
7
|
+
gem 'apiary_blueprint_convertor'
|
8
|
+
|
9
|
+
And then execute:
|
10
|
+
|
11
|
+
$ bundle
|
12
|
+
|
13
|
+
Or install it yourself as:
|
14
|
+
|
15
|
+
$ gem install apiary_blueprint_convertor
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
```sh
|
20
|
+
$ apiary_blueprint_convertor path/to/legacy/ast.json
|
21
|
+
```
|
22
|
+
|
23
|
+
See the [convert feature](features/convert.feature) for details or run `apiary_blueprint_convertor --help`.
|
24
|
+
|
25
|
+
### Convert Legacy Apiary Blueprint to API Blueprint
|
26
|
+
Use this convertor together with the legacy [Apiary Blueprint Parser](https://github.com/apiaryio/blueprint-parser) and API Blueprint Composer – [Matter Compiler](https://github.com/apiaryio/matter_compiler).
|
27
|
+
|
28
|
+
1. Parse Legacy Apiary Blueprint into its JSON AST using `Apiary Blueprint Parser`
|
29
|
+
2. Convert legacy JSON AST into API Blueprint JSON AST using `apiary_blueprint_convertor`
|
30
|
+
3. Compose API Blueprint from API Blueprint JSON AST using `matter_compiler`
|
31
|
+
|
32
|
+
## Contributing
|
33
|
+
1. Fork this repository (http://github.com/apiaryio/apiary_blueprint_convertor/fork)
|
34
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
35
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
36
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
37
|
+
5. Create new Pull Request
|
38
|
+
|
39
|
+
## License
|
40
|
+
MIT License. See the [LICENSE](LICENSE) file.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'cucumber/rake/task'
|
4
|
+
|
5
|
+
Rake::TestTask.new do |t|
|
6
|
+
t.libs.push "lib"
|
7
|
+
t.test_files = FileList['test/*_test.rb']
|
8
|
+
t.verbose = true
|
9
|
+
end
|
10
|
+
|
11
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
12
|
+
t.cucumber_opts = "features --format pretty"
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Run all CI tests"
|
16
|
+
task :test_ci do
|
17
|
+
Rake::Task['test'].invoke
|
18
|
+
Rake::Task['features'].invoke
|
19
|
+
end
|
20
|
+
|
21
|
+
task :default => :test_ci
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'apiary_blueprint_convertor/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "apiary_blueprint_convertor"
|
8
|
+
spec.version = ApiaryBlueprintConvertor::VERSION
|
9
|
+
spec.authors = ["Zdenek Nemec"]
|
10
|
+
spec.email = ["z@apiary.io"]
|
11
|
+
spec.summary = %q{Apiary Blueprint AST convertor.}
|
12
|
+
spec.description = %q{Convert legacy Apiary Blueprint AST into API Blueprint AST (JSON).}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "cucumber"
|
24
|
+
spec.add_development_dependency "minitest"
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,321 @@
|
|
1
|
+
Feature: Convert AST
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given a file named "legacy_ast.json" with:
|
5
|
+
"""
|
6
|
+
{
|
7
|
+
"location": "http://www.google.com/",
|
8
|
+
"name": "Sample API v2",
|
9
|
+
"description": "Welcome to our sample API documentation. All comments can be written in (support [Markdown](http://daringfireball.net/projects/markdown/syntax) syntax)",
|
10
|
+
"sections": [
|
11
|
+
{
|
12
|
+
"name": "Shopping Cart Resources",
|
13
|
+
"description": "The following is a section of resources related to the shopping cart",
|
14
|
+
"resources": [
|
15
|
+
{
|
16
|
+
"description": "List products added into your shopping-cart. (comment block again in Markdown)",
|
17
|
+
"method": "GET",
|
18
|
+
"url": "/shopping-cart",
|
19
|
+
"request": {
|
20
|
+
"headers": {},
|
21
|
+
"body": null
|
22
|
+
},
|
23
|
+
"responses": [
|
24
|
+
{
|
25
|
+
"status": 200,
|
26
|
+
"headers": {
|
27
|
+
"Content-Type": "application/json"
|
28
|
+
},
|
29
|
+
"body": "{\n \"items\": [\n {\n \"url\": \"/shopping-cart/1\",\n \"product\": \"2ZY48XPZ\",\n \"quantity\": 1,\n \"name\": \"New socks\",\n \"price\": 1.25\n }\n ]\n}"
|
30
|
+
}
|
31
|
+
]
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"description": "Save new products in your shopping cart",
|
35
|
+
"method": "POST",
|
36
|
+
"url": "/shopping-cart",
|
37
|
+
"request": {
|
38
|
+
"headers": {
|
39
|
+
"Content-Type": "application/json"
|
40
|
+
},
|
41
|
+
"body": "{\n \"product\": \"1AB23ORM\",\n \"quantity\": 2\n}"
|
42
|
+
},
|
43
|
+
"responses": [
|
44
|
+
{
|
45
|
+
"status": 201,
|
46
|
+
"headers": {
|
47
|
+
"Content-Type": "application/json"
|
48
|
+
},
|
49
|
+
"body": "{\n \"status\": \"created\",\n \"url\": \"/shopping-cart/2\"\n}"
|
50
|
+
},
|
51
|
+
{
|
52
|
+
"status": 401,
|
53
|
+
"headers": {
|
54
|
+
"Content-Type": "application/json; charset=utf-8"
|
55
|
+
},
|
56
|
+
"body": "{\n \"message\": \"You have not provided proper request token\"\n}"
|
57
|
+
}
|
58
|
+
]
|
59
|
+
}
|
60
|
+
]
|
61
|
+
},
|
62
|
+
{
|
63
|
+
"name": "Payment Resources",
|
64
|
+
"description": null,
|
65
|
+
"resources": [
|
66
|
+
{
|
67
|
+
"description": "This resource allows you to submit payment information to process your *shopping cart* items",
|
68
|
+
"method": "POST",
|
69
|
+
"url": "/payment",
|
70
|
+
"request": {
|
71
|
+
"headers": {},
|
72
|
+
"body": "{\n \"cc\": \"12345678900\",\n \"cvc\": \"123\",\n \"expiry\": \"0112\"\n}"
|
73
|
+
},
|
74
|
+
"responses": [
|
75
|
+
{
|
76
|
+
"status": 200,
|
77
|
+
"headers": {},
|
78
|
+
"body": "{\n \"receipt\": \"/payment/receipt/1\"\n}"
|
79
|
+
}
|
80
|
+
]
|
81
|
+
},
|
82
|
+
{
|
83
|
+
"description": null,
|
84
|
+
"method": "POST",
|
85
|
+
"url": "/resource",
|
86
|
+
"request": {
|
87
|
+
"headers": {
|
88
|
+
"Content-Type": "application/json"
|
89
|
+
},
|
90
|
+
"body": "{\n \"a\": \"b\",\n \"c\": \"0\"\n}"
|
91
|
+
},
|
92
|
+
"responses": [
|
93
|
+
{
|
94
|
+
"status": 200,
|
95
|
+
"headers": {},
|
96
|
+
"body": "{\n \"status\": \"ok\"\n}"
|
97
|
+
}
|
98
|
+
]
|
99
|
+
}
|
100
|
+
]
|
101
|
+
}
|
102
|
+
],
|
103
|
+
"validations": [
|
104
|
+
{
|
105
|
+
"method": "POST",
|
106
|
+
"url": "/resource",
|
107
|
+
"body": "{\n \"request\": {\n \"type\": \"object\",\n \"properties\": {\n \"a\": {\n \"type\": \"string\",\n \"format\": \"alphanumeric\"\n },\n \"c\": {\n \"type\": \"integer\"\n }\n }\n },\n \"response\": {\n \"type\": \"object\",\n \"properties\": {\n \"status\": {\n \"type\": \"string\",\n \"format\": \"alphanumeric\"\n }\n }\n }\n}"
|
108
|
+
}
|
109
|
+
]
|
110
|
+
}
|
111
|
+
"""
|
112
|
+
|
113
|
+
Given a file named "apiblueprint_ast.json" with:
|
114
|
+
"""
|
115
|
+
{
|
116
|
+
"_version": "1.0",
|
117
|
+
"metadata": {
|
118
|
+
"HOST": {
|
119
|
+
"value": "http://www.google.com/"
|
120
|
+
}
|
121
|
+
},
|
122
|
+
"name": "Sample API v2",
|
123
|
+
"description": "Welcome to our sample API documentation. All comments can be written in (support [Markdown](http://daringfireball.net/projects/markdown/syntax) syntax)",
|
124
|
+
"resourceGroups": [
|
125
|
+
{
|
126
|
+
"name": "Shopping Cart Resources",
|
127
|
+
"description": "The following is a section of resources related to the shopping cart",
|
128
|
+
"resources": [
|
129
|
+
{
|
130
|
+
"name": null,
|
131
|
+
"description": null,
|
132
|
+
"uriTemplate": "/shopping-cart",
|
133
|
+
"model": null,
|
134
|
+
"parameters": null,
|
135
|
+
"headers": null,
|
136
|
+
"actions": [
|
137
|
+
{
|
138
|
+
"name": null,
|
139
|
+
"description": "List products added into your shopping-cart. (comment block again in Markdown)",
|
140
|
+
"method": "GET",
|
141
|
+
"parameters": null,
|
142
|
+
"headers": null,
|
143
|
+
"examples": [
|
144
|
+
{
|
145
|
+
"name": null,
|
146
|
+
"description": null,
|
147
|
+
"requests": null,
|
148
|
+
"responses": [
|
149
|
+
{
|
150
|
+
"name": "200",
|
151
|
+
"description": null,
|
152
|
+
"headers": {
|
153
|
+
"Content-Type": {
|
154
|
+
"value": "application/json"
|
155
|
+
}
|
156
|
+
},
|
157
|
+
"body": "{\n \"items\": [\n {\n \"url\": \"/shopping-cart/1\",\n \"product\": \"2ZY48XPZ\",\n \"quantity\": 1,\n \"name\": \"New socks\",\n \"price\": 1.25\n }\n ]\n}",
|
158
|
+
"schema": null
|
159
|
+
}
|
160
|
+
]
|
161
|
+
}
|
162
|
+
]
|
163
|
+
},
|
164
|
+
{
|
165
|
+
"name": null,
|
166
|
+
"description": "Save new products in your shopping cart",
|
167
|
+
"method": "POST",
|
168
|
+
"parameters": null,
|
169
|
+
"headers": null,
|
170
|
+
"examples": [
|
171
|
+
{
|
172
|
+
"name": null,
|
173
|
+
"description": null,
|
174
|
+
"requests": [
|
175
|
+
{
|
176
|
+
"name": null,
|
177
|
+
"description": null,
|
178
|
+
"headers": {
|
179
|
+
"Content-Type": {
|
180
|
+
"value": "application/json"
|
181
|
+
}
|
182
|
+
},
|
183
|
+
"body": "{\n \"product\": \"1AB23ORM\",\n \"quantity\": 2\n}",
|
184
|
+
"schema": null
|
185
|
+
}
|
186
|
+
],
|
187
|
+
"responses": [
|
188
|
+
{
|
189
|
+
"name": "201",
|
190
|
+
"description": null,
|
191
|
+
"headers": {
|
192
|
+
"Content-Type": {
|
193
|
+
"value": "application/json"
|
194
|
+
}
|
195
|
+
},
|
196
|
+
"body": "{\n \"status\": \"created\",\n \"url\": \"/shopping-cart/2\"\n}",
|
197
|
+
"schema": null
|
198
|
+
},
|
199
|
+
{
|
200
|
+
"name": "401",
|
201
|
+
"description": null,
|
202
|
+
"headers": {
|
203
|
+
"Content-Type": {
|
204
|
+
"value": "application/json; charset=utf-8"
|
205
|
+
}
|
206
|
+
},
|
207
|
+
"body": "{\n \"message\": \"You have not provided proper request token\"\n}",
|
208
|
+
"schema": null
|
209
|
+
}
|
210
|
+
]
|
211
|
+
}
|
212
|
+
]
|
213
|
+
}
|
214
|
+
]
|
215
|
+
}
|
216
|
+
]
|
217
|
+
},
|
218
|
+
{
|
219
|
+
"name": "Payment Resources",
|
220
|
+
"description": null,
|
221
|
+
"resources": [
|
222
|
+
{
|
223
|
+
"name": null,
|
224
|
+
"description": null,
|
225
|
+
"uriTemplate": "/payment",
|
226
|
+
"model": null,
|
227
|
+
"parameters": null,
|
228
|
+
"headers": null,
|
229
|
+
"actions": [
|
230
|
+
{
|
231
|
+
"name": null,
|
232
|
+
"description": "This resource allows you to submit payment information to process your *shopping cart* items",
|
233
|
+
"method": "POST",
|
234
|
+
"parameters": null,
|
235
|
+
"headers": null,
|
236
|
+
"examples": [
|
237
|
+
{
|
238
|
+
"name": null,
|
239
|
+
"description": null,
|
240
|
+
"requests": [
|
241
|
+
{
|
242
|
+
"name": null,
|
243
|
+
"description": null,
|
244
|
+
"headers": null,
|
245
|
+
"body": "{\n \"cc\": \"12345678900\",\n \"cvc\": \"123\",\n \"expiry\": \"0112\"\n}",
|
246
|
+
"schema": null
|
247
|
+
}
|
248
|
+
],
|
249
|
+
"responses": [
|
250
|
+
{
|
251
|
+
"name": "200",
|
252
|
+
"description": null,
|
253
|
+
"headers": null,
|
254
|
+
"body": "{\n \"receipt\": \"/payment/receipt/1\"\n}",
|
255
|
+
"schema": null
|
256
|
+
}
|
257
|
+
]
|
258
|
+
}
|
259
|
+
]
|
260
|
+
}
|
261
|
+
]
|
262
|
+
},
|
263
|
+
{
|
264
|
+
"name": null,
|
265
|
+
"description": null,
|
266
|
+
"uriTemplate": "/resource",
|
267
|
+
"model": null,
|
268
|
+
"parameters": null,
|
269
|
+
"headers": null,
|
270
|
+
"actions": [
|
271
|
+
{
|
272
|
+
"name": null,
|
273
|
+
"description": null,
|
274
|
+
"method": "POST",
|
275
|
+
"parameters": null,
|
276
|
+
"headers": null,
|
277
|
+
"examples": [
|
278
|
+
{
|
279
|
+
"name": null,
|
280
|
+
"description": null,
|
281
|
+
"requests": [
|
282
|
+
{
|
283
|
+
"name": null,
|
284
|
+
"description": null,
|
285
|
+
"headers": {
|
286
|
+
"Content-Type": {
|
287
|
+
"value": "application/json"
|
288
|
+
}
|
289
|
+
},
|
290
|
+
"body": "{\n \"a\": \"b\",\n \"c\": \"0\"\n}",
|
291
|
+
"schema": "{\"type\":\"object\",\"properties\":{\"a\":{\"type\":\"string\",\"format\":\"alphanumeric\"},\"c\":{\"type\":\"integer\"}}}"
|
292
|
+
}
|
293
|
+
],
|
294
|
+
"responses": [
|
295
|
+
{
|
296
|
+
"name": "200",
|
297
|
+
"description": null,
|
298
|
+
"headers": null,
|
299
|
+
"body": "{\n \"status\": \"ok\"\n}",
|
300
|
+
"schema": "{\"type\":\"object\",\"properties\":{\"status\":{\"type\":\"string\",\"format\":\"alphanumeric\"}}}"
|
301
|
+
}
|
302
|
+
]
|
303
|
+
}
|
304
|
+
]
|
305
|
+
}
|
306
|
+
]
|
307
|
+
}
|
308
|
+
]
|
309
|
+
}
|
310
|
+
]
|
311
|
+
}
|
312
|
+
"""
|
313
|
+
|
314
|
+
Scenario: Convert Legacy Apiary Blueprint AST into API Blueprint AST
|
315
|
+
When I run `apiary_blueprint_convertor legacy_ast.json`
|
316
|
+
Then the output should contain the content of file "apiblueprint_ast.json"
|
317
|
+
|
318
|
+
Scenario: Convert Legacy Apiary Blueprint AST on STDIN into API Blueprint AST
|
319
|
+
When I run `apiary_blueprint_convertor` interactively
|
320
|
+
When I pipe in the file "legacy_ast.json"
|
321
|
+
Then the output should contain the content of file "apiblueprint_ast.json"
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'aruba/cucumber'
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'apiary_blueprint_convertor/version'
|
3
|
+
require 'apiary_blueprint_convertor/convertor'
|
4
|
+
|
5
|
+
module ApiaryBlueprintConvertor
|
6
|
+
|
7
|
+
class CLI
|
8
|
+
|
9
|
+
attr_reader :command
|
10
|
+
|
11
|
+
def self.start
|
12
|
+
cli = CLI.new
|
13
|
+
options = cli.parse_options!(ARGV)
|
14
|
+
cli.runCommand(ARGV, options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def runCommand(args, options)
|
18
|
+
command = :convert if args.first.nil? || @command.nil?
|
19
|
+
command = @command if @command
|
20
|
+
|
21
|
+
case command
|
22
|
+
when :convert
|
23
|
+
Convertor.convert(args.first)
|
24
|
+
when :version
|
25
|
+
puts ApiaryBlueprintConvertor::VERSION
|
26
|
+
else
|
27
|
+
CLI.help
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def parse_options!(args)
|
32
|
+
@command = nil
|
33
|
+
options = {}
|
34
|
+
options_parser = OptionParser.new do |opts|
|
35
|
+
opts.on('-v', '--version') do
|
36
|
+
@command = :version
|
37
|
+
end
|
38
|
+
|
39
|
+
opts.on( '-h', '--help') do
|
40
|
+
@command = :help
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
options_parser.parse!
|
45
|
+
options
|
46
|
+
|
47
|
+
rescue OptionParser::InvalidOption => e
|
48
|
+
puts e
|
49
|
+
CLI.help
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.help
|
54
|
+
puts "Usage: apiary_blueprint_convertor <legacy ast file>"
|
55
|
+
puts "\nConvert Legacy Apiary Blueprint AST into API Blueprint AST (JSON)."
|
56
|
+
puts "If no <legacy ast file> is specified 'apiary_blueprint_convertor' will listen on stdin."
|
57
|
+
|
58
|
+
puts "\nOptions:\n\n"
|
59
|
+
puts "\t-h, --help Show this help"
|
60
|
+
puts "\t-v, --version Show version"
|
61
|
+
puts "\n"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,319 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'object'
|
3
|
+
|
4
|
+
module ApiaryBlueprintConvertor
|
5
|
+
|
6
|
+
class Convertor
|
7
|
+
|
8
|
+
API_BLUEPRONT_AST_VERSION = "1.0"
|
9
|
+
|
10
|
+
def self.read_file(file)
|
11
|
+
unless File.readable?(file)
|
12
|
+
abort "Unable to read input ast file: #{file.inspect}"
|
13
|
+
end
|
14
|
+
input = File.read(file)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Read file / input and convert the AST
|
18
|
+
def self.convert(file = nil)
|
19
|
+
# Read input
|
20
|
+
input = nil
|
21
|
+
if file.nil?
|
22
|
+
input = $stdin.read
|
23
|
+
else
|
24
|
+
input = self.read_file(file)
|
25
|
+
end
|
26
|
+
|
27
|
+
if input.blank?
|
28
|
+
puts "Empty input, bailing out!"
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
|
32
|
+
legacy_ast = JSON.parse(input).deep_symbolize_keys
|
33
|
+
|
34
|
+
# Top level API Blueprint Template
|
35
|
+
blueprint_ast = {
|
36
|
+
:_version => API_BLUEPRONT_AST_VERSION,
|
37
|
+
:metadata => nil,
|
38
|
+
:name => nil,
|
39
|
+
:description => nil,
|
40
|
+
:resourceGroups => nil
|
41
|
+
}
|
42
|
+
|
43
|
+
# Run the conversion
|
44
|
+
convert_blueprint(legacy_ast, blueprint_ast)
|
45
|
+
|
46
|
+
# Print output to stdou
|
47
|
+
puts JSON.pretty_generate(blueprint_ast)
|
48
|
+
|
49
|
+
rescue JSON::ParserError => e
|
50
|
+
abort("unable to parse input JSON: #{e}")
|
51
|
+
end
|
52
|
+
|
53
|
+
# Convert AST root
|
54
|
+
def self.convert_blueprint(legacy_ast, blueprint_ast)
|
55
|
+
|
56
|
+
# Location key
|
57
|
+
convert_location(legacy_ast[:location], blueprint_ast) if legacy_ast[:location]
|
58
|
+
|
59
|
+
# Name key
|
60
|
+
blueprint_ast[:name] = legacy_ast[:name]
|
61
|
+
|
62
|
+
# Description
|
63
|
+
blueprint_ast[:description] = legacy_ast[:description]
|
64
|
+
|
65
|
+
# Sections
|
66
|
+
convert_sections(legacy_ast[:sections], legacy_ast[:validations], blueprint_ast)
|
67
|
+
|
68
|
+
# NOTE: Validations are processed in `convert_sections`.
|
69
|
+
end
|
70
|
+
|
71
|
+
# Convert Location / Metadata key
|
72
|
+
# \param location ... location to convert
|
73
|
+
# \param blueprint_ast ... output AST
|
74
|
+
def self.convert_location(legacy_location, blueprint_ast)
|
75
|
+
if legacy_location.blank?
|
76
|
+
blueprint_ast[:metadata] = nil
|
77
|
+
return
|
78
|
+
end
|
79
|
+
|
80
|
+
blueprint_ast[:metadata] = {
|
81
|
+
:HOST => {
|
82
|
+
:value => "#{legacy_location}"
|
83
|
+
}
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
# Convert array of blueprint sections
|
88
|
+
# \param legacy_sections ... sections to convert
|
89
|
+
# \param legacy_validations ... legacy validations
|
90
|
+
# \param blueprint_ast ... output AST
|
91
|
+
def self.convert_sections(legacy_sections, legacy_validations, blueprint_ast)
|
92
|
+
resourceGroups = [];
|
93
|
+
legacy_sections.each do |legact_section|
|
94
|
+
group = {
|
95
|
+
:name => legact_section[:name],
|
96
|
+
:description => legact_section[:description],
|
97
|
+
:resources => nil
|
98
|
+
}
|
99
|
+
|
100
|
+
convert_resources(legact_section[:resources], legacy_validations, group)
|
101
|
+
resourceGroups << group
|
102
|
+
end
|
103
|
+
|
104
|
+
blueprint_ast[:resourceGroups] = resourceGroups unless resourceGroups.blank?
|
105
|
+
end
|
106
|
+
|
107
|
+
# Convert all resources of a resource group
|
108
|
+
# \param legacy_resources ... resources to convert
|
109
|
+
# \param legacy_validations ... legacy validations
|
110
|
+
# \param resource_group ... output resource group
|
111
|
+
def self.convert_resources(legacy_resources, legacy_validations, resource_group)
|
112
|
+
resources = [];
|
113
|
+
legacy_resources.each do |legacy_resource|
|
114
|
+
|
115
|
+
resource = find_resource(resources, legacy_resource[:url])
|
116
|
+
|
117
|
+
if (resource)
|
118
|
+
# Existing Resource
|
119
|
+
add_resource_action(legacy_resource, legacy_validations, resource)
|
120
|
+
else
|
121
|
+
# New Resource
|
122
|
+
resource = {
|
123
|
+
:name => nil,
|
124
|
+
:description => nil,
|
125
|
+
:uriTemplate => legacy_resource[:url],
|
126
|
+
:model => nil,
|
127
|
+
:parameters => nil,
|
128
|
+
:headers => nil,
|
129
|
+
:actions => nil
|
130
|
+
}
|
131
|
+
|
132
|
+
add_resource_action(legacy_resource, legacy_validations, resource)
|
133
|
+
resources << resource
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
resource_group[:resources] = resources unless resources.blank?
|
138
|
+
end
|
139
|
+
|
140
|
+
# Look for a resource by URL in array of resources
|
141
|
+
# \returns the matching resource or nil
|
142
|
+
def self.find_resource(resources, uri_template)
|
143
|
+
return nil if resources.blank?
|
144
|
+
matches = resources.select { |resource| resource[:uriTemplate] == uri_template }
|
145
|
+
return matches.blank? ? nil : matches.first
|
146
|
+
end
|
147
|
+
|
148
|
+
# Add an action entry in resources
|
149
|
+
# \param legacy_resource ... resource with action to be converted
|
150
|
+
# \param legacy_validations ... legacy validations
|
151
|
+
# \param resource ... output resource to recieve the action
|
152
|
+
def self.add_resource_action(legacy_resource, legacy_validations, resource)
|
153
|
+
|
154
|
+
action = find_action(resource[:actions], legacy_resource[:method])
|
155
|
+
if action
|
156
|
+
$stderr.write "Ignoring duplicate action definiton for resource '#{resource[:uriTemplate]}' and request method '#{action[:method]}'\n"
|
157
|
+
return
|
158
|
+
end
|
159
|
+
|
160
|
+
action = {
|
161
|
+
:name => nil,
|
162
|
+
:description => legacy_resource[:description],
|
163
|
+
:method => legacy_resource[:method],
|
164
|
+
:parameters => nil,
|
165
|
+
:headers => nil,
|
166
|
+
:examples => nil
|
167
|
+
}
|
168
|
+
|
169
|
+
add_action_example(legacy_resource, legacy_validations, action)
|
170
|
+
|
171
|
+
resource[:actions] = Array.new if resource[:actions].nil?
|
172
|
+
resource[:actions] << action
|
173
|
+
end
|
174
|
+
|
175
|
+
# Look for an action by Method in array of actions
|
176
|
+
# \returns the matching action or nil
|
177
|
+
def self.find_action(actions, method)
|
178
|
+
return nil if actions.blank?
|
179
|
+
matches = actions.select { |action| action[:method] == method }
|
180
|
+
return matches.blank? ? nil : matches.first
|
181
|
+
end
|
182
|
+
|
183
|
+
# Add an example entry in action
|
184
|
+
# \param legacy_resource ... resource with example to be converted
|
185
|
+
# \param legacy_validations ... legacy validations
|
186
|
+
# \param action ... output action to recieve the example
|
187
|
+
def self.add_action_example(legacy_resource, legacy_validations, action)
|
188
|
+
example = {
|
189
|
+
:name => nil,
|
190
|
+
:description => nil,
|
191
|
+
:requests => nil,
|
192
|
+
:responses => nil
|
193
|
+
}
|
194
|
+
|
195
|
+
schema = resource_schema(legacy_resource, legacy_validations)
|
196
|
+
|
197
|
+
# Convert Request
|
198
|
+
if legacy_resource[:request] &&
|
199
|
+
!(legacy_resource[:request][:headers].blank? && legacy_resource[:request][:body].blank?)
|
200
|
+
|
201
|
+
request = {
|
202
|
+
:name => nil,
|
203
|
+
:description => nil,
|
204
|
+
:headers => create_headers_hash(legacy_resource[:request][:headers]),
|
205
|
+
:body => legacy_resource[:request][:body],
|
206
|
+
:schema => (schema) ? schema[:request] : nil
|
207
|
+
}
|
208
|
+
example[:requests] = Array.new
|
209
|
+
example[:requests] << request
|
210
|
+
end
|
211
|
+
|
212
|
+
# Convert resources
|
213
|
+
unless legacy_resource[:responses].blank?
|
214
|
+
example[:responses] = Array.new
|
215
|
+
|
216
|
+
legacy_resource[:responses].each do |legacy_response|
|
217
|
+
response = {
|
218
|
+
:name => "#{legacy_response[:status]}",
|
219
|
+
:description => nil,
|
220
|
+
:headers => create_headers_hash(legacy_response[:headers]),
|
221
|
+
:body => legacy_response[:body],
|
222
|
+
:schema => (schema) ? schema[:response] : nil
|
223
|
+
}
|
224
|
+
|
225
|
+
example[:responses] << response
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
action[:examples] = Array.new if action[:examples].nil?
|
230
|
+
action[:examples] << example
|
231
|
+
end
|
232
|
+
|
233
|
+
# Create an API Blueprint header hash
|
234
|
+
# from legacy headers hash
|
235
|
+
def self.create_headers_hash(legacy_headers)
|
236
|
+
return nil if legacy_headers.blank?
|
237
|
+
headers = {}
|
238
|
+
|
239
|
+
legacy_headers.each do |key, value|
|
240
|
+
headers[key] = {
|
241
|
+
:value => value
|
242
|
+
}
|
243
|
+
end
|
244
|
+
|
245
|
+
headers
|
246
|
+
end
|
247
|
+
|
248
|
+
# Returns legacy resource validation if exists, nil otherwise
|
249
|
+
def self.legacy_resource_validation(legacy_resource, legacy_validations)
|
250
|
+
return nil if legacy_validations.blank?
|
251
|
+
|
252
|
+
matches = legacy_validations.select do |legacy_validation|
|
253
|
+
(legacy_validation[:url] == legacy_resource[:url] &&
|
254
|
+
legacy_validation[:method] == legacy_resource[:method])
|
255
|
+
end
|
256
|
+
|
257
|
+
return nil if matches.blank? || matches.first[:body].blank?
|
258
|
+
|
259
|
+
matches.first[:body]
|
260
|
+
end
|
261
|
+
|
262
|
+
# Attempt to retrieve request and response schema from legacy validations
|
263
|
+
# for given legacy resource
|
264
|
+
def self.resource_schema(legacy_resource, legacy_validations)
|
265
|
+
|
266
|
+
validation = legacy_resource_validation(legacy_resource, legacy_validations)
|
267
|
+
return nil if validation.blank?
|
268
|
+
|
269
|
+
# Attempt to parse validation
|
270
|
+
validation_hash = JSON.parse(validation)
|
271
|
+
validation_hash = validation_hash.deep_symbolize_keys
|
272
|
+
|
273
|
+
schema = {
|
274
|
+
:request => nil,
|
275
|
+
:response => nil
|
276
|
+
}
|
277
|
+
|
278
|
+
if validation_hash.nil?
|
279
|
+
schema[:request] = validation
|
280
|
+
return schema
|
281
|
+
end
|
282
|
+
|
283
|
+
if validation_hash[:request]
|
284
|
+
if validation_hash[:request].is_a?(Hash)
|
285
|
+
schema[:request] = validation_hash[:request].to_json
|
286
|
+
else
|
287
|
+
schema[:request] = validation_hash[:request]
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
if validation_hash[:response]
|
292
|
+
if validation_hash[:response].is_a?(Hash)
|
293
|
+
schema[:response] = validation_hash[:response].to_json
|
294
|
+
else
|
295
|
+
schema[:response] = validation_hash[:response]
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
if validation_hash[:request].nil? && validation_hash[:response].nil?
|
300
|
+
schema[:request] = validation
|
301
|
+
end
|
302
|
+
return schema
|
303
|
+
rescue
|
304
|
+
return {
|
305
|
+
:request => validation,
|
306
|
+
:response => nil
|
307
|
+
}
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
|
313
|
+
|
314
|
+
|
315
|
+
|
316
|
+
|
317
|
+
|
318
|
+
|
319
|
+
|
data/lib/object.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
class Object
|
2
|
+
|
3
|
+
# Symbolizes keys of a hash
|
4
|
+
def deep_symbolize_keys
|
5
|
+
return self.inject({}){|memo, (k,v)| memo[k.to_sym] = v.deep_symbolize_keys; memo} if self.is_a? Hash
|
6
|
+
return self.inject([]){|memo, v | memo << v.deep_symbolize_keys; memo} if self.is_a? Array
|
7
|
+
return self
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns true if object is nil or empty, false otherwise
|
11
|
+
def blank?
|
12
|
+
respond_to?(:empty?) ? empty? : !self
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,241 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'apiary_blueprint_convertor/convertor'
|
3
|
+
|
4
|
+
class ConvertorTest < Minitest::Test
|
5
|
+
include ApiaryBlueprintConvertor
|
6
|
+
|
7
|
+
VALIDATIONS_AST = [{
|
8
|
+
:url => "/resource2",
|
9
|
+
:method => "POST",
|
10
|
+
:body => "{ \"request\": \"42\", \"response\": \"0xdeadbeef\" }"
|
11
|
+
},
|
12
|
+
{
|
13
|
+
:url => "/resource1",
|
14
|
+
:method => "GET",
|
15
|
+
:body => "GOOD STUFF"
|
16
|
+
}
|
17
|
+
]
|
18
|
+
|
19
|
+
REQUEST_AST = {
|
20
|
+
:headers => nil,
|
21
|
+
:body => "A"
|
22
|
+
}
|
23
|
+
|
24
|
+
RESPONSES_AST = [{
|
25
|
+
:status => 200,
|
26
|
+
:headers => {
|
27
|
+
:'Content-Type' => "text/plain"
|
28
|
+
},
|
29
|
+
:body => "Hello World!"
|
30
|
+
},
|
31
|
+
{
|
32
|
+
:status => 404,
|
33
|
+
:headers => {
|
34
|
+
:'Content-Type' => "application/json",
|
35
|
+
:'X-Header' => "42"
|
36
|
+
},
|
37
|
+
:body => "42 not found."
|
38
|
+
}
|
39
|
+
]
|
40
|
+
|
41
|
+
RESOURCES_AST = [{
|
42
|
+
:description => "Ipsum Lorem",
|
43
|
+
:method => "GET",
|
44
|
+
:url => "/resource1",
|
45
|
+
:request => REQUEST_AST,
|
46
|
+
:responses => []
|
47
|
+
},
|
48
|
+
{
|
49
|
+
:description => nil,
|
50
|
+
:method => "POST",
|
51
|
+
:url => "/resource2",
|
52
|
+
:request => REQUEST_AST,
|
53
|
+
:responses => RESPONSES_AST
|
54
|
+
},
|
55
|
+
{
|
56
|
+
:description => nil,
|
57
|
+
:method => "PUT",
|
58
|
+
:url => "/resource1",
|
59
|
+
:request => nil,
|
60
|
+
:responses => []
|
61
|
+
}
|
62
|
+
]
|
63
|
+
|
64
|
+
SECTIONS_AST = [{
|
65
|
+
:name => "Section One",
|
66
|
+
:description => "Lorem Ipsum",
|
67
|
+
:resources => []
|
68
|
+
},
|
69
|
+
{
|
70
|
+
:name => "Section TWO",
|
71
|
+
:description => nil,
|
72
|
+
:resources => RESOURCES_AST
|
73
|
+
}
|
74
|
+
]
|
75
|
+
|
76
|
+
BLUEPRINT_AST = {
|
77
|
+
:location => "http://google.com",
|
78
|
+
:name => "API NAME",
|
79
|
+
:description => "Lorem Ipsum",
|
80
|
+
:sections => SECTIONS_AST,
|
81
|
+
:validations => VALIDATIONS_AST
|
82
|
+
}
|
83
|
+
|
84
|
+
def test_convert_location
|
85
|
+
blueprint_ast = {}
|
86
|
+
Convertor.convert_location("http://google.com", blueprint_ast)
|
87
|
+
|
88
|
+
assert_equal 1, blueprint_ast.keys.length
|
89
|
+
assert_equal :metadata, blueprint_ast.keys.first
|
90
|
+
|
91
|
+
assert_equal 1, blueprint_ast[:metadata].keys.length
|
92
|
+
assert_equal :HOST, blueprint_ast[:metadata].keys.first
|
93
|
+
|
94
|
+
assert_equal 1, blueprint_ast[:metadata][:HOST].keys.length
|
95
|
+
assert_equal :value, blueprint_ast[:metadata][:HOST].keys.first
|
96
|
+
|
97
|
+
assert_equal "http://google.com", blueprint_ast[:metadata][:HOST][:value]
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_convert_blueprint
|
101
|
+
blueprint_ast = {}
|
102
|
+
Convertor.convert_blueprint(BLUEPRINT_AST, blueprint_ast)
|
103
|
+
|
104
|
+
assert_equal 4, blueprint_ast.keys.length
|
105
|
+
|
106
|
+
assert blueprint_ast[:metadata]
|
107
|
+
assert_equal "API NAME", blueprint_ast[:name]
|
108
|
+
assert_equal "Lorem Ipsum", blueprint_ast[:description]
|
109
|
+
assert blueprint_ast[:resourceGroups]
|
110
|
+
assert_equal 2, blueprint_ast[:resourceGroups].length
|
111
|
+
|
112
|
+
#puts "\n\n>>#{JSON.pretty_generate(blueprint_ast)}\n"
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_convert_sections
|
116
|
+
blueprint_ast = {}
|
117
|
+
Convertor.convert_sections(SECTIONS_AST, {}, blueprint_ast)
|
118
|
+
|
119
|
+
assert_equal 1, blueprint_ast.keys.length
|
120
|
+
assert_equal :resourceGroups, blueprint_ast.keys.first
|
121
|
+
assert_instance_of Array, blueprint_ast[:resourceGroups]
|
122
|
+
assert_equal 2, blueprint_ast[:resourceGroups].length
|
123
|
+
|
124
|
+
assert_equal "Section One", blueprint_ast[:resourceGroups][0][:name]
|
125
|
+
assert_equal "Lorem Ipsum", blueprint_ast[:resourceGroups][0][:description]
|
126
|
+
assert_equal nil, blueprint_ast[:resourceGroups][0][:resources]
|
127
|
+
|
128
|
+
assert_equal "Section TWO", blueprint_ast[:resourceGroups][1][:name]
|
129
|
+
assert_equal nil, blueprint_ast[:resourceGroups][1][:description]
|
130
|
+
assert_instance_of Array, blueprint_ast[:resourceGroups][1][:resources]
|
131
|
+
assert_equal 2, blueprint_ast[:resourceGroups][1][:resources].length
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_convert_resources
|
135
|
+
group_ast = {}
|
136
|
+
Convertor.convert_resources(RESOURCES_AST, {}, group_ast)
|
137
|
+
|
138
|
+
assert_equal 1, group_ast.keys.length
|
139
|
+
assert_equal :resources, group_ast.keys.first
|
140
|
+
assert_instance_of Array, group_ast[:resources]
|
141
|
+
assert_equal 2, group_ast[:resources].length
|
142
|
+
|
143
|
+
assert_equal nil, group_ast[:resources][0][:name]
|
144
|
+
assert_equal nil, group_ast[:resources][0][:description]
|
145
|
+
assert_equal "/resource1", group_ast[:resources][0][:uriTemplate]
|
146
|
+
assert_equal nil, group_ast[:resources][0][:model]
|
147
|
+
assert_equal nil, group_ast[:resources][0][:parameters]
|
148
|
+
assert_equal nil, group_ast[:resources][0][:headers]
|
149
|
+
assert group_ast[:resources][0][:actions]
|
150
|
+
assert_equal 2, group_ast[:resources][0][:actions].length
|
151
|
+
|
152
|
+
assert_equal nil, group_ast[:resources][1][:name]
|
153
|
+
assert_equal nil, group_ast[:resources][1][:description]
|
154
|
+
assert_equal "/resource2", group_ast[:resources][1][:uriTemplate]
|
155
|
+
assert_equal nil, group_ast[:resources][1][:model]
|
156
|
+
assert_equal nil, group_ast[:resources][1][:parameters]
|
157
|
+
assert_equal nil, group_ast[:resources][1][:headers]
|
158
|
+
assert group_ast[:resources][1][:actions]
|
159
|
+
assert_equal 1, group_ast[:resources][1][:actions].length
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_add_resource_action
|
163
|
+
resource_ast = {}
|
164
|
+
Convertor.add_resource_action(RESOURCES_AST[0], {}, resource_ast)
|
165
|
+
|
166
|
+
assert resource_ast[:actions], "resource actions exists"
|
167
|
+
assert_equal 1, resource_ast[:actions].length
|
168
|
+
assert_equal "GET", resource_ast[:actions][0][:method]
|
169
|
+
assert_equal "Ipsum Lorem", resource_ast[:actions][0][:description]
|
170
|
+
assert_equal nil, resource_ast[:actions][0][:parameters]
|
171
|
+
assert_equal nil, resource_ast[:actions][0][:headers]
|
172
|
+
assert_instance_of Array, resource_ast[:actions][0][:examples]
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_add_action_example
|
176
|
+
action_ast = {}
|
177
|
+
Convertor.add_action_example(RESOURCES_AST[1], VALIDATIONS_AST, action_ast)
|
178
|
+
|
179
|
+
assert_instance_of Array, action_ast[:examples]
|
180
|
+
assert_equal 1, action_ast[:examples].length
|
181
|
+
assert_equal nil, action_ast[:examples][0][:name]
|
182
|
+
assert_equal nil, action_ast[:examples][0][:description]
|
183
|
+
|
184
|
+
assert_instance_of Array, action_ast[:examples][0][:requests]
|
185
|
+
assert_equal 1, action_ast[:examples][0][:requests].length
|
186
|
+
assert_equal nil, action_ast[:examples][0][:requests][0][:name]
|
187
|
+
assert_equal nil, action_ast[:examples][0][:requests][0][:description]
|
188
|
+
assert_equal nil, action_ast[:examples][0][:requests][0][:headers]
|
189
|
+
assert_equal "A", action_ast[:examples][0][:requests][0][:body]
|
190
|
+
assert_equal "42", action_ast[:examples][0][:requests][0][:schema]
|
191
|
+
|
192
|
+
assert_instance_of Array, action_ast[:examples][0][:responses]
|
193
|
+
assert_equal 2, action_ast[:examples][0][:responses].length
|
194
|
+
|
195
|
+
assert_equal "200", action_ast[:examples][0][:responses][0][:name]
|
196
|
+
assert_equal nil, action_ast[:examples][0][:responses][0][:description]
|
197
|
+
|
198
|
+
assert_instance_of Hash, action_ast[:examples][0][:responses][0][:headers]
|
199
|
+
assert_equal 1, action_ast[:examples][0][:responses][0][:headers].keys.length
|
200
|
+
assert_equal :'Content-Type', action_ast[:examples][0][:responses][0][:headers].keys[0]
|
201
|
+
assert_instance_of Hash, action_ast[:examples][0][:responses][0][:headers][:'Content-Type']
|
202
|
+
assert_equal 1, action_ast[:examples][0][:responses][0][:headers][:'Content-Type'].keys.length
|
203
|
+
assert_equal :value, action_ast[:examples][0][:responses][0][:headers][:'Content-Type'].keys[0]
|
204
|
+
assert_equal "text/plain", action_ast[:examples][0][:responses][0][:headers][:'Content-Type'][:value]
|
205
|
+
|
206
|
+
assert_equal "Hello World!", action_ast[:examples][0][:responses][0][:body]
|
207
|
+
assert_equal "0xdeadbeef", action_ast[:examples][0][:responses][0][:schema]
|
208
|
+
|
209
|
+
assert_equal "404", action_ast[:examples][0][:responses][1][:name]
|
210
|
+
assert_equal nil, action_ast[:examples][0][:responses][1][:description]
|
211
|
+
|
212
|
+
assert_instance_of Hash, action_ast[:examples][0][:responses][1][:headers]
|
213
|
+
assert_equal 2, action_ast[:examples][0][:responses][1][:headers].keys.length
|
214
|
+
|
215
|
+
assert_equal :'Content-Type', action_ast[:examples][0][:responses][1][:headers].keys[0]
|
216
|
+
assert_instance_of Hash, action_ast[:examples][0][:responses][1][:headers][:'Content-Type']
|
217
|
+
assert_equal 1, action_ast[:examples][0][:responses][1][:headers][:'Content-Type'].keys.length
|
218
|
+
assert_equal :value, action_ast[:examples][0][:responses][1][:headers][:'Content-Type'].keys[0]
|
219
|
+
assert_equal "application/json", action_ast[:examples][0][:responses][1][:headers][:'Content-Type'][:value]
|
220
|
+
|
221
|
+
assert_equal :'X-Header', action_ast[:examples][0][:responses][1][:headers].keys[1]
|
222
|
+
assert_instance_of Hash, action_ast[:examples][0][:responses][1][:headers][:'X-Header']
|
223
|
+
assert_equal 1, action_ast[:examples][0][:responses][1][:headers][:'X-Header'].keys.length
|
224
|
+
assert_equal :value, action_ast[:examples][0][:responses][1][:headers][:'X-Header'].keys[0]
|
225
|
+
assert_equal "42", action_ast[:examples][0][:responses][1][:headers][:'X-Header'][:value]
|
226
|
+
|
227
|
+
assert_equal "42 not found.", action_ast[:examples][0][:responses][1][:body]
|
228
|
+
assert_equal "0xdeadbeef", action_ast[:examples][0][:responses][1][:schema]
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
|
233
|
+
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
|
238
|
+
|
239
|
+
|
240
|
+
|
241
|
+
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: apiary_blueprint_convertor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Zdenek Nemec
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: cucumber
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Convert legacy Apiary Blueprint AST into API Blueprint AST (JSON).
|
70
|
+
email:
|
71
|
+
- z@apiary.io
|
72
|
+
executables:
|
73
|
+
- apiary_blueprint_convertor
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- ".travis.yml"
|
79
|
+
- Gemfile
|
80
|
+
- Gemfile.lock
|
81
|
+
- LICENSE
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- apiary_blueprint_convertor.gemspec
|
85
|
+
- bin/apiary_blueprint_convertor
|
86
|
+
- features/convert.feature
|
87
|
+
- features/step_definitions/file_content_step.rb
|
88
|
+
- features/support/setup.rb
|
89
|
+
- lib/apiary_blueprint_convertor.rb
|
90
|
+
- lib/apiary_blueprint_convertor/cli.rb
|
91
|
+
- lib/apiary_blueprint_convertor/convertor.rb
|
92
|
+
- lib/apiary_blueprint_convertor/version.rb
|
93
|
+
- lib/object.rb
|
94
|
+
- test/convertor_test.rb
|
95
|
+
homepage: ''
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
metadata: {}
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 2.2.0
|
116
|
+
signing_key:
|
117
|
+
specification_version: 4
|
118
|
+
summary: Apiary Blueprint AST convertor.
|
119
|
+
test_files:
|
120
|
+
- features/convert.feature
|
121
|
+
- features/step_definitions/file_content_step.rb
|
122
|
+
- features/support/setup.rb
|
123
|
+
- test/convertor_test.rb
|