wsdsl 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
data/lib/response.rb CHANGED
@@ -9,22 +9,30 @@ class WSDSL
9
9
  # @api public
10
10
  attr_reader :elements
11
11
 
12
+ # The list of all the arays inside the response
13
+ #
14
+ # @return [Array<WSDSL::Response::Array>]
15
+ attr_reader :arrays
16
+
12
17
  def initialize
13
18
  @elements = []
19
+ @arrays = []
14
20
  end
15
21
 
16
- alias :nodes :elements
22
+ def nodes
23
+ elements + arrays
24
+ end
17
25
 
18
- # Shortcut to automatically create a typed node.
19
- # Very useful when describing a JSON response.
26
+ # Shortcut to automatically create a node of array type.
27
+ # Useful when describing a JSON response.
20
28
  #
21
29
  # @param [String, Symbol] name the name of the element.
22
30
  # @param [Hash] opts the element options.
23
- # @see Element#array
24
- def array(name, opts={})
25
- el = element(opts.merge(:name => name))
26
- yield el if block_given?
27
- el
31
+ # @see Vector#initialize
32
+ def array(name, type=nil)
33
+ vector = Vector.new(name, type)
34
+ yield(vector) if block_given?
35
+ @arrays << vector
28
36
  end
29
37
 
30
38
  # Defines a new element and yields the content of an optional block
@@ -170,27 +178,27 @@ class WSDSL
170
178
 
171
179
  # Defines an array aka vector of elements.
172
180
  #
173
- # @param [Hash] opts A hash representing the array information, usually a name and a type.
174
- # @option opts [String, Symbol] :name The name of the defined array
175
- # @option opts [String, Symbol] :type The class name of the element inside the array
181
+ # @param [String, Symbol] name The name of the array element.
182
+ # @param [String, Symbol] type Optional type information, useful to store the represented
183
+ # object types for instance.
176
184
  #
177
185
  # @param [Proc] &block
178
186
  # A block to execute against the newly created array.
179
187
  #
180
188
  # @example Defining an element array called 'player_creation_rating'
181
- # element.array :name => 'player_creation_rating', :type => 'PlayerCreationRating' do |a|
189
+ # element.array 'player_creation_rating', 'PlayerCreationRating' do |a|
182
190
  # a.attribute :comments => :string
183
191
  # a.attribute :player_id => :integer
184
192
  # a.attribute :rating => :integer
185
193
  # a.attribute :username => :string
186
194
  # end
187
195
  # @yield [Vector] the newly created array/vector instance
188
- # @see Vector#initialize
196
+ # @see Element#initialize
189
197
  #
190
- # @return [Array<WSDSL::Response::Element::Vector>]
198
+ # @return [Array<WSDSL::Response::Vector>]
191
199
  # @api public
192
- def array(opts)
193
- vector = Vector.new(opts)
200
+ def array(name, type=nil)
201
+ vector = Vector.new(name, type)
194
202
  yield(vector) if block_given?
195
203
  @vectors << vector
196
204
  end
@@ -198,8 +206,8 @@ class WSDSL
198
206
  # Returns the arrays/vectors contained in the response.
199
207
  # This is an alias to access @vectors
200
208
  # @see @vectors
201
- #
202
- # @return [Array<WSDSL::Response::Element::Vector>]
209
+ #
210
+ # @return [Array<WSDSL::Response::Vector>]
203
211
  # @api public
204
212
  def arrays
205
213
  @vectors
@@ -220,9 +228,9 @@ class WSDSL
220
228
  #
221
229
  # @return [Array<WSDSL::Response::Element>]
222
230
  # @api public
223
- def element(opts={}, &block)
231
+ def element(opts={})
224
232
  el = Element.new(opts[:name], opts[:type])
225
- block.call(el) if block_given?
233
+ yield(el) if block_given?
226
234
  @elements ||= []
227
235
  @elements << el
228
236
  el
@@ -300,7 +308,8 @@ class WSDSL
300
308
  if name
