weasel_diesel 1.2.2 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![CI Build Status](https://secure.travis-ci.org/mattetti/Weasel-Diesel.png?branch=master)](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
|