wsdsl 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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