301
309
  meta_attribute({name => type}.merge(opts))
302
310
  else
303
- meta_attributes.find{|att| att.type == type}
311
+ # with a fallback to the @type ivar
312
+ meta_attributes.find{|att| att.type == type} || @type
304
313
  end
305
314
  end
306
315
 
@@ -359,79 +368,12 @@ class WSDSL
359
368
  class MetaAttribute < Attribute
360
369
  end
361
370
 
362
- # Array of objects inside an element
363
- # @api public
364
- class Vector
365
-
366
- # @api public
367
- attr_reader :name
368
-
369
- # @api public
370
- attr_reader :obj_type
371
-
372
- # @api public
373
- attr_accessor :attributes
374
-
375
- # A vector can have nested elements.
376
- # This value is nil by default.
377
- #
378
- # @return [NilClass, Array<WSDSL::Response::Element>]
379
- # @see #element
380
- # @api public
381
- attr_reader :elements
382
-
383
- # Initialize a Vector object, think about it as an array of objects of a certain type.
384
- # It is recommended to passthe type argument as a string so the constant doesn't need to be resolved.
385
- # In other words, if you say you are creating a vector of Foo objects, the Foo class doesn't need to be
386
- # loaded yet. That makes service parsing easier and avoids dependency challenges.
387
- #
388
- # @param [Hash] opts A hash representing the vector information, usually a name and a type, both as strings
389
- # @option opts [String] :name The array's name
390
- # @option opts [Symbol, String] :type The type of the objects inside the array
391
- #
392
- # @example
393
- # Vector.new(:name => 'player_creation_rating', :type => 'PlayerCreationRating')
394
- #
395
- # @api public
396
- def initialize(opts)
397
- @name = opts[:name]
398
- @obj_type = opts[:type]
399
- @attributes = []
400
- end
401
-
402
- # Sets a vector attribute
403
- #
404
- # @param (see Attribute#initialize)
405
- # @api public
406
- def attribute(opts)
407
- raise ArgumentError unless opts.is_a?(Hash)
408
- @attributes << Attribute.new(opts)
409
- end
410
-
411
- # Defines a new element and yields the content of an optional block
412
- # Each new element is then stored in the elements array.
413
- #
414
- # @param [Hash] opts Options used to define the element
415
- # @option opts [String, Symbol] :name The element name
416
- # @option opts [String, Symbol] :type The optional type
417
- #
418
- # @yield [WSDSL::Response::Element] the newly created element
419
- # @example create an element called 'my_stats'.
420
- # service.response do |response|
421
- # response.element(:name => "my_stats", :type => 'Leaderboard')
422
- # end
423
- #
424
- # @return [Array<WSDSL::Response::Element>]
425
- # @api public
426
- def element(opts={})
427
- el = Element.new(opts[:name], opts[:type])
428
- yield(el) if block_given?
429
- @elements ||= []
430
- @elements << el
431
- end
432
-
433
- end # of Vector
434
371
  end # of Element
435
372
 
373
+ # Array of objects
374
+ # @api public
375
+ class Vector < Element
376
+ end # of Vector
377
+
436
378
  end # of Response
437
379
  end
data/lib/ws_list.rb CHANGED
@@ -34,7 +34,7 @@ module WSList
34
34
  # @return [WSDSL] The found service.
35
35
  #
36
36
  # @api public
37
- def self.named(name)
37
+ def named(name)
38
38
  service = all.find{|service| service.name == name}
39
39
  if service.nil?
40
40
  raise UnknownService, "Service named #{name} isn't available"
@@ -42,6 +42,16 @@ module WSList
42
42
  service
43
43
  end
44
44
  end
45
+
46
+ # Returns a service based on its url
47
+ #
48
+ # @param [String] url The url of the service you are looking for.
49
+ # @return [Nil, WSDSL] The found service.
50
+ #
51
+ # @api public
52
+ def [](url)
53
+ @list.find{|service| service.url == url}
54
+ end
45
55
 
