weasel_diesel 1.2.2 → 1.3.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 +4 -4
- data/.travis.yml +0 -1
- data/CHANGELOG.md +9 -4
- data/Gemfile +1 -1
- data/LICENSE +3 -1
- data/README.md +36 -58
- data/bin/weasel_diesel +5 -0
- data/lib/framework_ext/sinatra_controller.rb +17 -17
- data/lib/response.rb +23 -24
- data/lib/weasel_diesel.rb +12 -8
- data/lib/weasel_diesel/cli.rb +60 -0
- data/lib/weasel_diesel/doc_generator/_input_params.erb +36 -0
- data/lib/weasel_diesel/doc_generator/_response_element.erb +49 -0
- data/lib/weasel_diesel/doc_generator/template.erb +120 -0
- data/lib/weasel_diesel/dsl.rb +34 -0
- data/lib/weasel_diesel/version.rb +1 -1
- data/spec/hello_world_service.rb +5 -5
- data/spec/json_response_description_spec.rb +15 -15
- data/spec/json_response_verification_spec.rb +2 -2
- data/spec/params_verification_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -6
- data/spec/test_services.rb +2 -3
- data/spec/wd_controller_dispatch_spec.rb +1 -1
- data/spec/wd_documentation_spec.rb +4 -2
- data/spec/wd_params_spec.rb +2 -2
- data/spec/wd_spec.rb +1 -1
- data/spec/ws_list_spec.rb +1 -1
- data/spec/wsdsl_sinatra_ext_spec.rb +2 -2
- data/weasel_diesel.gemspec +4 -5
- metadata +27 -6
- data/lib/kernel_ext.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66a37bea5e3454ee526eb9281ae4e98ce75945db
|
4
|
+
data.tar.gz: 29e993efacc6873959b347b4141e93f1cbb85738
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a04322e780856bf69f40e3311cfd3fdd00c4bbabb492b30b8822e99537dac179a7d1929040c3710313df8aa753803415a5465387fe58789a3287f3187477f31d
|
7
|
+
data.tar.gz: 473aa3828ff0474ecafad534d986353d67b415fbdcbb9b358ddc461146538ae396e4523882db54ef9705954dd2c605c40db7385976c9ac3ca9235b417eb96e16
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -3,10 +3,16 @@
|
|
3
3
|
All changes can be seen on GitHub and git tags are used to isolate each
|
4
4
|
release.
|
5
5
|
|
6
|
-
1.
|
6
|
+
## 1.3.0
|
7
|
+
* Move documentation generation from wd_sinatra into Weasel-Diesel.
|
8
|
+
* Drop support for Ruby 1.8.7.
|
9
|
+
* Fix rspec deprecation: `expect { }.not_to raise_error(SpecificErrorClass)`
|
10
|
+
* DSL now only extends the top level main object.
|
11
|
+
|
12
|
+
## 1.2.2:
|
7
13
|
* Added support for anonymous top level arrays.
|
8
14
|
|
9
|
-
|
15
|
+
## 1.2.1:
|
10
16
|
|
11
17
|
* Modified the way an empty string param is cast/verified. If a param is
|
12
18
|
passed as an empty string but the param isn't specified as a string, the
|
@@ -15,8 +21,7 @@ an integer param, the cast params will look like that: `{'id' => nil}`,
|
|
15
21
|
however if `name` is a string param and `{'name' => ''}` is passed, the
|
16
22
|
value won't be nullified.
|
17
23
|
|
18
|
-
|
19
|
-
**1.2.0**:
|
24
|
+
## 1.2.0:
|
20
25
|
|
21
26
|
* All service urls are now stored with a prepended slash (if not defined
|
22
27
|
with one). `WDList.find(<verb>, <url>)` will automatically find the
|
data/Gemfile
CHANGED
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](http://travis-ci.org/mattetti/Weasel-Diesel)
|
4
4
|
|
5
|
-
Weasel Diesel is a DSL to describe and document your web API.
|
5
|
+
Weasel Diesel is a DSL to describe and document your web API.
|
6
6
|
|
7
7
|
To get you going quickly, see the [generator for sinatra apps](https://github.com/mattetti/wd-sinatra).
|
8
8
|
The wd_sinatra gem allows you to generate the structure for a sinatra app using Weasel Diesel and with lots of goodies.
|
@@ -34,8 +34,8 @@ describe_service "/hello_world" do |service|
|
|
34
34
|
|
35
35
|
# DOCUMENTATION
|
36
36
|
service.documentation do |doc|
|
37
|
-
|
38
|
-
|
37
|
+
doc.overall "This service provides a simple hello world implementation example."
|
38
|
+
doc.example "<code>curl -I 'http://localhost:9292/hello_world?name=Matt'</code>"
|
39
39
|
end
|
40
40
|
|
41
41
|
# ACTION/IMPLEMENTATION (specific to the sinatra app example, can
|
@@ -55,34 +55,34 @@ Or a more complex example using XML:
|
|
55
55
|
describe_service "/wsdsl/test.xml" do |service|
|
56
56
|
service.formats :xml, :json
|
57
57
|
service.http_verb :get
|
58
|
-
|
58
|
+
|
59
59
|
# INPUT
|
60
60
|
service.params do |p|
|
61
61
|
p.string :framework, :in => SpecOptions, :null => false, :required => true
|
62
|
-
|
63
|
-
p.datetime :timestamp,
|
64
|
-
:default => Time.now,
|
62
|
+
|
63
|
+
p.datetime :timestamp,
|
64
|
+
:default => Time.now,
|
65
65
|
:doc => "The test framework used, could be one of the two following: #{SpecOptions.join(", ")}."
|
66
66
|
|
67
67
|
p.string :alpha, :in => ['a', 'b', 'c']
|
68
|
-
p.string :version,
|
68
|
+
p.string :version,
|
69
69
|
:null => false,
|
70
70
|
:doc => "The version of the framework to use."
|
71
|
-
|
71
|
+
|
72
72
|
p.integer :num, :minvalue => 42
|
73
73
|
p.namespace :user do |user|
|
74
74
|
user.integer :id, :required => :true
|
75
75
|
end
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
# OUTPUT
|
79
|
-
# the response contains a list of player creation ratings each object in the list
|
79
|
+
# the response contains a list of player creation ratings each object in the list
|
80
80
|
service.response do |response|
|
81
81
|
response.element(:name => "player_creation_ratings") do |e|
|
82
82
|
e.attribute :id => :integer, :doc => "id doc"
|
83
83
|
e.attribute :is_accepted => :boolean, :doc => "is accepted doc"
|
84
84
|
e.attribute :name => :string, :doc => "name doc"
|
85
|
-
|
85
|
+
|
86
86
|
e.array :name => 'player_creation_rating', :type => 'PlayerCreationRating' do |a|
|
87
87
|
a.attribute :comments => :string, :doc => "comments doc"
|
88
88
|
a.attribute :player_id => :integer, :doc => "player_id doc"
|
@@ -91,14 +91,14 @@ Or a more complex example using XML:
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
# DOCUMENTATION
|
96
96
|
service.documentation do |doc|
|
97
97
|
# doc.overall <markdown description text>
|
98
98
|
doc.overall <<-DOC
|
99
99
|
This is a test service used to test the framework.
|
100
100
|
DOC
|
101
|
-
|
101
|
+
|
102
102
|
# doc.example <markdown text>
|
103
103
|
doc.example <<-DOC
|
104
104
|
The most common way to use this service looks like that:
|
@@ -178,7 +178,7 @@ This is particuliarly frequent when using Rails for instance.
|
|
178
178
|
|
179
179
|
```ruby
|
180
180
|
service.params do |param|
|
181
|
-
param.string :framework,
|
181
|
+
param.string :framework,
|
182
182
|
:in => ['RSpec', 'Bacon'],
|
183
183
|
:required => true,
|
184
184
|
:doc => "The test framework used, could be one of the two following: #{WeaselDieselSpecOptions.join(", ")}."
|
@@ -240,26 +240,26 @@ end
|
|
240
240
|
|
241
241
|
Consider the following JSON response:
|
242
242
|
|
243
|
-
```
|
244
|
-
{ people: [
|
245
|
-
{
|
246
|
-
id : 1,
|
243
|
+
```
|
244
|
+
{ people: [
|
245
|
+
{
|
246
|
+
id : 1,
|
247
247
|
online : false,
|
248
|
-
created_at : 123123123123,
|
248
|
+
created_at : 123123123123,
|
249
249
|
team : {
|
250
250
|
id : 1231,
|
251
251
|
score : 123.32
|
252
252
|
}
|
253
|
-
},
|
254
|
-
{
|
255
|
-
id : 2,
|
253
|
+
},
|
254
|
+
{
|
255
|
+
id : 2,
|
256
256
|
online : true,
|
257
|
-
created_at : 123123123123,
|
257
|
+
created_at : 123123123123,
|
258
258
|
team: {
|
259
259
|
id : 1233,
|
260
260
|
score : 1.32
|
261
261
|
}
|
262
|
-
},
|
262
|
+
},
|
263
263
|
] }
|
264
264
|
```
|
265
265
|
|
@@ -287,7 +287,7 @@ Nodes/elements can also use some meta-attributes including:
|
|
287
287
|
* `key` : refers to an attribute name that is key to this object
|
288
288
|
* `type` : refers to the type of object described, valuable when using JSON across OO based apps.
|
289
289
|
|
290
|
-
JSON response validation can be done using an optional module as shown in
|
290
|
+
JSON response validation can be done using an optional module as shown in
|
291
291
|
(spec/json_response_verification_spec.rb)[https://github.com/mattetti/Weasel-Diesel/blob/master/spec/json_response_verification_spec.rb].
|
292
292
|
The goal of this module is to help automate API testing by
|
293
293
|
validating the data structure of the returned object.
|
@@ -312,7 +312,7 @@ end
|
|
312
312
|
```
|
313
313
|
|
314
314
|
Actual output:
|
315
|
-
```
|
315
|
+
```
|
316
316
|
{"name": "Example"}
|
317
317
|
```
|
318
318
|
|
@@ -328,42 +328,20 @@ describe_service "example" do |service|
|
|
328
328
|
end
|
329
329
|
```
|
330
330
|
|
331
|
+
## Documentation generation
|
331
332
|
|
332
|
-
|
333
|
-
|
334
|
-
The test suite requires Ruby 1.9.* along with `RSpec`, `Rack`, and `Sinatra` gems.
|
335
|
-
|
336
|
-
## Usage with Ruby 1.8
|
337
|
-
|
338
|
-
This library prioritizes Ruby 1.9, but 1.8 support was added
|
339
|
-
via the backports library and some tweaks.
|
340
|
-
|
341
|
-
However, because Ruby 1.8 hashes do not preserve insert order, the following syntax
|
342
|
-
**will not work**:
|
343
|
-
|
344
|
-
``` ruby
|
345
|
-
service.response do |response|
|
346
|
-
response.element(:name => "player_creation_ratings") do |e|
|
347
|
-
e.attribute :id => :integer, :doc => "id doc"
|
348
|
-
e.attribute :is_accepted => :boolean, :doc => "is accepted doc"
|
349
|
-
e.attribute :name => :string, :doc => "name doc"
|
350
|
-
end
|
351
|
-
end
|
333
|
+
```bash
|
334
|
+
$ weasel_diesel generate_doc <SOURCE_PATH> <DESTINATION_PATH>
|
352
335
|
```
|
353
336
|
|
354
|
-
|
337
|
+
To generate documentation for the APIs you created in the api folder. The
|
338
|
+
source path is the location of your ruby files. The destination is optional,
|
339
|
+
'doc' is the default.
|
355
340
|
|
356
|
-
``` ruby
|
357
|
-
service.response do |response|
|
358
|
-
response.element(:name => "player_creation_ratings") do |e|
|
359
|
-
e.integer :id, :doc => "id doc"
|
360
|
-
e.boolean :is_accepted, :doc => "is accepted doc"
|
361
|
-
e.string :name, :doc => "name doc"
|
362
|
-
end
|
363
|
-
end
|
364
|
-
```
|
365
341
|
|
366
|
-
|
342
|
+
## Test Suite & Dependencies
|
343
|
+
|
344
|
+
The test suite requires `rspec`, `rack`, and `sinatra` gems.
|
367
345
|
|
368
346
|
## Copyright
|
369
347
|
|
data/bin/weasel_diesel
ADDED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'forwardable'
|
2
|
-
|
2
|
+
require_relative '../params_verification'
|
3
3
|
|
4
4
|
# Base code shared by all service controllers
|
5
5
|
# This allows us to share code between controllers
|
@@ -10,44 +10,44 @@ require File.expand_path('./../params_verification', File.dirname(__FILE__))
|
|
10
10
|
# @author Matt Aimonetti
|
11
11
|
class SinatraServiceController
|
12
12
|
extend Forwardable
|
13
|
-
|
13
|
+
|
14
14
|
# The service controller might be loaded outside of a Sinatra App
|
15
15
|
# in this case, we don't need to load the helpers
|
16
16
|
if Object.const_defined?(:Sinatra)
|
17
|
-
include Sinatra::Helpers
|
17
|
+
include Sinatra::Helpers
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
class AuthenticationFailed < StandardError; end
|
21
|
-
|
21
|
+
|
22
22
|
# @return [WeaselDiesel] The service served by this controller
|
23
23
|
# @api public
|
24
24
|
attr_reader :service
|
25
|
-
|
25
|
+
|
26
26
|
# @return [Sinatra::Application]
|
27
27
|
# @api public
|
28
28
|
attr_reader :app
|
29
|
-
|
29
|
+
|
30
30
|
# @return [Hash]
|
31
31
|
# @api public
|
32
32
|
attr_reader :env
|
33
|
-
|
33
|
+
|
34
34
|
# @return [Sinatra::Request]
|
35
35
|
# @see http://rubydoc.info/github/sinatra/sinatra/Sinatra/Request
|
36
36
|
# @api public
|
37
37
|
attr_reader :request
|
38
|
-
|
38
|
+
|
39
39
|
# @return [Sinatra::Response]
|
40
40
|
# @see http://rubydoc.info/github/sinatra/sinatra/Sinatra/Response
|
41
41
|
# @api public
|
42
42
|
attr_reader :response
|
43
|
-
|
43
|
+
|
44
44
|
# @return [Hash]
|
45
45
|
# @api public
|
46
46
|
attr_accessor :params
|
47
|
-
|
47
|
+
|
48
48
|
# @param [Sinatra::Application] app The Sinatra app used as a reference and to access request params
|
49
49
|
# @param [WeaselDiesel] service The service served by this controller
|
50
|
-
# @raise [ParamError, NoParamsDefined, MissingParam, UnexpectedParam, InvalidParamType, InvalidParamValue]
|
50
|
+
# @raise [ParamError, NoParamsDefined, MissingParam, UnexpectedParam, InvalidParamType, InvalidParamValue]
|
51
51
|
# If the params don't validate one of the {ParamsVerification} errors will be raised.
|
52
52
|
# @api public
|
53
53
|
def initialize(app, service)
|
@@ -56,10 +56,10 @@ class SinatraServiceController
|
|
56
56
|
@request = app.request
|
57
57
|
@response = app.response
|
58
58
|
@service = service
|
59
|
-
|
59
|
+
|
60
60
|
# raises an exception if the params are not valid
|
61
|
-
# otherwise update the app params with potentially new params (using default values)
|
62
|
-
# note that if a type if mentioned for a params, the object will be cast to this object type
|
61
|
+
# otherwise update the app params with potentially new params (using default values)
|
62
|
+
# note that if a type if mentioned for a params, the object will be cast to this object type
|
63
63
|
@params = app.params = ParamsVerification.validate!(app.params, service.defined_params)
|
64
64
|
|
65
65
|
# Authentication check
|
@@ -67,7 +67,7 @@ class SinatraServiceController
|
|
67
67
|
raise AuthenticationFailed unless logged_in?
|
68
68
|
end
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
|
72
72
|
# Forwarding some methods to the underlying app object
|
73
73
|
def_delegators :app, :settings, :halt, :compile_template, :session
|
@@ -76,5 +76,5 @@ class SinatraServiceController
|
|
76
76
|
def logged_in?
|
77
77
|
!session[:player_id].nil?
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
end
|
data/lib/response.rb
CHANGED
@@ -24,7 +24,7 @@ class WeaselDiesel
|
|
24
24
|
# Lists all top level simple elements and array elements.
|
25
25
|
#
|
26
26
|
# @return [Array<WeaselDiesel::Response::Element, WeaselDiesel::Response::Array>]
|
27
|
-
def nodes
|
27
|
+
def nodes
|
28
28
|
elements + arrays
|
29
29
|
end
|
30
30
|
|
@@ -153,6 +153,7 @@ class WeaselDiesel
|
|
153
153
|
@type = type
|
154
154
|
@attributes = []
|
155
155
|
@meta_attributes = []
|
156
|
+
@elements = []
|
156
157
|
@vectors = []
|
157
158
|
@key = nil
|
158
159
|
# we don't need to initialize the nested elements, by default they should be nil
|
@@ -164,7 +165,7 @@ class WeaselDiesel
|
|
164
165
|
# @option opts [String, Symbol] attribute_name The name of the attribute, the value being the type
|
165
166
|
# @option opts [String, Symbol] :doc The attribute documentation
|
166
167
|
# @option opts [String, Symbol] :mock An optional mock value used by service related tools
|
167
|
-
#
|
168
|
+
#
|
168
169
|
# @example Creation of a response attribute called 'best_lap_time'
|
169
170
|
# service.response do |response|
|
170
171
|
# response.element(:name => "my_stats", :type => 'Leaderboard') do |e|
|
@@ -174,13 +175,13 @@ class WeaselDiesel
|
|
174
175
|
#
|
175
176
|
# @return [Array<WeaselDiesel::Response::Attribute>]
|
176
177
|
# @api public
|
177
|
-
def attribute(opts
|
178
|
-
raise ArgumentError unless opts.is_a?(Hash)
|
179
|
-
new_attribute = Attribute.new(opts
|
178
|
+
def attribute(opts)
|
179
|
+
raise ArgumentError unless opts.is_a?(Hash)
|
180
|
+
new_attribute = Attribute.new(opts)
|
180
181
|
@attributes << new_attribute
|
181
182
|
# document the attribute if description available
|
182
183
|
# we might want to have a placeholder message when a response attribute isn't defined
|
183
|
-
if opts.
|
184
|
+
if opts.has_key?(:doc)
|
184
185
|
@doc.attribute(new_attribute.name, opts[:doc])
|
185
186
|
end
|
186
187
|
@attributes
|
@@ -191,7 +192,7 @@ class WeaselDiesel
|
|
191
192
|
# @param [Hash] opts An element's attribute options
|
192
193
|
# @option opts [String, Symbol] attribute_name The name of the attribute, the value being the type
|
193
194
|
# @option opts [String, Symbol] :mock An optional mock value used by service related tools
|
194
|
-
#
|
195
|
+
#
|
195
196
|
# @example Creation of a response attribute called 'best_lap_time'
|
196
197
|
# service.response do |response|
|
197
198
|
# response.element(:name => "my_stats", :type => 'Leaderboard') do |e|
|
@@ -212,12 +213,12 @@ class WeaselDiesel
|
|
212
213
|
# Defines an array aka vector of elements.
|
213
214
|
#
|
214
215
|
# @param [String, Symbol] name The name of the array element.
|
215
|
-
# @param [String, Symbol] type Optional type information, useful to store the represented
|
216
|
+
# @param [String, Symbol] type Optional type information, useful to store the represented
|
216
217
|
# object types for instance.
|
217
218
|
#
|
218
219
|
# @param [Proc] &block
|
219
220
|
# A block to execute against the newly created array.
|
220
|
-
#
|
221
|
+
#
|
221
222
|
# @example Defining an element array called 'player_creation_rating'
|
222
223
|
# element.array 'player_creation_rating', 'PlayerCreationRating' do |a|
|
223
224
|
# a.attribute :comments => :string
|
@@ -227,7 +228,7 @@ class WeaselDiesel
|
|
227
228
|
# end
|
228
229
|
# @yield [Vector] the newly created array/vector instance
|
229
230
|
# @see Element#initialize
|
230
|
-
#
|
231
|
+
#
|
231
232
|
# @return [Array<WeaselDiesel::Response::Vector>]
|
232
233
|
# @api public
|
233
234
|
def array(name, type=nil)
|
@@ -299,7 +300,7 @@ class WeaselDiesel
|
|
299
300
|
# @param [Symbol, String] name the name of the attribute.
|
300
301
|
# @param [Hash] opts the attribute options.
|
301
302
|
def string(name=nil, opts={})
|
302
|
-
attribute({name => :string}
|
303
|
+
attribute({name => :string}.merge(opts))
|
303
304
|
end
|
304
305
|
|
305
306
|
# Shortcut to create a string attribute
|
@@ -307,7 +308,7 @@ class WeaselDiesel
|
|
307
308
|
# @param [Symbol, String] name the name of the attribute.
|
308
309
|
# @param [Hash] opts the attribute options.
|
309
310
|
def integer(name=nil, opts={})
|
310
|
-
attribute({name => :integer}
|
311
|
+
attribute({name => :integer}.merge(opts))
|
311
312
|
end
|
312
313
|
|
313
314
|
# Shortcut to create a string attribute
|
@@ -315,7 +316,7 @@ class WeaselDiesel
|
|
315
316
|
# @param [Symbol, String] name the name of the attribute.
|
316
317
|
# @param [Hash] opts the attribute options.
|
317
318
|
def float(name=nil, opts={})
|
318
|
-
attribute({name => :float}
|
319
|
+
attribute({name => :float}.merge(opts))
|
319
320
|
end
|
320
321
|
|
321
322
|
# Shortcut to create a string attribute
|
@@ -323,7 +324,7 @@ class WeaselDiesel
|
|
323
324
|
# @param [Symbol, String] name the name of the attribute.
|
324
325
|
# @param [Hash] opts the attribute options.
|
325
326
|
def boolean(name=nil, opts={})
|
326
|
-
attribute({name => :boolean}
|
327
|
+
attribute({name => :boolean}.merge(opts))
|
327
328
|
end
|
328
329
|
|
329
330
|
# Shortcut to create a string attribute
|
@@ -331,20 +332,21 @@ class WeaselDiesel
|
|
331
332
|
# @param [Symbol, String] name the name of the attribute.
|
332
333
|
# @param [Hash] opts the attribute options.
|
333
334
|
def datetime(name=nil, opts={})
|
334
|
-
attribute({name => :datetime}
|
335
|
+
attribute({name => :datetime}.merge(opts))
|
335
336
|
end
|
336
337
|
|
337
338
|
# Converts an element into a hash representation
|
338
339
|
#
|
340
|
+
# @param [Boolean] root_node true if this node has no parents.
|
339
341
|
# @return [Hash] the element attributes formated in a hash
|
340
|
-
def to_hash
|
342
|
+
def to_hash(root_node=true)
|
341
343
|
attrs = {}
|
342
344
|
attributes.each{ |attr| attrs[attr.name] = attr.type }
|
343
|
-
elements.each{ |el| attrs[el.name] = el.to_hash }
|
345
|
+
(vectors + elements).each{ |el| attrs[el.name] = el.to_hash(false) }
|
344
346
|
if self.class == Vector
|
345
|
-
name ? {name => [attrs]} : [attrs]
|
347
|
+
(root_node && name) ? {name => [attrs]} : [attrs]
|
346
348
|
else
|
347
|
-
name ? {name => attrs} : attrs
|
349
|
+
(root_node && name) ? {name => attrs} : attrs
|
348
350
|
end
|
349
351
|
end
|
350
352
|
|
@@ -429,17 +431,14 @@ class WeaselDiesel
|
|
429
431
|
# name, type, doc, type
|
430
432
|
#
|
431
433
|
# @param [Hash, Array] o_params
|
432
|
-
# @param [Hash] o_extra_params A hash with extra params passed, needed to support Ruby 1.8 :(
|
433
434
|
#
|
434
435
|
# @api public
|
435
|
-
def initialize(o_params
|
436
|
+
def initialize(o_params)
|
436
437
|
params = o_params.dup
|
437
|
-
extra_params = o_extra_params.dup
|
438
438
|
if params.is_a?(Hash)
|
439
439
|
@name, @type = params.shift
|
440
440
|
@doc = params.delete(:doc) if params.has_key?(:doc)
|
441
|
-
@
|
442
|
-
@opts = params.merge!(extra_params)
|
441
|
+
@opts = params
|
443
442
|
elsif params.is_a?(Array)
|
444
443
|
@name = params.shift
|
445
444
|
@type = params.shift
|
data/lib/weasel_diesel.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
require
|
1
|
+
require_relative 'inflection'
|
2
|
+
require_relative 'params'
|
3
|
+
require_relative 'response'
|
4
|
+
require_relative 'documentation'
|
5
|
+
require_relative 'ws_list'
|
6
|
+
require 'weasel_diesel/dsl'
|
7
7
|
|
8
8
|
# WeaselDiesel offers a web service DSL to define web services,
|
9
9
|
# their params, http verbs, formats expected as well as the documentation
|
@@ -386,6 +386,12 @@ class WeaselDiesel
|
|
386
386
|
end
|
387
387
|
end
|
388
388
|
|
389
|
+
# Left for generators to implement. It's empty because WD itself isn't concerned
|
390
|
+
# with implementation, but needs it defined so doc generation can read WD web
|
391
|
+
# service definitions.
|
392
|
+
def implementation(&block)
|
393
|
+
end
|
394
|
+
|
389
395
|
SERVICE_ROOT_REGEXP = /(.*?)[\/\(\.]/
|
390
396
|
SERVICE_ACTION_REGEXP = /[\/\(\.]([a-z0-9_]+)[\/\(\.\?]/i
|
391
397
|
SERVICE_RESTFUL_SHOW_REGEXP = /\/:[a-z0-9_]+\.\w{3}$/
|
@@ -422,6 +428,4 @@ class WeaselDiesel
|
|
422
428
|
end
|
423
429
|
end
|
424
430
|
|
425
|
-
|
426
|
-
|
427
431
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require "thor"
|
2
|
+
require_relative "../weasel_diesel"
|
3
|
+
|
4
|
+
class WeaselDiesel
|
5
|
+
class CLI < Thor
|
6
|
+
include Thor::Actions
|
7
|
+
namespace :weasel_diesel
|
8
|
+
|
9
|
+
desc "generate_doc SOURCE_PATH DESTINATION_PATH", "Generate HTML documentation for WeaselDiesel web services"
|
10
|
+
def generate_doc(source_path, destination_path="doc")
|
11
|
+
api_files = Dir.glob(File.join(destination_root, source_path, "**", "*.rb"))
|
12
|
+
if api_files.empty?
|
13
|
+
puts "No ruby files in source_path: #{File.join(destination_root, source_path)}"
|
14
|
+
return
|
15
|
+
end
|
16
|
+
api_files.each do |api|
|
17
|
+
require api
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'fileutils'
|
21
|
+
destination = File.join(destination_root, destination_path)
|
22
|
+
FileUtils.mkdir_p(destination) unless File.exist?(destination)
|
23
|
+
File.open("#{destination}/index.html", "w"){|f| f << doc_template.result(binding)}
|
24
|
+
puts "Documentation available there: #{destination}/index.html"
|
25
|
+
`open #{destination}/index.html` if RUBY_PLATFORM =~ /darwin/ && !ENV['DONT_OPEN']
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def response_element_html(el)
|
31
|
+
response_element_template.result(binding)
|
32
|
+
end
|
33
|
+
|
34
|
+
def input_params_html(required, optional)
|
35
|
+
input_params_template.result(binding)
|
36
|
+
end
|
37
|
+
|
38
|
+
def input_params_template
|
39
|
+
file = resources.join '_input_params.erb'
|
40
|
+
ERB.new File.read(file)
|
41
|
+
end
|
42
|
+
|
43
|
+
def response_element_template
|
44
|
+
file = resources.join '_response_element.erb'
|
45
|
+
ERB.new File.read(file)
|
46
|
+
end
|
47
|
+
|
48
|
+
def doc_template
|
49
|
+
file = resources.join 'template.erb'
|
50
|
+
ERB.new File.read(file)
|
51
|
+
end
|
52
|
+
|
53
|
+
def resources
|
54
|
+
require 'pathname'
|
55
|
+
@resources ||= Pathname.new(File.join(File.dirname(__FILE__), 'doc_generator'))
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<table class="table table-striped table-responsive">
|
2
|
+
<tdbody>
|
3
|
+
<% [["required", required], ["optional", optional]].each do |label, rules| %>
|
4
|
+
<% unless rules.empty? %>
|
5
|
+
<% rules.each do |rule| %>
|
6
|
+
<tr>
|
7
|
+
<td>
|
8
|
+
<strong><%= rule.name %></strong>
|
9
|
+
<br />
|
10
|
+
<em><%= label %></em>
|
11
|
+
</td>
|
12
|
+
<td>
|
13
|
+
<p>
|
14
|
+
<strong><%= rule.options[:type] || 'string' %></strong>
|
15
|
+
|
16
|
+
<% if desc = rule.doc %>
|
17
|
+
- <%= desc %>
|
18
|
+
<% end %>
|
19
|
+
</p>
|
20
|
+
|
21
|
+
<% if options = rule.options[:options] %>
|
22
|
+
<strong>Options:</strong> <%= options.join(', ') %>
|
23
|
+
<br />
|
24
|
+
<% end %>
|
25
|
+
|
26
|
+
<% if default = rule.options[:default] %>
|
27
|
+
<strong>Default:</strong> <%= default %>
|
28
|
+
<br />
|
29
|
+
<% end %>
|
30
|
+
</td>
|
31
|
+
</tr>
|
32
|
+
<% end %>
|
33
|
+
<% end %>
|
34
|
+
<% end %>
|
35
|
+
</tdbody>
|
36
|
+
</table>
|
@@ -0,0 +1,49 @@
|
|
1
|
+
<table class="table table-striped table-responsive">
|
2
|
+
<tdbody>
|
3
|
+
<% if el.name %>
|
4
|
+
<tr>
|
5
|
+
<td colspan="2">
|
6
|
+
<strong><%= el.name %></strong>
|
7
|
+
<% if false && el.is_a?(WeaselDiesel::Response::Vector) %>
|
8
|
+
<span class="response-array">(Array, these are the properties of each array item)</span>
|
9
|
+
<% end %>
|
10
|
+
</td>
|
11
|
+
</tr>
|
12
|
+
<% end %>
|
13
|
+
<% el.properties.each do |prop| %>
|
14
|
+
<tr>
|
15
|
+
<td>
|
16
|
+
<strong><%= prop.name %></strong>
|
17
|
+
<br />
|
18
|
+
<em>
|
19
|
+
<% if false && prop.opts && prop.opts.respond_to?(:[]) && prop.opts[:null] %>
|
20
|
+
required
|
21
|
+
<% else %>
|
22
|
+
optional
|
23
|
+
<% end %>
|
24
|
+
</em>
|
25
|
+
</td>
|
26
|
+
<td>
|
27
|
+
<p>
|
28
|
+
<strong><%= prop.type %></strong>
|
29
|
+
<% unless true && prop.doc.nil? or prop.doc.empty? %>
|
30
|
+
- <%= prop.doc %>
|
31
|
+
<% end %>
|
32
|
+
</p>
|
33
|
+
</td>
|
34
|
+
</tr>
|
35
|
+
<% end %>
|
36
|
+
|
37
|
+
<% if false && el.arrays %>
|
38
|
+
<% el.arrays.each do |e| %>
|
39
|
+
<%= response_element_html(e) %>
|
40
|
+
<% end %>
|
41
|
+
<% end %>
|
42
|
+
|
43
|
+
<% if false && el.elements %>
|
44
|
+
<% el.elements.each do |e| %>
|
45
|
+
<%= response_element_html(e) %>
|
46
|
+
<% end %>
|
47
|
+
<% end %>
|
48
|
+
</tdbody>
|
49
|
+
</table>
|
@@ -0,0 +1,120 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>API Documentation</title>
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<!-- Bootstrap -->
|
7
|
+
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
|
8
|
+
<!-- Optional theme -->
|
9
|
+
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css">
|
10
|
+
|
11
|
+
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
12
|
+
<!--[if lt IE 9]>
|
13
|
+
<script src="../../assets/js/html5shiv.js"></script>
|
14
|
+
<script src="../../assets/js/respond.min.js"></script>
|
15
|
+
<![endif]-->
|
16
|
+
</head>
|
17
|
+
<body>
|
18
|
+
<div class="container">
|
19
|
+
<div class="navbar navbar-default">
|
20
|
+
<div class="navbar-header">
|
21
|
+
<a class="navbar-brand" href="#">API Documentation</a>
|
22
|
+
</div>
|
23
|
+
<div class="navbar-collapse collapse">
|
24
|
+
<ul class="nav navbar-nav">
|
25
|
+
<li class="active"><a href="index.html">Home</a></li>
|
26
|
+
</ul>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<div class="row">
|
31
|
+
<div class="sidebar col-md-3 well">
|
32
|
+
<h5>Resources</h5>
|
33
|
+
<ul>
|
34
|
+
<% WSList.all.sort{|a,b| a.url <=> b.url}.each do |api| %>
|
35
|
+
<li><a href="#<%= "raw-#{api.verb}-#{api.url}" %>"><%= api.verb.upcase %> <%= api.url %></a></li>
|
36
|
+
<% end %>
|
37
|
+
</ul>
|
38
|
+
</div>
|
39
|
+
<div class="content col-md-9">
|
40
|
+
<div class="jumbotron">
|
41
|
+
<h1>API Documentation</h1>
|
42
|
+
<p>Resources are listed on the sidebar to the left.</p>
|
43
|
+
</div>
|
44
|
+
|
45
|
+
<% WSList.all.each do |api| %>
|
46
|
+
<div id="<%= "raw-#{api.verb}-#{api.url}" %>">
|
47
|
+
<div class="overall">
|
48
|
+
<h2><%= api.verb.upcase %> <%= '[SSL]' if api.ssl %> <%= api.url %></h2>
|
49
|
+
<% if api.auth_required %>
|
50
|
+
<span class='label label-danger'>Authentication required</span>
|
51
|
+
<% end %>
|
52
|
+
|
53
|
+
<% if api.doc.desc %>
|
54
|
+
<p>
|
55
|
+
<%= "#{api.doc.desc}" %>
|
56
|
+
</p>
|
57
|
+
<% end %>
|
58
|
+
</div>
|
59
|
+
|
60
|
+
<div class="parameters">
|
61
|
+
<h3>Parameters</h3>
|
62
|
+
<% if api.required_rules.any? || api.optional_rules.any? %>
|
63
|
+
<%= input_params_html(api.required_rules, api.optional_rules) %>
|
64
|
+
<% end %>
|
65
|
+
|
66
|
+
<ul class="list-unstyled">
|
67
|
+
<% api.params.namespaced_params.each do |params| %>
|
68
|
+
<li>
|
69
|
+
<strong><%= params.space_name.name %></strong>
|
70
|
+
<em>
|
71
|
+
(<%= params.space_name.null ? 'optional' : 'required' %>)
|
72
|
+
</em>
|
73
|
+
<%= input_params_html(params.list_required, params.list_optional) %>
|
74
|
+
</li>
|
75
|
+
<% end %>
|
76
|
+
</ul>
|
77
|
+
</div>
|
78
|
+
|
79
|
+
<div class="example-request">
|
80
|
+
<h3>Example Request</h3>
|
81
|
+
<% api.doc.examples.each do |example| %>
|
82
|
+
<pre class="example"><%= example %></pre>
|
83
|
+
<% end %>
|
84
|
+
</div>
|
85
|
+
|
86
|
+
<div class="response">
|
87
|
+
<% if api.response.nodes.any? %>
|
88
|
+
<h3>Response</h3>
|
89
|
+
<% if api.response.arrays %>
|
90
|
+
<span class="response-array">(Array, these are the properties of each array item)</span>
|
91
|
+
<% end %>
|
92
|
+
|
93
|
+
<% api.response.arrays.each do |array| %>
|
94
|
+
<%= response_element_html(array) %>
|
95
|
+
<% end %>
|
96
|
+
<% api.response.elements.each do |el| %>
|
97
|
+
<%= response_element_html(el) %>
|
98
|
+
<% end %>
|
99
|
+
<% end %>
|
100
|
+
<h4>Example</h4>
|
101
|
+
<pre><%= JSON.pretty_generate(JSON.parse(api.response.to_json)) %></pre>
|
102
|
+
</div>
|
103
|
+
|
104
|
+
</div>
|
105
|
+
<hr>
|
106
|
+
<% end %>
|
107
|
+
|
108
|
+
<footer>
|
109
|
+
<p>© <%= Time.now.year %></p>
|
110
|
+
</footer>
|
111
|
+
</div>
|
112
|
+
</div>
|
113
|
+
</div>
|
114
|
+
|
115
|
+
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
|
116
|
+
<script src="https://code.jquery.com/jquery.js"></script>
|
117
|
+
<!-- Include all compiled plugins (below), or include individual files as needed -->
|
118
|
+
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
|
119
|
+
</body>
|
120
|
+
</html>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Extending the top level module to add some helpers
|
2
|
+
#
|
3
|
+
# @api public
|
4
|
+
class WeaselDiesel
|
5
|
+
module DSL
|
6
|
+
private
|
7
|
+
|
8
|
+
# Base DSL method called to describe a service
|
9
|
+
#
|
10
|
+
# @param [String] url The url of the service to add.
|
11
|
+
# @yield [WeaselDiesel] The newly created service.
|
12
|
+
# @return [Array] The services already defined
|
13
|
+
# @example Describing a basic service
|
14
|
+
# describe_service "hello-world.xml" do |service|
|
15
|
+
# # describe the service
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
def describe_service(url, &block)
|
20
|
+
service = WeaselDiesel.new(url)
|
21
|
+
yield service
|
22
|
+
|
23
|
+
service.sync_input_param_doc
|
24
|
+
WSList.add(service)
|
25
|
+
|
26
|
+
service
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Extend the main object with the DSL methods. This allows top-level calls
|
33
|
+
# without polluting the object inheritance tree.
|
34
|
+
self.extend WeaselDiesel::DSL
|
data/spec/hello_world_service.rb
CHANGED
@@ -7,14 +7,14 @@ describe_service "hello_world.xml" do |service|
|
|
7
7
|
|
8
8
|
service.response do |response|
|
9
9
|
response.element(:name => "greeting") do |e|
|
10
|
-
|
11
|
-
|
10
|
+
e.attribute "message" => :string, :doc => "The greeting message sent back."
|
11
|
+
end
|
12
12
|
end
|
13
13
|
|
14
14
|
service.documentation do |doc|
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
doc.overall "This service provides a simple hello world implementation example."
|
16
|
+
doc.params :name, "The name of the person to greet."
|
17
|
+
doc.example "<code>http://ps3.yourgame.com/hello_world.xml?name=Matt</code>"
|
18
18
|
end
|
19
19
|
|
20
20
|
end
|
@@ -1,34 +1,34 @@
|
|
1
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
2
|
|
3
3
|
describe "WeaselDiesel JSON response description" do
|
4
4
|
|
5
5
|
# JSON response example
|
6
6
|
=begin
|
7
|
-
{ vouchers: [
|
8
|
-
{
|
9
|
-
id : 1,
|
7
|
+
{ vouchers: [
|
8
|
+
{
|
9
|
+
id : 1,
|
10
10
|
redeemed : false,
|
11
|
-
created_at : 123123123123,
|
11
|
+
created_at : 123123123123,
|
12
12
|
option: {
|
13
13
|
id : 1231,
|
14
14
|
price: 123.32
|
15
15
|
}
|
16
|
-
},
|
17
|
-
{
|
18
|
-
id : 2,
|
16
|
+
},
|
17
|
+
{
|
18
|
+
id : 2,
|
19
19
|
redeemed : true,
|
20
|
-
created_at : 123123123123,
|
20
|
+
created_at : 123123123123,
|
21
21
|
option: {
|
22
22
|
id : 1233,
|
23
23
|
price: 1.32
|
24
24
|
}
|
25
|
-
},
|
25
|
+
},
|
26
26
|
] }
|
27
27
|
=end
|
28
28
|
|
29
29
|
before :all do
|
30
30
|
@timestamp = Time.now.to_i
|
31
|
-
@service =
|
31
|
+
@service = describe_service "json_list" do |service|
|
32
32
|
service.formats :json
|
33
33
|
service.response do |response|
|
34
34
|
response.array :vouchers do |node|
|
@@ -104,7 +104,7 @@ describe "WeaselDiesel JSON response description" do
|
|
104
104
|
end
|
105
105
|
|
106
106
|
it "should allow an anonymous object at the root of the response" do
|
107
|
-
service =
|
107
|
+
service = describe_service "json_anonymous_obj" do |service|
|
108
108
|
service.formats :json
|
109
109
|
service.response do |response|
|
110
110
|
response.object do |obj|
|
@@ -120,7 +120,7 @@ describe "WeaselDiesel JSON response description" do
|
|
120
120
|
obj.properties.find{|prop| prop.name == :id}.should_not be_nil
|
121
121
|
obj.properties.find{|prop| prop.name == :foo}.should_not be_nil
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
end
|
125
125
|
|
126
126
|
|
@@ -134,7 +134,7 @@ describe "WeaselDiesel simple JSON object response description" do
|
|
134
134
|
|
135
135
|
before :all do
|
136
136
|
@timestamp = Time.now.to_i
|
137
|
-
@service =
|
137
|
+
@service = describe_service "json_obj" do |service|
|
138
138
|
service.formats :json
|
139
139
|
service.response do |response|
|
140
140
|
response.object :organization do |node|
|
@@ -165,7 +165,7 @@ describe "WeaselDiesel anonymous JSON object response description" do
|
|
165
165
|
|
166
166
|
before :all do
|
167
167
|
@timestamp = Time.now.to_i
|
168
|
-
@service =
|
168
|
+
@service = describe_service "anon_json_obj" do |service|
|
169
169
|
service.formats :json
|
170
170
|
service.response do |response|
|
171
171
|
response.object do |node|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative '../lib/json_response_verification'
|
3
3
|
|
4
4
|
WeaselDiesel.send(:include, JSONResponseVerification)
|
5
5
|
|
@@ -70,7 +70,7 @@ describe ParamsVerification do
|
|
70
70
|
params['timestamp'] = Time.now.iso8601
|
71
71
|
lambda { ParamsVerification.validate!(params, @service.defined_params) }.should_not raise_error
|
72
72
|
params['timestamp'] = Time.now.getutc.iso8601
|
73
|
-
lambda { ParamsVerification.validate!(params, @service.defined_params) }.should_not raise_error
|
73
|
+
lambda { ParamsVerification.validate!(params, @service.defined_params) }.should_not raise_error
|
74
74
|
end
|
75
75
|
|
76
76
|
it "should set the default value for a namespace optional param" do
|
@@ -111,7 +111,7 @@ describe ParamsVerification do
|
|
111
111
|
it "should not raise an exception if a req array param doesn't contain a comma" do
|
112
112
|
service = WSList.find(:post, "/services/array_param.xml")
|
113
113
|
params = {'seq' => "a b c d e g"}
|
114
|
-
lambda{ ParamsVerification.validate!(params, service.defined_params) }.should_not raise_exception
|
114
|
+
lambda{ ParamsVerification.validate!(params, service.defined_params) }.should_not raise_exception
|
115
115
|
end
|
116
116
|
|
117
117
|
it "should raise an exception when a param is of the wrong type" do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,9 +1,3 @@
|
|
1
|
-
if RUBY_VERSION =~ /1.8/
|
2
|
-
require 'rubygems'
|
3
|
-
require 'backports'
|
4
|
-
require 'json'
|
5
|
-
end
|
6
|
-
|
7
1
|
require 'rspec'
|
8
2
|
require 'rack/test'
|
9
3
|
require 'sinatra'
|
@@ -16,5 +10,6 @@ require_relative "../lib/framework_ext/sinatra_controller"
|
|
16
10
|
ENV["RACK_ENV"] = 'test'
|
17
11
|
|
18
12
|
RSpec.configure do |conf|
|
13
|
+
conf.include WeaselDiesel::DSL
|
19
14
|
conf.include Rack::Test::Methods
|
20
15
|
end
|
data/spec/test_services.rb
CHANGED
@@ -7,8 +7,8 @@ describe_service "services/test.xml" do |service|
|
|
7
7
|
service.http_verb :get
|
8
8
|
|
9
9
|
service.params do |p|
|
10
|
-
p.string :framework,
|
11
|
-
:in => WeaselDieselSpecOptions,
|
10
|
+
p.string :framework,
|
11
|
+
:in => WeaselDieselSpecOptions,
|
12
12
|
:required => true,
|
13
13
|
:doc => "The test framework used, could be one of the two following: #{WeaselDieselSpecOptions.join(", ")}."
|
14
14
|
|
@@ -38,7 +38,6 @@ describe_service "services/test.xml" do |service|
|
|
38
38
|
# the response contains a list of player creation ratings each object in the list
|
39
39
|
|
40
40
|
=begin
|
41
|
-
#Format not supported by Ruby 1.8 due to hash insertion order not being maintained.
|
42
41
|
service.response do |response|
|
43
42
|
response.element(:name => "player_creation_ratings") do |e|
|
44
43
|
e.attribute :id => :integer, :doc => "id doc"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
2
|
|
3
3
|
describe WeaselDiesel::Documentation do
|
4
4
|
|
@@ -77,7 +77,9 @@ The most common way to use this service looks like that:
|
|
77
77
|
it "should have a json representation of an response element" do
|
78
78
|
json = @service.response.elements.first.to_json
|
79
79
|
loaded_json = JSON.load(json)
|
80
|
-
loaded_json
|
80
|
+
loaded_json.has_key?(@service.response.elements.first.name).should be_true
|
81
|
+
loaded_json[@service.response.elements.first.name].should_not be_empty
|
82
|
+
loaded_json[@service.response.elements.first.name].has_key?("player_creation_rating").should be_true
|
81
83
|
end
|
82
84
|
|
83
85
|
it "should have documentation for a response element attribute" do
|
data/spec/wd_params_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
2
|
|
3
3
|
describe WeaselDiesel::Params do
|
4
4
|
|
@@ -69,7 +69,7 @@ describe WeaselDiesel::Params do
|
|
69
69
|
|
70
70
|
it "should have options" do
|
71
71
|
@rule.options[:type].should == :string
|
72
|
-
@rule.options[:in].should ==
|
72
|
+
@rule.options[:in].should == WeaselDieselSpecOptions
|
73
73
|
@rule.options[:null].should be_false
|
74
74
|
end
|
75
75
|
end
|
data/spec/wd_spec.rb
CHANGED
data/spec/ws_list_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
2
|
require 'sinatra'
|
3
|
-
|
3
|
+
require_relative '../lib/framework_ext/sinatra'
|
4
4
|
WeaselDiesel.send(:include, WeaselDieselSinatraExtension)
|
5
5
|
|
6
6
|
describe "Hello World example" do
|
data/weasel_diesel.gemspec
CHANGED
@@ -10,6 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.homepage = "https://github.com/mattetti/Weasel-Diesel"
|
11
11
|
s.summary = %q{Web Service DSL}
|
12
12
|
s.description = %q{Ruby DSL describing Web Services without implementation details.}
|
13
|
+
s.license = 'MIT'
|
13
14
|
|
14
15
|
s.rubyforge_project = "wsdsl"
|
15
16
|
|
@@ -18,14 +19,12 @@ Gem::Specification.new do |s|
|
|
18
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
20
|
s.require_paths = ["lib"]
|
20
21
|
|
22
|
+
s.add_dependency('thor')
|
23
|
+
|
21
24
|
# specify any dependencies here; for example:
|
22
25
|
s.add_development_dependency "rspec"
|
23
26
|
s.add_development_dependency "rack-test"
|
24
27
|
s.add_development_dependency "yard"
|
25
28
|
s.add_development_dependency "sinatra"
|
26
|
-
|
27
|
-
if RUBY_VERSION =~ /1.8/
|
28
|
-
s.add_runtime_dependency "backports"
|
29
|
-
s.add_runtime_dependency "json"
|
30
|
-
end
|
29
|
+
s.add_development_dependency "rake"
|
31
30
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: weasel_diesel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Aimonetti
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rspec
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -83,7 +97,8 @@ dependencies:
|
|
83
97
|
description: Ruby DSL describing Web Services without implementation details.
|
84
98
|
email:
|
85
99
|
- mattaimonetti@gmail.com
|
86
|
-
executables:
|
100
|
+
executables:
|
101
|
+
- weasel_diesel
|
87
102
|
extensions: []
|
88
103
|
extra_rdoc_files: []
|
89
104
|
files:
|
@@ -94,16 +109,21 @@ files:
|
|
94
109
|
- LICENSE
|
95
110
|
- README.md
|
96
111
|
- Rakefile
|
112
|
+
- bin/weasel_diesel
|
97
113
|
- lib/documentation.rb
|
98
114
|
- lib/framework_ext/sinatra.rb
|
99
115
|
- lib/framework_ext/sinatra_controller.rb
|
100
116
|
- lib/inflection.rb
|
101
117
|
- lib/json_response_verification.rb
|
102
|
-
- lib/kernel_ext.rb
|
103
118
|
- lib/params.rb
|
104
119
|
- lib/params_verification.rb
|
105
120
|
- lib/response.rb
|
106
121
|
- lib/weasel_diesel.rb
|
122
|
+
- lib/weasel_diesel/cli.rb
|
123
|
+
- lib/weasel_diesel/doc_generator/_input_params.erb
|
124
|
+
- lib/weasel_diesel/doc_generator/_response_element.erb
|
125
|
+
- lib/weasel_diesel/doc_generator/template.erb
|
126
|
+
- lib/weasel_diesel/dsl.rb
|
107
127
|
- lib/weasel_diesel/version.rb
|
108
128
|
- lib/ws_list.rb
|
109
129
|
- spec/hello_world_controller.rb
|
@@ -122,7 +142,8 @@ files:
|
|
122
142
|
- spec/wsdsl_sinatra_ext_spec.rb
|
123
143
|
- weasel_diesel.gemspec
|
124
144
|
homepage: https://github.com/mattetti/Weasel-Diesel
|
125
|
-
licenses:
|
145
|
+
licenses:
|
146
|
+
- MIT
|
126
147
|
metadata: {}
|
127
148
|
post_install_message:
|
128
149
|
rdoc_options: []
|
@@ -140,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
161
|
version: '0'
|
141
162
|
requirements: []
|
142
163
|
rubyforge_project: wsdsl
|
143
|
-
rubygems_version: 2.0.
|
164
|
+
rubygems_version: 2.0.7
|
144
165
|
signing_key:
|
145
166
|
specification_version: 4
|
146
167
|
summary: Web Service DSL
|
data/lib/kernel_ext.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# Extending the top level module to add some helpers
|
2
|
-
#
|
3
|
-
# @api public
|
4
|
-
module Kernel
|
5
|
-
|
6
|
-
# Base DSL method called to describe a service
|
7
|
-
#
|
8
|
-
# @param [String] url The url of the service to add.
|
9
|
-
# @yield [WeaselDiesel] The newly created service.
|
10
|
-
# @return [Array] The services already defined
|
11
|
-
# @example Describing a basic service
|
12
|
-
# describe_service "hello-world.xml" do |service|
|
13
|
-
# # describe the service
|
14
|
-
# end
|
15
|
-
#
|
16
|
-
# @api public
|
17
|
-
def describe_service(url, &block)
|
18
|
-
service = WeaselDiesel.new(url)
|
19
|
-
yield service
|
20
|
-
|
21
|
-
service.sync_input_param_doc
|
22
|
-
WSList.add(service)
|
23
|
-
|
24
|
-
service
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|