weasel_diesel 1.0.2 → 1.0.3

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.
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - jruby-18mode
7
+ - jruby-19mode
8
+ - rbx-18mode
9
+ - rbx-19mode
10
+ - ruby-head
11
+ - jruby-head
12
+ - ree
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in weasel_diesel.gemspec
4
4
  gemspec
5
+
6
+ gem "json", :platform => :jruby
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Web Service DSL
2
2
 
3
+ [![CI Build Status](https://secure.travis-ci.org/mattetti/Weasel-Diesel.png?branch=master)](http://travis-ci.org/mattetti/Weasel-Diesel)
4
+
3
5
  Weasel Diesel is a DSL to describe and document your web API.
4
6
 
5
7
  To get you going quickly, see the [generator for sinatra apps](https://github.com/mattetti/wd-sinatra).
@@ -20,7 +22,7 @@ describe_service "hello_world" do |service|
20
22
  service.disable_auth # on by default
21
23
 
22
24
  # INPUT
23
- service.param.string :name, :default => 'World'
25
+ service.param.string :name, :default => 'World', :doc => "The name of the person to greet."
24
26
 
25
27
  # OUTPUT
26
28
  service.response do |response|
@@ -33,7 +35,6 @@ describe_service "hello_world" do |service|
33
35
  # DOCUMENTATION
34
36
  service.documentation do |doc|
35
37
  doc.overall "This service provides a simple hello world implementation example."
36
- doc.param :name, "The name of the person to greet."
37
38
  doc.example "<code>curl -I 'http://localhost:9292/hello_world?name=Matt'</code>"
38
39
  end
39
40
 
@@ -59,9 +60,15 @@ Or a more complex example using XML:
59
60
  service.params do |p|
60
61
  p.string :framework, :in => SpecOptions, :null => false, :required => true
61
62
 
62
- p.datetime :timestamp, :default => Time.now
63
+ p.datetime :timestamp,
64
+ :default => Time.now,
65
+ :doc => "The test framework used, could be one of the two following: #{SpecOptions.join(", ")}."
66
+
63
67
  p.string :alpha, :in => ['a', 'b', 'c']
64
- p.string :version, :null => false
68
+ p.string :version,
69
+ :null => false,
70
+ :doc => "The version of the framework to use."
71
+
65
72
  p.integer :num, :minvalue => 42
66
73
  p.namespace :user do |user|
67
74
  user.integer :id, :required => :true
@@ -92,10 +99,6 @@ Or a more complex example using XML:
92
99
  This is a test service used to test the framework.
93
100
  DOC
94
101
 
95
- # doc.params <name>, <definition>
96
- doc.params :framework, "The test framework used, could be one of the two following: #{SpecOptions.join(", ")}."
97
- doc.params :version, "The version of the framework to use."
98
-
99
102
  # doc.example <markdown text>
100
103
  doc.example <<-DOC
101
104
  The most common way to use this service looks like that:
@@ -119,6 +119,7 @@ class WeaselDiesel
119
119
  end
120
120
  @namespaced_params << new_ns_param
121
121
  end
122
+ alias :object :namespace
122
123
 
123
124
  def response
124
125
  @response ||= Documentation.new
@@ -24,10 +24,10 @@ class WeaselDiesel
24
24
  # @option options [Symbol] :default The default value of the param.
25
25
  # @option options [Symbol] :minvalue The minimum acceptable value.
26
26
  # @option options [Symbol] :maxvalue The maximim acceptable value.
27
+ # @option options [Symbol] :doc Documentation for the param.
27
28
  # @api public
28
29
  attr_reader :options
29
30
 
30
-
31
31
  # @param [Symbol, String] name
32
32
  # The param's name
33
33
  # @param [Hash] opts The rule options
@@ -36,6 +36,7 @@ class WeaselDiesel
36
36
  # @option opts [Symbol] :default The default value of the param.
37
37
  # @option opts [Symbol] :minvalue The minimum acceptable value.
38
38
  # @option opts [Symbol] :maxvalue The maximim acceptable value.
39
+ # @option opts [Symbol] :doc Documentation for the param.
39
40
  # @api public
40
41
  def initialize(name, opts = {})
41
42
  @name = name
@@ -50,6 +51,14 @@ class WeaselDiesel
50
51
  @options[:space_name]
51
52
  end
52
53
 
54
+ # The documentation of this Rule
55
+ #
56
+ # @return [NilClass, String]
57
+ # api public
58
+ def doc
59
+ @options[:doc]
60
+ end
61
+
53
62
  # Converts the rule into a hash with its name and options.
54
63
  #
55
64
  # @return [Hash]
@@ -351,6 +360,7 @@ class WeaselDiesel
351
360
  yield(params) if block_given?
352
361
  namespaced_params << params unless namespaced_params.include?(params)
353
362
  end
363
+ alias :object :namespace
354
364
 
355
365
  # Returns the namespaced params
356
366
  #
@@ -79,7 +79,7 @@ module ParamsVerification
79
79
  params.each_pair do |key, value|
80
80
  if value.is_a?(Hash)
81
81
  namespaced = service_params.namespaced_params.find{|np| np.space_name.to_s == key.to_s}
82
- raise UnexpectedParam, "Request included unexpected parameter: #{key}" if namespaced.nil?
82
+ raise UnexpectedParam, "Request included unexpected parameter: #{ERB::Util.html_escape(key)}" if namespaced.nil?
83
83
  unexpected_params?(params[key], namespaced.param_names)
84
84
  end
85
85
  end
@@ -123,7 +123,7 @@ module ParamsVerification
123
123
  verify_cast(param_name, param_value, rule.options[:type])
124
124
  end
125
125
 
126
- if rule.options[:options] || rule.options[:in]
126
+ if rule.options[:options] || rule.options[:in.inspect]
127
127
  choices = rule.options[:options] || rule.options[:in]
128
128
  if rule.options[:type]
129
129
  # Force the cast so we can compare properly
@@ -348,6 +348,13 @@ class WeaselDiesel
348
348
  end
349
349
  end
350
350
 
351
+ # Converts an element into a json representation
352
+ #
353
+ # @return [String] the element attributes formated in a json structure
354
+ def to_json
355
+ to_hash.to_json
356
+ end
357
+
351
358
  def to_html
352
359
  output = ""
353
360
  if name
@@ -408,7 +408,17 @@ module Kernel
408
408
  def describe_service(url, &block)
409
409
  service = WeaselDiesel.new(url)
410
410
  yield service
411
+
412
+ service.defined_params.list_optional.each do |rule|
413
+ service.doc.param(rule.name, rule.options[:doc]) if rule.options[:doc]
414
+ end
415
+
416
+ service.defined_params.list_required.each do |rule|
417
+ service.doc.param(rule.name, rule.options[:doc]) if rule.options[:doc]
418
+ end
419
+
411
420
  WSList.add(service)
421
+
412
422
  service
413
423
  end
414
424
 
@@ -1,3 +1,3 @@
1
1
  class WeaselDiesel
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.3"
3
3
  end
@@ -5,12 +5,16 @@ describe_service "services/test.xml" do |service|
5
5
  service.http_verb :get
6
6
 
7
7
  service.params do |p|
8
- p.string :framework, :in => WeaselDieselSpecOptions, :null => false, :required => true
8
+ p.string :framework,
9
+ :in => WeaselDieselSpecOptions,
10
+ :null => false,
11
+ :required => true,
12
+ :doc => "The test framework used, could be one of the two following: #{WeaselDieselSpecOptions.join(", ")}."
9
13
 
10
14
  p.datetime :timestamp, :default => Time.now
11
15
  p.string :alpha, :in => ['a', 'b', 'c']
12
- p.string :version, :null => false
13
- p.integer :num, :minvalue => 42
16
+ p.string :version, :null => false, :doc => "The version of the framework to use."
17
+ p.integer :num, :minvalue => 42, :doc => "The number to test"
14
18
 
15
19
  end
16
20
 
@@ -66,10 +70,6 @@ describe_service "services/test.xml" do |service|
66
70
  This is a test service used to test the framework.
67
71
  DOC
68
72
 
69
- # doc.params <name>, <definition>
70
- doc.param :framework, "The test framework used, could be one of the two following: #{WeaselDieselSpecOptions.join(", ")}."
71
- doc.param :version, "The version of the framework to use."
72
-
73
73
  # doc.example <markdown text>
74
74
  doc.example <<-DOC
75
75
  The most common way to use this service looks like that:
@@ -0,0 +1,161 @@
1
+ require File.expand_path("spec_helper", File.dirname(__FILE__))
2
+
3
+ describe "WeaselDiesel #controller_dispatch" do
4
+
5
+ before :all do
6
+ @service = WSList.all.find{|s| s.url == 'services/test.xml'}
7
+ @service.should_not be_nil
8
+ end
9
+
10
+ describe "#controller_dispatch" do
11
+
12
+ class ProjectsController
13
+ def initialize(app, service)
14
+ @app = app
15
+ @service = service.name
16
+ end
17
+
18
+ def send(action)
19
+ [@app, @service, action]
20
+ end
21
+ end
22
+
23
+ module Projects
24
+ class TasksController < ProjectsController
25
+ end
26
+ end
27
+
28
+ module Projects
29
+ module Tasks
30
+ class ItemsController < ProjectsController
31
+ end
32
+ end
33
+ end
34
+
35
+ before :all do
36
+ @original_use_controller_dispatch = WeaselDiesel.use_controller_dispatch
37
+ WeaselDiesel.use_controller_dispatch = true
38
+ @original_services = WSList.all.dup
39
+ WSList.all.clear
40
+ end
41
+
42
+ after :all do
43
+ WeaselDiesel.use_controller_dispatch = @original_use_controller_dispatch
44
+ WSList.all.replace @original_services
45
+ end
46
+
47
+ it "should be able to dispatch controller" do
48
+ describe_service("projects.xml") { |s| }
49
+ service = WSList["projects.xml"]
50
+ service.controller_dispatch("application").
51
+ should == ["application", "projects", "list"]
52
+ end
53
+
54
+ it "should be able to dispatch namespaced controller" do
55
+ describe_service("project/:project_id/tasks.xml") do |service|
56
+ service.controller_name = "Projects::TasksController"
57
+ service.action = "list"
58
+ end
59
+
60
+ describe_service("project/:project_id/task/:task_id/items.xml") do |service|
61
+ service.controller_name = "Projects::Tasks::ItemsController"
62
+ service.action = "list"
63
+ end
64
+
65
+ service = WSList["project/:project_id/tasks.xml"]
66
+ service.controller_dispatch("application").should == ["application", "project", "list"]
67
+
68
+ service = WSList["project/:project_id/task/:task_id/items.xml"]
69
+ service.controller_dispatch("application").should == ["application", "project", "list"]
70
+ end
71
+
72
+ it "should raise exception when controller class is not found" do
73
+ describe_service("unknown.xml") do |service|
74
+ service.controller_name = "UnknownController"
75
+ service.action = "list"
76
+ end
77
+ service = WSList["unknown.xml"]
78
+ lambda { service.controller_dispatch("application") }.
79
+ should raise_error("The UnknownController class was not found")
80
+ end
81
+
82
+ end
83
+
84
+ describe "With controller dispatch on" do
85
+ before :all do
86
+ @original_services = WSList.all.dup
87
+ WSList.all.clear
88
+ WeaselDiesel.use_controller_dispatch = true
89
+ load File.expand_path('test_services.rb', File.dirname(__FILE__))
90
+ @c_service = WSList.all.find{|s| s.url == 'services/test.xml'}
91
+ @c_service.should_not be_nil
92
+ end
93
+ after :all do
94
+ WeaselDiesel.use_controller_dispatch = false
95
+ WSList.all.replace @original_services
96
+ end
97
+
98
+ it "should set the controller accordingly" do
99
+ @c_service.controller_name.should_not be_nil
100
+ @c_service.controller_name.should == 'ServicesController'
101
+ service = WeaselDiesel.new("preferences.xml")
102
+ service.name.should == 'preferences'
103
+ ExtlibCopy.classify('preferences').should == 'Preferences'
104
+ service.controller_name.should == 'PreferencesController'
105
+ end
106
+
107
+ it "should set the action accordingly" do
108
+ @c_service.action.should_not be_nil
109
+ @c_service.action.should == 'test'
110
+ end
111
+
112
+ it "should support restful routes based on the HTTP verb" do
113
+ service = WSList.all.find{|s| s.url == "services.xml"}
114
+ service.should_not be_nil
115
+ service.http_verb.should == :put
116
+ service.action.should_not be_nil
117
+ service.controller_name.should == 'ServicesController'
118
+ service.action.should == 'update'
119
+ end
120
+
121
+ it "should have a default action" do
122
+ service = WeaselDiesel.new('spec_test.xml')
123
+ service.action.should == 'list'
124
+ end
125
+
126
+ it "should route to show when an id is the last passed param" do
127
+ service = WeaselDiesel.new("players/:id.xml")
128
+ service.action.should == 'show'
129
+ end
130
+
131
+ it "should support some extra attributes" do
132
+ service = WeaselDiesel.new("players/:id.xml")
133
+ service.extra[:custom_name] = 'fooBar'
134
+ service.extra[:custom_name].should == 'fooBar'
135
+ end
136
+
137
+ it "should respect the global controller pluralization flag" do
138
+ WeaselDiesel.use_pluralized_controllers = true
139
+ service = WeaselDiesel.new("player/:id.xml")
140
+ service.controller_name.should == "PlayersController"
141
+ service = WeaselDiesel.new("players/:id.xml")
142
+ service.controller_name.should == "PlayersController"
143
+ WeaselDiesel.use_pluralized_controllers = false
144
+ service = WeaselDiesel.new("player/:id.xml")
145
+ service.controller_name.should == "PlayerController"
146
+ end
147
+
148
+
149
+ it "should let overwrite the controller name and action after initialization" do
150
+ describe_service "players/:id.xml" do |service|
151
+ service.controller_name = "CustomController"
152
+ service.action = "foo"
153
+ end
154
+ service = WSList.all.find{|s| s.url == "players/:id.xml"}
155
+ service.controller_name.should == "CustomController"
156
+ service.action.should == "foo"
157
+ end
158
+
159
+ end
160
+
161
+ end
@@ -0,0 +1,149 @@
1
+ require File.expand_path("spec_helper", File.dirname(__FILE__))
2
+
3
+ describe WeaselDiesel::Documentation do
4
+
5
+ before :all do
6
+ @service = WSList.all.find{|s| s.url == 'services/test.xml'}
7
+ @service.should_not be_nil
8
+ @doc = @service.doc
9
+ @doc.should_not be_nil
10
+ end
11
+
12
+ it "should have an overall description" do
13
+ @doc.desc.strip.should == "This is a test service used to test the framework."
14
+ end
15
+
16
+ it "should have a list of params doc" do
17
+ @doc.params_doc.should be_an_instance_of(Hash)
18
+ @doc.params_doc.keys.sort.should == [:framework, :num, :version]
19
+ @doc.params_doc[:framework].should == "The test framework used, could be one of the two following: #{WeaselDieselSpecOptions.join(", ")}."
20
+ @doc.params_doc[:num].should == 'The number to test'
21
+ end
22
+
23
+ it "should allow to define namespaced params doc" do
24
+ service = WSList.all.find{|s| s.url == "services.xml"}
25
+ service.documentation do |doc|
26
+ doc.namespace :preference do |ns|
27
+ ns.param :id, "Ze id."
28
+ end
29
+ end
30
+ service.doc.namespaced_params.should_not be_empty
31
+ ns = service.doc.namespaced_params.find{|ns| ns.name == :preference}
32
+ ns.should_not be_nil
33
+ ns.params[:id].should == "Ze id."
34
+ end
35
+
36
+ it "should allow object to be an alias for namespace params" do
37
+ service = WSList.all.find{|s| s.url == "services.xml"}
38
+ service.documentation do |doc|
39
+ doc.object :preference do |ns|
40
+ ns.param :id, "Ze id."
41
+ end
42
+ end
43
+ service.doc.namespaced_params.should_not be_empty
44
+ ns = service.doc.namespaced_params.find{|ns| ns.name == :preference}
45
+ ns.should_not be_nil
46
+ ns.params[:id].should == "Ze id."
47
+ end
48
+
49
+ it "should have an optional list of examples" do
50
+ @doc.examples.should be_an_instance_of(Array)
51
+ @doc.examples.first.should == <<-DOC
52
+ The most common way to use this service looks like that:
53
+ http://example.com/services/test.xml?framework=rspec&version=2.0.0
54
+ DOC
55
+ end
56
+
57
+ it "should have the service response documented" do
58
+ @doc.response.should_not be_nil
59
+ end
60
+
61
+ it "should have documentation for the response elements via the response itself" do
62
+ @service.response.elements.first.should_not be_nil
63
+ @service.response.elements.first.doc.should_not be_nil
64
+ @service.response.elements.first.doc.name.should == "player_creation_ratings"
65
+ end
66
+
67
+ it "should have a json representation of an response element" do
68
+ json = @service.response.elements.first.to_json
69
+ loaded_json = JSON.load(json)
70
+ loaded_json[@service.response.elements.first.doc.name].should_not be_empty
71
+ end
72
+
73
+ it "should have documentation for a response element attribute" do
74
+ @service.response.elements.first.doc.attributes.should_not be_empty
75
+ @service.response.elements.first.doc.attributes[:id].should == "id doc"
76
+ end
77
+
78
+ it "should have documentation for a response element array" do
79
+ element = @service.response.elements.first
80
+ element.arrays.should_not be_empty
81
+ element.arrays.first.name.should == :player_creation_rating
82
+ element.arrays.first.type.should == "PlayerCreationRating"
83
+ element.arrays.first.attributes.should_not be_empty
84
+ end
85
+
86
+ it "should have documentation for the attributes of an response element array" do
87
+ element = @service.response.elements.first
88
+ array = element.arrays.first
89
+ attribute = array.attributes.find{|att| att.name == :comments }
90
+ attribute.should_not be_nil
91
+ attribute.name.should == :comments # just in case we change the way to find the attribute
92
+ attribute.doc.should == "comments doc"
93
+ end
94
+
95
+ it "should emit html documention for elements" do
96
+ @service.response.elements.first.to_html.should be_a(String)
97
+ end
98
+
99
+ describe "legacy param documentation" do
100
+
101
+ before :all do
102
+ @original_services = WSList.all.dup
103
+ WSList.all.clear
104
+ define_service
105
+ end
106
+
107
+ after :all do
108
+ WSList.all.replace @original_services
109
+ end
110
+
111
+ def define_service
112
+ describe_service "legacy_param_doc" do |service|
113
+ service.formats :xml, :json
114
+
115
+ service.params do |p|
116
+ p.string :framework, :in => WeaselDieselSpecOptions, :null => false, :required => true
117
+
118
+ p.datetime :timestamp, :default => Time.now
119
+ p.string :alpha, :in => ['a', 'b', 'c']
120
+ p.string :version, :null => false
121
+ p.integer :num, :minvalue => 42
122
+
123
+ end
124
+
125
+ service.params.namespace :user do |user|
126
+ user.integer :id, :required => :true
127
+ user.string :sex, :in => %Q{female, male}
128
+ user.boolean :mailing_list, :default => true
129
+ end
130
+
131
+ service.documentation do |doc|
132
+ # doc.overall <markdown description text>
133
+ doc.overall "This is a test service used to test the framework."
134
+ # doc.params <name>, <definition>
135
+ doc.param :framework, "The test framework used, could be one of the two following: #{WeaselDieselSpecOptions.join(", ")}."
136
+ doc.param :version, "The version of the framework to use."
137
+ end
138
+ end
139
+ end
140
+
141
+ it "should have the param documented" do
142
+ service = WSList["legacy_param_doc"]
143
+ service.doc.params_doc.keys.sort.should == [:framework, :version]
144
+ service.doc.params_doc[service.doc.params_doc.keys.first].should_not be_nil
145
+ end
146
+
147
+ end
148
+
149
+ end
@@ -0,0 +1,76 @@
1
+ require File.expand_path("spec_helper", File.dirname(__FILE__))
2
+
3
+ describe WeaselDiesel::Params do
4
+
5
+ before :all do
6
+ @service = WSList.all.find{|s| s.url == 'services/test.xml'}
7
+ @service.should_not be_nil
8
+ @sparams = @service.params
9
+ end
10
+
11
+ it "should have the possibility to have a space name" do
12
+ @sparams.should respond_to(:space_name)
13
+ service_params = WeaselDiesel::Params.new(:space_name => 'spec_test')
14
+ service_params.space_name.should == 'spec_test'
15
+ end
16
+
17
+ it "should have a list of required param rules" do
18
+ @sparams.list_required.should be_an_instance_of(Array)
19
+ @sparams.list_required.length.should == 1
20
+ end
21
+
22
+ it "should have a list of optional param rules" do
23
+ @sparams.list_optional.should be_an_instance_of(Array)
24
+ @sparams.list_optional.length.should == 4
25
+ end
26
+
27
+ it "should have a list of namespaced param rules" do
28
+ @sparams.namespaced_params.should be_an_instance_of(Array)
29
+ @sparams.namespaced_params.length.should == 1
30
+ @sparams.namespaced_params.first.space_name.should == :user
31
+ end
32
+
33
+ it "should allow to define namespaced param" do
34
+ service = WSList.all.find{|s| s.url == "services.xml"}
35
+ service.params do |params|
36
+ params.namespace :preference do |ns|
37
+ ns.param :id, "Ze id."
38
+ end
39
+ end
40
+ service.params.namespaced_params.should_not be_empty
41
+ ns = service.params.namespaced_params.find{|ns| ns.space_name == :preference}
42
+ ns.should_not be_nil
43
+ ns.list_optional.first.name.should == "Ze id."
44
+ end
45
+
46
+ it "should allow object as an alias to namespaced param" do
47
+ service = WSList.all.find{|s| s.url == "services.xml"}
48
+ service.params do |params|
49
+ params.object :preference do |ns|
50
+ ns.param :id, "Ze id."
51
+ end
52
+ end
53
+ service.params.namespaced_params.should_not be_empty
54
+ ns = service.params.namespaced_params.find{|ns| ns.space_name == :preference}
55
+ ns.should_not be_nil
56
+ ns.list_optional.first.name.should == "Ze id."
57
+ end
58
+
59
+ describe WeaselDiesel::Params::Rule do
60
+ before :all do
61
+ @rule = @sparams.list_required.first
62
+ @rule.should_not be_nil
63
+ end
64
+
65
+ it "should have a name" do
66
+ @rule.name.should == :framework
67
+ end
68
+
69
+ it "should have options" do
70
+ @rule.options[:type].should == :string
71
+ @rule.options[:in].should == WeaselDieselSpecOptions
72
+ @rule.options[:null].should be_false
73
+ end
74
+ end
75
+
76
+ end
@@ -0,0 +1,43 @@
1
+ require File.expand_path("spec_helper", File.dirname(__FILE__))
2
+
3
+ describe WeaselDiesel do
4
+
5
+ before :all do
6
+ @service = WSList.all.find{|s| s.url == 'services/test.xml'}
7
+ @service.should_not be_nil
8
+ end
9
+
10
+ it "should have an url" do
11
+ # dummy test since that's how we found the service, but oh well
12
+ @service.url.should == 'services/test.xml'
13
+ end
14
+
15
+ it "should have some http verbs defined" do
16
+ @service.verb.should == :get
17
+ end
18
+
19
+ it "should have supported formats defined" do
20
+ @service.formats.should == [:xml, :json]
21
+ end
22
+
23
+ it "should have params info" do
24
+ @service.params.should be_an_instance_of(WeaselDiesel::Params)
25
+ end
26
+
27
+ it "should have direct access to the required params" do
28
+ @service.required_rules.should == @service.params.list_required
29
+ end
30
+
31
+ it "should have direct access to the optional params" do
32
+ @service.optional_rules.should == @service.params.list_optional
33
+ end
34
+
35
+ it "should have direct access to the nested params" do
36
+ @service.nested_params.should == @service.params.namespaced_params
37
+ end
38
+
39
+ it "should have some documentation" do
40
+ @service.doc.should be_an_instance_of(WeaselDiesel::Documentation)
41
+ end
42
+
43
+ end
@@ -4,20 +4,30 @@ require File.expand_path("./../lib/framework_ext/sinatra.rb", File.dirname(__FIL
4
4
  WeaselDiesel.send(:include, WeaselDieselSinatraExtension)
5
5
 
6
6
  describe "Hello World example" do
7
- require_relative "hello_world_service"
8
- require_relative "hello_world_controller"
9
7
 
10
- def app
11
- Sinatra::Application
8
+ before :all do
9
+ @original_use_controller_dispatch = WeaselDiesel.use_controller_dispatch
10
+ WeaselDiesel.use_controller_dispatch = true
11
+ @original_services = WSList.all.dup
12
+ WSList.all.clear
13
+ require "hello_world_service"
14
+ require "hello_world_controller"
15
+ @service = WSList.all.find{|s| s.url == 'hello_world.xml'}
16
+ @service.should_not be_nil
17
+ @service.load_sinatra_route
18
+ end
19
+
20
+ after :all do
21
+ WeaselDiesel.use_controller_dispatch = @original_use_controller_dispatch
22
+ WSList.all.replace @original_services
12
23
  end
13
24
 
14
- before(:all) do
15
- service = WSList.all.find{|s| s.url == 'hello_world.xml'}
16
- service.should_not be_nil
17
- service.load_sinatra_route
25
+ def app
26
+ Sinatra::Application
18
27
  end
19
28
 
20
29
  it "should dispatch the hello world service properly" do
30
+ @service.controller_name.should == "HelloWorldController"
21
31
  get "/hello_world.xml"
22
32
  last_response.body.should include("Hello World")
23
33
  end
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
23
23
  s.add_development_dependency "rack-test"
24
24
  s.add_development_dependency "yard"
25
25
  s.add_development_dependency "sinatra"
26
+ s.add_development_dependency "rake"
26
27
  if RUBY_VERSION =~ /1.8/
27
28
  s.add_runtime_dependency "backports"
28
29
  s.add_runtime_dependency "json"
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.2
4
+ version: 1.0.3
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-05-11 00:00:00.000000000 Z
12
+ date: 2012-05-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70245501824860 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70245501824860
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: rack-test
27
- requirement: &70245501824280 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: '0'
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *70245501824280
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: yard
38
- requirement: &70245501823640 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ! '>='
@@ -43,10 +53,15 @@ dependencies:
43
53
  version: '0'
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *70245501823640
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: sinatra
49
- requirement: &70245501823060 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ! '>='
@@ -54,7 +69,28 @@ dependencies:
54
69
  version: '0'
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *70245501823060
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
58
94
  description: Ruby DSL describing Web Services without implementation details.
59
95
  email:
60
96
  - mattaimonetti@gmail.com
@@ -63,6 +99,7 @@ extensions: []
63
99
  extra_rdoc_files: []
64
100
  files:
65
101
  - .gitignore
102
+ - .travis.yml
66
103
  - Gemfile
67
104
  - LICENSE
68
105
  - README.md
@@ -86,8 +123,11 @@ files:
86
123
  - spec/preferences_service.rb
87
124
  - spec/spec_helper.rb
88
125
  - spec/test_services.rb
126
+ - spec/wd_controller_dispatch_spec.rb
127
+ - spec/wd_documentation_spec.rb
128
+ - spec/wd_params_spec.rb
129
+ - spec/wd_spec.rb
89
130
  - spec/wsdsl_sinatra_ext_spec.rb
90
- - spec/wsdsl_spec.rb
91
131
  - weasel_diesel.gemspec
92
132
  homepage: https://github.com/mattetti/Weasel-Diesel
93
133
  licenses: []
@@ -109,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
149
  version: '0'
110
150
  requirements: []
111
151
  rubyforge_project: wsdsl
112
- rubygems_version: 1.8.16
152
+ rubygems_version: 1.8.24
113
153
  signing_key:
114
154
  specification_version: 3
115
155
  summary: Web Service DSL
@@ -122,6 +162,9 @@ test_files:
122
162
  - spec/preferences_service.rb
123
163
  - spec/spec_helper.rb
124
164
  - spec/test_services.rb
165
+ - spec/wd_controller_dispatch_spec.rb
166
+ - spec/wd_documentation_spec.rb
167
+ - spec/wd_params_spec.rb
168
+ - spec/wd_spec.rb
125
169
  - spec/wsdsl_sinatra_ext_spec.rb
126
- - spec/wsdsl_spec.rb
127
170
  has_rdoc:
@@ -1,317 +0,0 @@
1
- require File.expand_path("spec_helper", File.dirname(__FILE__))
2
-
3
- describe WeaselDiesel do
4
-
5
- before :all do
6
- @service = WSList.all.find{|s| s.url == 'services/test.xml'}
7
- @service.should_not be_nil
8
- end
9
-
10
- it "should have an url" do
11
- # dummy test since that's how we found the service, but oh well
12
- @service.url.should == 'services/test.xml'
13
- end
14
-
15
- it "should have some http verbs defined" do
16
- @service.verb.should == :get
17
- end
18
-
19
- it "should have supported formats defined" do
20
- @service.formats.should == [:xml, :json]
21
- end
22
-
23
- it "should have params info" do
24
- @service.params.should be_an_instance_of(WeaselDiesel::Params)
25
- end
26
-
27
- it "should have direct access to the required params" do
28
- @service.required_rules.should == @service.params.list_required
29
- end
30
-
31
- it "should have direct access to the optional params" do
32
- @service.optional_rules.should == @service.params.list_optional
33
- end
34
-
35
- it "should have direct access to the nested params" do
36
- @service.nested_params.should == @service.params.namespaced_params
37
- end
38
-
39
- describe "#controller_dispatch" do
40
-
41
- class ProjectsController
42
- def initialize(app, service)
43
- @app = app
44
- @service = service.name
45
- end
46
-
47
- def send(action)
48
- [@app, @service, action]
49
- end
50
- end
51
-
52
- module Projects
53
- class TasksController < ProjectsController
54
- end
55
- end
56
-
57
- module Projects
58
- module Tasks
59
- class ItemsController < ProjectsController
60
- end
61
- end
62
- end
63
-
64
- before :all do
65
- @original_use_controller_dispatch = WeaselDiesel.use_controller_dispatch
66
- WeaselDiesel.use_controller_dispatch = true
67
- @original_services = WSList.all.dup
68
- WSList.all.clear
69
- end
70
-
71
- after :all do
72
- WeaselDiesel.use_controller_dispatch = @original_use_controller_dispatch
73
- WSList.all.replace @original_services
74
- end
75
-
76
- it "should be able to dispatch controller" do
77
- describe_service("projects.xml") { |s| }
78
- service = WSList["projects.xml"]
79
- service.controller_dispatch("application").
80
- should == ["application", "projects", "list"]
81
- end
82
-
83
- it "should be able to dispatch namespaced controller" do
84
- describe_service("project/:project_id/tasks.xml") do |service|
85
- service.controller_name = "Projects::TasksController"
86
- service.action = "list"
87
- end
88
-
89
- describe_service("project/:project_id/task/:task_id/items.xml") do |service|
90
- service.controller_name = "Projects::Tasks::ItemsController"
91
- service.action = "list"
92
- end
93
-
94
- service = WSList["project/:project_id/tasks.xml"]
95
- service.controller_dispatch("application").should == ["application", "project", "list"]
96
-
97
- service = WSList["project/:project_id/task/:task_id/items.xml"]
98
- service.controller_dispatch("application").should == ["application", "project", "list"]
99
- end
100
-
101
- it "should raise exception when controller class is not found" do
102
- describe_service("unknown.xml") do |service|
103
- service.controller_name = "UnknownController"
104
- service.action = "list"
105
- end
106
- service = WSList["unknown.xml"]
107
- lambda { service.controller_dispatch("application") }.
108
- should raise_error("The UnknownController class was not found")
109
- end
110
-
111
- end
112
-
113
- describe "With controller dispatch on" do
114
- before :all do
115
- @original_services = WSList.all.dup
116
- WSList.all.clear
117
- WeaselDiesel.use_controller_dispatch = true
118
- load File.expand_path('test_services.rb', File.dirname(__FILE__))
119
- @c_service = WSList.all.find{|s| s.url == 'services/test.xml'}
120
- @c_service.should_not be_nil
121
- end
122
- after :all do
123
- WeaselDiesel.use_controller_dispatch = false
124
- WSList.all.replace @original_services
125
- end
126
-
127
- it "should set the controller accordingly" do
128
- @c_service.controller_name.should_not be_nil
129
- @c_service.controller_name.should == 'ServicesController'
130
- service = WeaselDiesel.new("preferences.xml")
131
- service.name.should == 'preferences'
132
- ExtlibCopy.classify('preferences').should == 'Preferences'
133
- service.controller_name.should == 'PreferencesController'
134
- end
135
-
136
- it "should set the action accordingly" do
137
- @c_service.action.should_not be_nil
138
- @c_service.action.should == 'test'
139
- end
140
-
141
- it "should support restful routes based on the HTTP verb" do
142
- service = WSList.all.find{|s| s.url == "services.xml"}
143
- service.should_not be_nil
144
- service.http_verb.should == :put
145
- service.action.should_not be_nil
146
- service.controller_name.should == 'ServicesController'
147
- service.action.should == 'update'
148
- end
149
-
150
- it "should have a default action" do
151
- service = WeaselDiesel.new('spec_test.xml')
152
- service.action.should == 'list'
153
- end
154
-
155
- it "should route to show when an id is the last passed param" do
156
- service = WeaselDiesel.new("players/:id.xml")
157
- service.action.should == 'show'
158
- end
159
-
160
- it "should support some extra attributes" do
161
- service = WeaselDiesel.new("players/:id.xml")
162
- service.extra[:custom_name] = 'fooBar'
163
- service.extra[:custom_name].should == 'fooBar'
164
- end
165
-
166
- it "should respect the global controller pluralization flag" do
167
- WeaselDiesel.use_pluralized_controllers = true
168
- service = WeaselDiesel.new("player/:id.xml")
169
- service.controller_name.should == "PlayersController"
170
- service = WeaselDiesel.new("players/:id.xml")
171
- service.controller_name.should == "PlayersController"
172
- WeaselDiesel.use_pluralized_controllers = false
173
- service = WeaselDiesel.new("player/:id.xml")
174
- service.controller_name.should == "PlayerController"
175
- end
176
-
177
-
178
- it "should let overwrite the controller name and action after initialization" do
179
- describe_service "players/:id.xml" do |service|
180
- service.controller_name = "CustomController"
181
- service.action = "foo"
182
- end
183
- service = WSList.all.find{|s| s.url == "players/:id.xml"}
184
- service.controller_name.should == "CustomController"
185
- service.action.should == "foo"
186
- end
187
-
188
- end
189
-
190
-
191
- describe WeaselDiesel::Params do
192
-
193
- before(:all) do
194
- @sparams = @service.params
195
- end
196
-
197
- it "should have the possibility to have a space name" do
198
- @sparams.should respond_to(:space_name)
199
- service_params = WeaselDiesel::Params.new(:space_name => 'spec_test')
200
- service_params.space_name.should == 'spec_test'
201
- end
202
-
203
- it "should have a list of required param rules" do
204
- @sparams.list_required.should be_an_instance_of(Array)
205
- @sparams.list_required.length.should == 1
206
- end
207
-
208
- it "should have a list of optional param rules" do
209
- @sparams.list_optional.should be_an_instance_of(Array)
210
- @sparams.list_optional.length.should == 4
211
- end
212
-
213
- it "should have a list of namespaced param rules" do
214
- @sparams.namespaced_params.should be_an_instance_of(Array)
215
- @sparams.namespaced_params.length.should == 1
216
- @sparams.namespaced_params.first.space_name.should == :user
217
- end
218
-
219
- describe WeaselDiesel::Params::Rule do
220
- before :all do
221
- @rule = @sparams.list_required.first
222
- @rule.should_not be_nil
223
- end
224
-
225
- it "should have a name" do
226
- @rule.name.should == :framework
227
- end
228
-
229
- it "should have options" do
230
- @rule.options[:type].should == :string
231
- @rule.options[:in].should == WeaselDieselSpecOptions
232
- @rule.options[:null].should be_false
233
- end
234
- end
235
-
236
- end
237
-
238
- it "should have some documentation" do
239
- @service.doc.should be_an_instance_of(WeaselDiesel::Documentation)
240
- end
241
-
242
- describe WeaselDiesel::Documentation do
243
- before(:all) do
244
- @doc = @service.doc
245
- @doc.should_not be_nil
246
- end
247
-
248
- it "should have an overall description" do
249
- @doc.desc.strip.should == "This is a test service used to test the framework."
250
- end
251
-
252
- it "should have a list of params doc" do
253
- @doc.params_doc.should be_an_instance_of(Hash)
254
- @doc.params_doc.keys.sort.should == [:framework, :version]
255
- @doc.params_doc[:framework].should == "The test framework used, could be one of the two following: #{WeaselDieselSpecOptions.join(", ")}."
256
- end
257
-
258
- it "should allow to define namespaced params doc" do
259
- service = WSList.all.find{|s| s.url == "services.xml"}
260
- service.documentation do |doc|
261
- doc.namespace :preference do |ns|
262
- ns.param :id, "Ze id."
263
- end
264
- end
265
- service.doc.namespaced_params.should_not be_empty
266
- ns = service.doc.namespaced_params.find{|ns| ns.name == :preference}
267
- ns.should_not be_nil
268
- ns.params[:id].should == "Ze id."
269
- end
270
-
271
- it "should have an optional list of examples" do
272
- @doc.examples.should be_an_instance_of(Array)
273
- @doc.examples.first.should == <<-DOC
274
- The most common way to use this service looks like that:
275
- http://example.com/services/test.xml?framework=rspec&version=2.0.0
276
- DOC
277
- end
278
-
279
- it "should have the service response documented" do
280
- @doc.response.should_not be_nil
281
- end
282
-
283
- it "should have documentation for the response elements via the response itself" do
284
- @service.response.elements.first.should_not be_nil
285
- @service.response.elements.first.doc.should_not be_nil
286
- @service.response.elements.first.doc.name.should == "player_creation_ratings"
287
- end
288
-
289
- it "should have documentation for a response element attribute" do
290
- p @service.response.elements.first.doc.inspect
291
- @service.response.elements.first.doc.attributes.should_not be_empty
292
- @service.response.elements.first.doc.attributes[:id].should == "id doc"
293
- end
294
-
295
- it "should have documentation for a response element array" do
296
- element = @service.response.elements.first
297
- element.arrays.should_not be_empty
298
- element.arrays.first.name.should == :player_creation_rating
299
- element.arrays.first.type.should == "PlayerCreationRating"
300
- element.arrays.first.attributes.should_not be_empty
301
- end
302
-
303
- it "should have documentation for the attributes of an response element array" do
304
- element = @service.response.elements.first
305
- array = element.arrays.first
306
- attribute = array.attributes.find{|att| att.name == :comments }
307
- attribute.should_not be_nil
308
- attribute.name.should == :comments # just in case we change the way to find the attribute
309
- attribute.doc.should == "comments doc"
310
- end
311
-
312
- it "should emit html documention for elements" do
313
- @service.response.elements.first.to_html.should be_a(String)
314
- end
315
-
316
- end
317
- end