46
56
 
47
57
  end
data/lib/wsdsl.rb CHANGED
@@ -25,9 +25,11 @@ require File.expand_path('ws_list', File.dirname(__FILE__))
25
25
  # | |_ Namespaced params (array containing nested optional and required rules)
26
26
  # |__ response (instance of WSDSL::Response)
27
27
  # | |_ elements (array of elements with each element having a name, type, attributes and vectors
28
- # | | |_ attributes (array of WSDSL::Response::Attribute, each attribute has a name, a type, a doc and some extra options)
29
- # | |_ vectors (array of WSDSL::Response::Vector), each vector has a name, obj_type, & an array of attributes
30
- # | |_ attributes (array of WSDSL::Response::Attribute, each attribute has a name, a type and a doc)
28
+ # | | | |_ attributes (array of WSDSL::Response::Attribute, each attribute has a name, a type, a doc and some extra options)
29
+ # | | |_ vectors (array of WSDSL::Response::Vector), each vector has a name, obj_type, & an array of attributes
30
+ # | | |_ attributes (array of WSDSL::Response::Attribute, each attribute has a name, a type and a doc)
31
+ # | |_ arrays (like elements but represent an array of objects)
32
+ # |
31
33
  # |__ doc (instance of WSDSL::Documentation)
32
34
  # | | | |_ overal) description
33
35
  # | | |_ examples (array of examples as strings)
@@ -123,14 +125,16 @@ class WSDSL
123
125
  @defined_params = WSDSL::Params.new
124
126
  @doc = WSDSL::Documentation.new
125
127
  @response = WSDSL::Response.new
126
- @name = extract_service_root_name(url)
127
- if WSDSL.use_pluralized_controllers
128
- base_name = ExtlibCopy::Inflection.pluralize(ExtlibCopy::Inflection.singular(name))
129
- @controller_name = "#{ExtlibCopy.classify(base_name)}Controller"
130
- else
131
- @controller_name = "#{ExtlibCopy.classify(name)}Controller"
128
+ if WSDSL.use_controller_dispatch
129
+ @name = extract_service_root_name(url)
130
+ if WSDSL.use_pluralized_controllers
131
+ base_name = ExtlibCopy::Inflection.pluralize(ExtlibCopy::Inflection.singular(name))
132
+ @controller_name = "#{ExtlibCopy.classify(base_name)}Controller"
133
+ else
134
+ @controller_name = "#{ExtlibCopy.classify(name)}Controller"
135
+ end
136
+ @action = extract_service_action(url)
132
137
  end
133
- @action = extract_service_action(url)
134
138
  @verb = :get
135
139
  @formats = []
136
140
  @version = '0.1'
@@ -159,6 +163,27 @@ class WSDSL
159
163
  @pluralized_controllers = val
160
164
  end
161
165
 
166
+ # Checks the WSDSL flag to see if controller are used to dispatch requests.
167
+ # This allows apps to use this DSL but route to controller/actions.
168
+ #
169
+ # @return [Boolean] The updated value, default to false
170
+ # @api public
171
+ # @since 0.3.0
172
+ def self.use_controller_dispatch
173
+ @controller_dispatch
174
+ end
175
+
176
+ # Sets a WSDSL global flag so the controller settings can be generated
177
+ # Setting this flag will automatically set the controller/action names.
178
+ # @param [Boolean] True if the controllers are pluralized, False otherwise.
179
+ #
180
+ # @return [Boolean] The updated value
181
+ # @api public
182
+ # @since 0.1.1
183
+ def self.use_controller_dispatch=(val)
184
+ @controller_dispatch = val
185
+ end
186
+
162
187
  # Offers a way to dispatch the service at runtime
163
188
  # Basically, it dispatches the request to the defined controller/action
164
189
  # The full request cycle looks like that:
@@ -196,7 +221,14 @@ class WSDSL
196
221
  end
197
222
  end
198
223
  alias :param :params
