weasel_diesel 1.0.0 → 1.0.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.
- data/.gitignore +1 -0
- data/README.md +50 -64
- data/lib/response.rb +9 -8
- data/lib/weasel_diesel/version.rb +1 -1
- data/spec/json_response_description_spec.rb +63 -0
- data/spec/wsdsl_spec.rb +4 -1
- metadata +11 -11
- data/Gemfile.lock +0 -38
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# Web Service DSL
|
2
2
|
|
3
|
-
Weasel Diesel is a
|
4
|
-
|
5
|
-
|
3
|
+
Weasel Diesel is a DSL to describe and document your web API.
|
4
|
+
|
5
|
+
To get you going quickly, there's a Sinatra-based [example
|
6
6
|
application](https://github.com/mattetti/sinatra-web-api-example) that
|
7
|
-
you can
|
7
|
+
you can fork and use as a base for your application.
|
8
8
|
|
9
9
|
DSL examples:
|
10
10
|
|
@@ -20,9 +20,9 @@ describe_service "hello_world" do |service|
|
|
20
20
|
# OUTPUT
|
21
21
|
service.response do |response|
|
22
22
|
response.object do |obj|
|
23
|
-
|
23
|
+
obj.string :message, :doc => "The greeting message sent back. Defaults to 'World'"
|
24
24
|
obj.datetime :at, :doc => "The timestamp of when the message was dispatched"
|
25
|
-
|
25
|
+
end
|
26
26
|
end
|
27
27
|
|
28
28
|
# DOCUMENTATION
|
@@ -41,30 +41,7 @@ describe_service "hello_world" do |service|
|
|
41
41
|
end
|
42
42
|
```
|
43
43
|
|
44
|
-
|
45
|
-
describe_service "hello_world" do |service|
|
46
|
-
service.formats :xml
|
47
|
-
service.http_verb :get
|
48
|
-
service.disable_auth # on by default
|
49
|
-
|
50
|
-
service.param.string :name, :default => 'World'
|
51
|
-
|
52
|
-
service.response do |response|
|
53
|
-
response.element(:name => "greeting") do |e|
|
54
|
-
e.attribute "message" => :string, :doc => "The greeting message sent back."
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
service.documentation do |doc|
|
59
|
-
doc.overall "This service provides a simple hello world implementation example."
|
60
|
-
doc.params :name, "The name of the person to greet."
|
61
|
-
doc.example "<code>http://example.com/hello_world.xml?name=Matt</code>"
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
```
|
66
|
-
|
67
|
-
Or a more complex example:
|
44
|
+
Or a more complex example using XML:
|
68
45
|
|
69
46
|
``` ruby
|
70
47
|
SpecOptions = ['RSpec', 'Bacon'] # usually pulled from a model
|
@@ -73,6 +50,7 @@ Or a more complex example:
|
|
73
50
|
service.formats :xml, :json
|
74
51
|
service.http_verb :get
|
75
52
|
|
53
|
+
# INPUT
|
76
54
|
service.params do |p|
|
77
55
|
p.string :framework, :in => SpecOptions, :null => false, :required => true
|
78
56
|
|
@@ -80,18 +58,13 @@ Or a more complex example:
|
|
80
58
|
p.string :alpha, :in => ['a', 'b', 'c']
|
81
59
|
p.string :version, :null => false
|
82
60
|
p.integer :num, :minvalue => 42
|
61
|
+
p.namespace :user do |user|
|
62
|
+
user.integer :id, :required => :true
|
63
|
+
end
|
83
64
|
end
|
84
65
|
|
85
|
-
#
|
86
|
-
# All params are optional by default.
|
87
|
-
# service.param :epsilon, :type => 'string'
|
88
|
-
|
89
|
-
service.params.namespace :user do |user|
|
90
|
-
user.integer :id, :required => :true
|
91
|
-
end
|
92
|
-
|
66
|
+
# OUTPUT
|
93
67
|
# the response contains a list of player creation ratings each object in the list
|
94
|
-
|
95
68
|
service.response do |response|
|
96
69
|
response.element(:name => "player_creation_ratings") do |e|
|
97
70
|
e.attribute :id => :integer, :doc => "id doc"
|
@@ -107,6 +80,7 @@ Or a more complex example:
|
|
107
80
|
end
|
108
81
|
end
|
109
82
|
|
83
|
+
# DOCUMENTATION
|
110
84
|
service.documentation do |doc|
|
111
85
|
# doc.overall <markdown description text>
|
112
86
|
doc.overall <<-DOC
|
@@ -128,11 +102,9 @@ Or a more complex example:
|
|
128
102
|
|
129
103
|
## JSON APIs
|
130
104
|
|
131
|
-
This library was designed with XML responses in mind and JSON support
|
132
|
-
was added later on which explains why some response methods are aliases.
|
133
105
|
Consider the following JSON response:
|
134
106
|
|
135
|
-
```
|
107
|
+
```
|
136
108
|
{ people: [
|
137
109
|
{
|
138
110
|
id : 1,
|
@@ -153,6 +125,7 @@ Consider the following JSON response:
|
|
153
125
|
}
|
154
126
|
},
|
155
127
|
] }
|
128
|
+
```
|
156
129
|
|
157
130
|
It would be described as follows:
|
158
131
|
|
@@ -173,30 +146,46 @@ It would be described as follows:
|
|
173
146
|
end
|
174
147
|
```
|
175
148
|
|
176
|
-
Nodes/elements can also use some meta
|
177
|
-
following meta attributes are available:
|
149
|
+
Nodes/elements can also use some meta-attributes including:
|
178
150
|
|
179
|
-
* key
|
180
|
-
* type
|
181
|
-
cross OO based apps.
|
151
|
+
* `key` : refers to an attribute name that is key to this object
|
152
|
+
* `type` : refers to the type of object described, valuable when using JSON across OO based apps.
|
182
153
|
|
183
|
-
JSON response validation can be done using an optional module
|
184
|
-
|
185
|
-
|
154
|
+
JSON response validation can be done using an optional module as shown in
|
155
|
+
(spec/json_response_verification_spec.rb)[https://github.com/mattetti/Weasel-Diesel/blob/master/spec/json_response_verification_spec.rb].
|
156
|
+
The goal of this module is to help automate API testing by
|
186
157
|
validating the data structure of the returned object.
|
187
158
|
|
188
|
-
## Test suite
|
189
159
|
|
190
|
-
|
191
|
-
|
192
|
-
|
160
|
+
Other JSON DSL examples:
|
161
|
+
|
162
|
+
```
|
163
|
+
{"organization": {"name": "Example"}}
|
164
|
+
```
|
165
|
+
|
166
|
+
``` Ruby
|
167
|
+
describe_service "example" do |service|
|
168
|
+
service.formats :json
|
169
|
+
service.response do |response|
|
170
|
+
response.object :organization do |node|
|
171
|
+
node.string :name
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
```
|
176
|
+
|
177
|
+
|
178
|
+
## Test Suite & Dependencies
|
193
179
|
|
194
|
-
|
180
|
+
The test suite requires Ruby 1.9.* along with `RSpec`, `Rack`, and `Sinatra` gems.
|
195
181
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
182
|
+
## Usage with Ruby 1.8
|
183
|
+
|
184
|
+
This library prioritizes Ruby 1.9, but 1.8 support was added
|
185
|
+
via the backports library and some tweaks.
|
186
|
+
|
187
|
+
However, because Ruby 1.8 hashes do not preserve insert order, the following syntax
|
188
|
+
**will not work**:
|
200
189
|
|
201
190
|
``` ruby
|
202
191
|
service.response do |response|
|
@@ -208,7 +197,7 @@ isn't supported and the alternative version needs to be used:
|
|
208
197
|
end
|
209
198
|
```
|
210
199
|
|
211
|
-
Instead
|
200
|
+
Instead, this alternate syntax must be used:
|
212
201
|
|
213
202
|
``` ruby
|
214
203
|
service.response do |response|
|
@@ -220,10 +209,7 @@ Instead the following version should be used:
|
|
220
209
|
end
|
221
210
|
```
|
222
211
|
|
223
|
-
|
224
|
-
only.
|
225
|
-
|
226
|
-
|
212
|
+
The end results are identical.
|
227
213
|
|
228
214
|
## Copyright
|
229
215
|
|
data/lib/response.rb
CHANGED
@@ -62,12 +62,13 @@ class WeaselDiesel
|
|
62
62
|
el
|
63
63
|
end
|
64
64
|
|
65
|
-
# Defines an
|
66
|
-
#
|
67
|
-
#
|
68
|
-
# @
|
69
|
-
|
70
|
-
|
65
|
+
# Defines an element/object in a consistent way with
|
66
|
+
# the way objects are defined in nested objects.
|
67
|
+
# @param [Symbol, String] name the name of the element.
|
68
|
+
# @param [Hash] opts the options for the newly created element.
|
69
|
+
# @return [WeaselDiesel::Response] returns self since it yields to the used block.
|
70
|
+
def object(name=nil, opts={})
|
71
|
+
yield element(opts.merge(:name => name))
|
71
72
|
end
|
72
73
|
|
73
74
|
# Returns a response element object based on its name
|
@@ -361,10 +362,10 @@ class WeaselDiesel
|
|
361
362
|
output << "<ul>"
|
362
363
|
properties.each do |prop|
|
363
364
|
output << "<li><span class='label notice'>#{prop.name}</span> of type <span class='label success'>#{prop.type}</span> #{'(Can be blank or missing) ' if prop.opts && prop.opts.respond_to?(:[]) && prop.opts[:null]} "
|
364
|
-
output << prop.doc unless prop.doc.
|
365
|
+
output << prop.doc unless prop.doc.nil? or prop.doc.empty?
|
365
366
|
output << "</li>"
|
366
367
|
end
|
367
|
-
arrays.each{ |arr| output << arr.
|
368
|
+
arrays.each{ |arr| output << arr.to_html }
|
368
369
|
elements.each {|el| output << el.to_html } if elements
|
369
370
|
output << "</ul>"
|
370
371
|
output << "</li>" if name
|
@@ -122,3 +122,66 @@ describe "WeaselDiesel JSON response description" do
|
|
122
122
|
end
|
123
123
|
|
124
124
|
end
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
describe "WeaselDiesel simple JSON object response description" do
|
129
|
+
|
130
|
+
# JSON response example
|
131
|
+
=begin
|
132
|
+
{"organization": {"name": "Example"}}
|
133
|
+
=end
|
134
|
+
|
135
|
+
before :all do
|
136
|
+
@timestamp = Time.now.to_i
|
137
|
+
@service = describe_service "json_obj" do |service|
|
138
|
+
service.formats :json
|
139
|
+
service.response do |response|
|
140
|
+
response.object :organization do |node|
|
141
|
+
node.string :name
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
@response = @service.response
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should have a properly structured reponse" do
|
149
|
+
top_object = @service.response.element_named(:organization)
|
150
|
+
top_object.should_not be_nil
|
151
|
+
name_node = top_object.properties.find{|o| o.name == :name}
|
152
|
+
name_node.should_not be_nil
|
153
|
+
name_node.type.should == :string
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
describe "WeaselDiesel anonymous JSON object response description" do
|
160
|
+
|
161
|
+
# JSON response example
|
162
|
+
=begin
|
163
|
+
{"name": "Example"}
|
164
|
+
=end
|
165
|
+
|
166
|
+
before :all do
|
167
|
+
@timestamp = Time.now.to_i
|
168
|
+
@service = describe_service "anon_json_obj" do |service|
|
169
|
+
service.formats :json
|
170
|
+
service.response do |response|
|
171
|
+
response.object do |node|
|
172
|
+
node.string :name
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
@response = @service.response
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should have a properly structured reponse" do
|
180
|
+
top_object = @service.response.elements.first
|
181
|
+
top_object.should_not be_nil
|
182
|
+
name_node = top_object.properties.find{|o| o.name == :name}
|
183
|
+
name_node.should_not be_nil
|
184
|
+
name_node.type.should == :string
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
data/spec/wsdsl_spec.rb
CHANGED
@@ -309,6 +309,9 @@ The most common way to use this service looks like that:
|
|
309
309
|
attribute.doc.should == "comments doc"
|
310
310
|
end
|
311
311
|
|
312
|
-
|
312
|
+
it "should emit html documention for elements" do
|
313
|
+
@service.response.elements.first.to_html.should be_a(String)
|
314
|
+
end
|
313
315
|
|
316
|
+
end
|
314
317
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: weasel_diesel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70204984229320 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70204984229320
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rack-test
|
27
|
-
requirement: &
|
27
|
+
requirement: &70204984228900 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70204984228900
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: yard
|
38
|
-
requirement: &
|
38
|
+
requirement: &70204984228480 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70204984228480
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: sinatra
|
49
|
-
requirement: &
|
49
|
+
requirement: &70204984228060 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70204984228060
|
58
58
|
description: Ruby DSL describing Web Services without implementation details.
|
59
59
|
email:
|
60
60
|
- mattaimonetti@gmail.com
|
@@ -62,8 +62,8 @@ executables: []
|
|
62
62
|
extensions: []
|
63
63
|
extra_rdoc_files: []
|
64
64
|
files:
|
65
|
+
- .gitignore
|
65
66
|
- Gemfile
|
66
|
-
- Gemfile.lock
|
67
67
|
- LICENSE
|
68
68
|
- README.md
|
69
69
|
- Rakefile
|
data/Gemfile.lock
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
wsdsl (1.0.0)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: http://rubygems.org/
|
8
|
-
specs:
|
9
|
-
diff-lcs (1.1.3)
|
10
|
-
rack (1.4.1)
|
11
|
-
rack-protection (1.2.0)
|
12
|
-
rack
|
13
|
-
rack-test (0.6.1)
|
14
|
-
rack (>= 1.0)
|
15
|
-
rspec (2.9.0)
|
16
|
-
rspec-core (~> 2.9.0)
|
17
|
-
rspec-expectations (~> 2.9.0)
|
18
|
-
rspec-mocks (~> 2.9.0)
|
19
|
-
rspec-core (2.9.0)
|
20
|
-
rspec-expectations (2.9.1)
|
21
|
-
diff-lcs (~> 1.1.3)
|
22
|
-
rspec-mocks (2.9.0)
|
23
|
-
sinatra (1.3.2)
|
24
|
-
rack (~> 1.3, >= 1.3.6)
|
25
|
-
rack-protection (~> 1.2)
|
26
|
-
tilt (~> 1.3, >= 1.3.3)
|
27
|
-
tilt (1.3.3)
|
28
|
-
yard (0.7.5)
|
29
|
-
|
30
|
-
PLATFORMS
|
31
|
-
ruby
|
32
|
-
|
33
|
-
DEPENDENCIES
|
34
|
-
rack-test
|
35
|
-
rspec
|
36
|
-
sinatra
|
37
|
-
wsdsl!
|
38
|
-
yard
|