199
-
224
+
225
+ # Returns true if the DSL defined any params
226
+ #
227
+ # @return [Boolean]
228
+ def params?
229
+ !(required_rules.empty? && optional_rules.empty? && nested_params.empty?)
230
+ end
231
+
200
232
  # Returns an array of required param rules
201
233
  #
202
234
  # @return [Array<WSDSL::Params::Rule>] Only the required param rules
@@ -32,7 +32,7 @@ describe_service "services/test.xml" do |service|
32
32
  e.attribute :is_accepted => :boolean, :doc => "is accepted doc"
33
33
  e.attribute :name => :string, :doc => "name doc"
34
34
 
35
- e.array :name => 'player_creation_rating', :type => 'PlayerCreationRating' do |a|
35
+ e.array :player_creation_rating, 'PlayerCreationRating' do |a|
36
36
  a.attribute :comments => :string, :doc => "comments doc"
37
37
  a.attribute :player_id => :integer, :doc => "player_id doc"
38
38
  a.attribute :rating => :integer, :doc => "rating doc"
data/spec/wsdsl_spec.rb CHANGED
@@ -35,68 +35,84 @@ describe WSDSL do
35
35
  it "should have direct access to the nested params" do
36
36
  @service.nested_params.should == @service.params.namespaced_params
37
37
  end
38
-
39
- it "should set the controller accordingly" do
40
- @service.controller_name.should_not be_nil
41
- @service.controller_name.should == 'ServicesController'
42
- service = WSDSL.new("preferences.xml")
43
- service.name.should == 'preferences'
44
- ExtlibCopy.classify('preferences').should == 'Preferences'
45
- service.controller_name.should == 'PreferencesController'
46
- end
47
-
48
- it "should set the action accordingly" do
49
- @service.action.should_not be_nil
50
- @service.action.should == 'test'
51
- end
52
-
53
- it "should support restful routes based on the HTTP verb" do
54
- service = WSList.all.find{|s| s.url == "services.xml"}
55
- service.should_not be_nil
56
- service.http_verb.should == :put
57
- service.action.should_not be_nil
58
- service.controller_name.should == 'ServicesController'
59
- service.action.should == 'update'
60
- end
38
+
39
+ describe "With controller dispatch on" do
40
+ before :all do
41
+ @original_services = WSList.all.dup
42
+ WSList.all.clear
43
+ WSDSL.use_controller_dispatch = true
44
+ load File.expand_path('test_services.rb', File.dirname(__FILE__))
45
+ @c_service = WSList.all.find{|s| s.url == 'services/test.xml'}
46
+ @c_service.should_not be_nil
47
+ end
48
+ after :all do
49
+ WSDSL.use_controller_dispatch = false
50
+ WSList.all.replace @original_services
51
+ end
61
52
 
62
- it "should have a default action" do
63
- service = WSDSL.new('spec_test.xml')
64
- service.action.should == 'list'
65
- end
53
+ it "should set the controller accordingly" do
54
+ @c_service.controller_name.should_not be_nil
55
+ @c_service.controller_name.should == 'ServicesController'
56
+ service = WSDSL.new("preferences.xml")
57
+ service.name.should == 'preferences'
58
+ ExtlibCopy.classify('preferences').should == 'Preferences'
59
+ service.controller_name.should == 'PreferencesController'
60
+ end
61
+
62
+ it "should set the action accordingly" do
63
+ @c_service.action.should_not be_nil
64
+ @c_service.action.should == 'test'
65
+ end
66
+
67
+ it "should support restful routes based on the HTTP verb" do
68
+ service = WSList.all.find{|s| s.url == "services.xml"}
69
+ service.should_not be_nil
70
+ service.http_verb.should == :put
71
+ service.action.should_not be_nil
72
+ service.controller_name.should == 'ServicesController'
73
+ service.action.should == 'update'
74
+ end
66
75
 
67
- it "should route to show when an id is the last passed param" do
68
- service = WSDSL.new("players/:id.xml")
69
- service.action.should == 'show'
70
- end
76
+ it "should have a default action" do
77
+ service = WSDSL.new('spec_test.xml')
78
+ service.action.should == 'list'
79
+ end
71
80
 
72
- it "should support some extra attributes" do
73
- service = WSDSL.new("players/:id.xml")
74
- service.extra[:custom_name] = 'fooBar'
75
- service.extra[:custom_name].should == 'fooBar'
76
- end
81
+ it "should route to show when an id is the last passed param" do
82
+ service = WSDSL.new("players/:id.xml")
83
+ service.action.should == 'show'
84
+ end
77
85
 
78
- it "should respect the global controller pluralization flag" do
79
- WSDSL.use_pluralized_controllers = true
80
- service = WSDSL.new("player/:id.xml")
81
- service.controller_name.should == "PlayersController"
82
- service = WSDSL.new("players/:id.xml")
83
- service.controller_name.should == "PlayersController"
84
- WSDSL.use_pluralized_controllers = false
85
- service = WSDSL.new("player/:id.xml")
86
- service.controller_name.should == "PlayerController"
87
- end
86
+ it "should support some extra attributes" do
87
+ service = WSDSL.new("players/:id.xml")
88
+ service.extra[:custom_name] = 'fooBar'
89
+ service.extra[:custom_name].should == 'fooBar'
90
+ end
91
+
92
+ it "should respect the global controller pluralization flag" do
93
+ WSDSL.use_pluralized_controllers = true
94
+ service = WSDSL.new("player/:id.xml")
95
+ service.controller_name.should == "PlayersController"
96
+ service = WSDSL.new("players/:id.xml")
97
+ service.controller_name.should == "PlayersController"
98
+ WSDSL.use_pluralized_controllers = false
99
+ service = WSDSL.new("player/:id.xml")
100
+ service.controller_name.should == "PlayerController"
101
+ end
88
102
 
89
103
 
90
- it "should let overwrite the controller name and action after initialization" do
91
- describe_service "players/:id.xml" do |service|
92
- service.controller_name = "CustomController"
93
- service.action = "foo"
94
- end
95
- service = WSList.all.find{|s| s.url == "players/:id.xml"}
96
- service.controller_name.should == "CustomController"
97
- service.action.should == "foo"
104
+ it "should let overwrite the controller name and action after initialization" do
105
+ describe_service "players/:id.xml" do |service|
106
+ service.controller_name = "CustomController"
107
+ service.action = "foo"
108
+ end
109
+ service = WSList.all.find{|s| s.url == "players/:id.xml"}
110
+ service.controller_name.should == "CustomController"
111
+ service.action.should == "foo"
112
+ end
98
113
  end
99
114
 
115
+
100
116
  describe WSDSL::Params do
101
117
 
102
118
  before(:all) do
@@ -203,8 +219,8 @@ The most common way to use this service looks like that:
203
219
  it "should have documentation for a response element array" do
204
220
  element = @service.response.elements.first
205
221
  element.arrays.should_not be_empty
206
- element.arrays.first.name.should == "player_creation_rating"
207
- element.arrays.first.obj_type.should == "PlayerCreationRating"
222
+ element.arrays.first.name.should == :player_creation_rating
223
+ element.arrays.first.type.should == "PlayerCreationRating"
208
224
  element.arrays.first.attributes.should_not be_empty
209
225
  end
210
226
 
data/wsdsl.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{wsdsl}
8
- s.version = "0.2.1"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = [%q{Matt Aimonetti}]
12
- s.date = %q{2011-09-02}
12
+ s.date = %q{2011-09-09}
13
13
  s.description = %q{A Ruby DSL describing Web Services without implementation details.}
14
14
  s.email = %q{mattaimonetti@gmail.com}
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wsdsl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-02 00:00:00.000000000Z
12
+ date: 2011-09-09 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description: A Ruby DSL describing Web Services without implementation details.
15
15
  email: mattaimonetti@gmail.com