path-to 0.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/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2009-04-04
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ path-to, Copyright (c) 2009 Mike Burrows
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,17 @@
1
+ History.txt
2
+ LICENSE
3
+ Manifest.txt
4
+ PostInstall.txt
5
+ README.rdoc
6
+ Rakefile
7
+ lib/path-to.rb
8
+ lib/path-to/application.rb
9
+ lib/path-to/path.rb
10
+ lib/path-to/with_params.rb
11
+ script/console
12
+ script/destroy
13
+ script/generate
14
+ test/path-to/test_application.rb
15
+ test/path-to/test_path.rb
16
+ test/path-to/test_with_params.rb
17
+ test/test_helper.rb
data/PostInstall.txt ADDED
@@ -0,0 +1,2 @@
1
+
2
+ For more information on path-to, see http://path-to.rubyforge.org
data/README.rdoc ADDED
@@ -0,0 +1,52 @@
1
+ = path-to README
2
+
3
+ == Description
4
+
5
+ path-to allows web applications to be modelled via URI templates and then accessed through an application-specific Ruby API. It is
6
+ designed to be extended easily to support discovery mechanisms; support for XRD may be added at some future date.
7
+
8
+ == Synopsis
9
+
10
+ Here's a simple example that illustrates access to a CMS:
11
+
12
+ require "path-to"
13
+
14
+ class Users < PathTo::Path ; end
15
+ class Articles < PathTo::Path ; end
16
+
17
+ app = Application.new(
18
+ :users => "http://example.com/users/{user}",
19
+ :articles => "http://example.com/users/{user}/articles/{slug}") do |app|
20
+ def app.child_class_for(instance, method, params)
21
+ {
22
+ :users => Users,
23
+ :articles => Articles
24
+ }[method]
25
+ end
26
+ end #=> Application
27
+
28
+ Note that the Users and Articles classes and the overridden #child_class_for method above can be done away with (reducing the above
29
+ code to just four lines) if there is no need to define any class-specific behaviour.
30
+
31
+ Having defined URI template and class mappings for keys :users and :articles mapping to URI templates, calls to app.users and
32
+ app.articles cause objects of the appropriate class to be generated. These in turn support chaining and the collection of request
33
+ params, like this:
34
+
35
+ app.users #=> http://example.com/users/ <Users>
36
+ app.users(:user => "dojo") #=> http://example.com/users/dojo <Users>
37
+ app.users[:user => "dojo"] #=> http://example.com/users/dojo <Users>
38
+ app.articles(:user => "dojo", :slug => "my-article") #=> http://example.com/users/dojo/articles/my-article <Articles>
39
+ app.users[:user => "dojo"].articles[:slug => "my-article"] #=> http://example.com/users/dojo/articles/my-article <Articles>
40
+
41
+ With a little more work (overriding Users#[] and Articles#[] - as described in the documentation for the Path class), the last example
42
+ becomes simply:
43
+
44
+ app.users["dojo"].articles["my-article"] #=> http://example.com/users/dojo/articles/my-article <Articles>
45
+
46
+ HTTP support comes courtesy of HTTParty (the Path class includes it). To GET an article in the above example, just invoke the get method on the path object:
47
+
48
+ app.users["dojo"].articles["my-article"].get #=> "<html>...</html>"
49
+
50
+ == Installation, Dependencies, Testing
51
+
52
+ TODO
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ $:.push File.dirname(__FILE__) + '/lib'
3
+ require 'path-to'
4
+
5
+ # undefined method `empty?' for nil:NilClass
6
+ # /Library/Ruby/Site/1.8/rubygems/specification.rb:886:in `validate'
7
+ class NilClass
8
+ def empty?
9
+ true
10
+ end
11
+ end
12
+
13
+ # Generate all the Rake tasks
14
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
15
+ $hoe = Hoe.new('path-to', PathTo::VERSION) do |p|
16
+ p.developer('Mike Burrows (asplake)', 'mjb@asplake.co.uk')
17
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
18
+ p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
19
+ p.rubyforge_name = p.name # TODO this is default value
20
+ p.extra_deps = [
21
+ ['httparty','>= 0.4.2'],
22
+ ['addressable','>= 2.0.2'],
23
+ ]
24
+ p.extra_dev_deps = [
25
+ ['newgem', ">= #{::Newgem::VERSION}"]
26
+ ]
27
+
28
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
29
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
30
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
31
+ p.rsync_args = '-av --delete --ignore-errors'
32
+ end
33
+
34
+ require 'newgem/tasks' # load /tasks/*.rake
35
+ Dir['tasks/**/*.rake'].each { |t| load t }
36
+
37
+ # TODO - want other tests/tasks run by default? Add them to the list
38
+ # task :default => [:spec, :features]
@@ -0,0 +1,121 @@
1
+ require "path-to/path"
2
+ require "path-to/http_client"
3
+ require "addressable/uri"
4
+
5
+ module PathTo
6
+ #
7
+ # Provides a Ruby client API interface to a web application. Method calls on this Application object generate Path objects that
8
+ # map (via URI templates held here on the Application) to the web application's URIs.
9
+ #
10
+ # Example:
11
+ #
12
+ # app = PathTo::Application.new(
13
+ # :users => "http://example.com/users/{user}",
14
+ # :articles => "http://example.com/users/{user}/articles/{slug}") do |app|
15
+ # def app.child_class_for(instance, method, params)
16
+ # {
17
+ # :users => Users,
18
+ # :articles => Articles
19
+ # }[method]
20
+ # end
21
+ # end #=> PathTo::Application
22
+ #
23
+ # app.users #=> http://example.com/users/ <Users>
24
+ # app.users(:user => "dojo") #=> http://example.com/users/dojo <Users>
25
+ # app.articles(:user => "dojo", :slug => "my-article") #=> http://example.com/users/dojo/articles/my-article <Articles>
26
+ # app.users[:user => "dojo"].articles[:slug => "my-article"] #=> http://example.com/users/dojo/articles/my-article <Articles>
27
+ #
28
+ class Application < WithParams
29
+ # A Hash that maps method keys (Symbol) to URI templates (String)
30
+ attr_reader :templates
31
+
32
+ # A Class (or at least something with a #new method) from which child objects will be created
33
+ attr_reader :default_type
34
+
35
+ # An HTTParty or similar
36
+ attr_reader :http_client
37
+
38
+ #
39
+ # Initializes an Application. Parameters:
40
+ #
41
+ # [templates] Initial value for the templates attribute, defaults to {}
42
+ # [default_type] Initial value for the default_type attribute, defaults to Path
43
+ # [http_client] An object through which http calls are invoked. See HTTPClient and Path#http_client.
44
+ #
45
+ # Simple example:
46
+ #
47
+ # # Model an application with just a "users" collection that generates Path objects
48
+ # simple_app = PathTo::Application.new(:users => "http://example.com/users/{user}")
49
+ #
50
+ # The constructor yields self, utilised in this example:
51
+ #
52
+ # # Model an application with "users" and "articles" collections, represented here on the client side by Users and Articles objects
53
+ # bigger_app = PathTo::Application.new(
54
+ # :users => "http://example.com/users/{user}",
55
+ # :articles => "http://example.com/users/{user}/articles/{slug}") do |app|
56
+ # def app.child_class_for(instance, method, params)
57
+ # {
58
+ # :users => Users,
59
+ # :articles => Articles
60
+ # }[method]
61
+ # end
62
+ # end
63
+ #
64
+ def initialize(templates = {}, default_type = Path, http_client = HTTPClient)
65
+ super() # with default args
66
+ @templates, @default_type, @http_client = templates, default_type, http_client
67
+ yield self if block_given?
68
+ end
69
+
70
+ #
71
+ # Determines whether this application &/or its child objects should respond to the given method, and if so returns a class from
72
+ # which a new child instance (typically Path or a subclass thereof) will be created. This implementation (easily overridden)
73
+ # returns #default_type if there is a URI template defined for the method.
74
+ #
75
+ # Parameters:
76
+ #
77
+ # [instance] This application or (presumably) one of its child objects
78
+ # [method] The method invoked on the instance that has (presumably) been intercepted by instance#method_missing
79
+ # [params] The instance's params
80
+ #
81
+ def child_class_for(instance, method, params)
82
+ default_type if uri_template_for(method, params)
83
+ end
84
+
85
+ #
86
+ # Returns self. See Path#application.
87
+ #
88
+ def application
89
+ self
90
+ end
91
+
92
+ #
93
+ # Returns a URI template for the given method and params. Parameters:
94
+ #
95
+ # [method] The method invoked on the instance that has (presumably) been intercepted by instance#method_missing
96
+ # [params] The instance's params
97
+ #
98
+ # This implementation returns a value from the #templates Hash, keyed by method (params is ignored).
99
+ #
100
+ #--
101
+ # TODO Consider taking an instance as the first parameter, as #child_class_for does
102
+ #
103
+ def uri_template_for(method, params = {})
104
+ templates[method]
105
+ end
106
+
107
+ #
108
+ # Generates a URI, looking up a URI template (via #uri_template_for) and getting it formatted with the params.
109
+ #
110
+ #--
111
+ # TODO Consider taking an instance as the first parameter, as #child_class_for does
112
+ #
113
+ def uri_for(method, params = {})
114
+ # TODO it's a 1-line fix to Addressable to permit symbols (etc) as keys
115
+ if (t = uri_template_for(method, params))
116
+ string_keyed_params = params.keys.inject({}){|hash, key| hash[key.to_s] = params[key]; hash}
117
+ Addressable::URI.expand_template(t, string_keyed_params).to_s
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,71 @@
1
+ require "path-to/with_params"
2
+
3
+ module PathTo
4
+ #
5
+ # Builds on the chaining and param collection of WithParams to provide chainable references to URIs. Delegates the modelling of the
6
+ # web application to a parent (or ancestor) application object, so that this configuration is in one place (and perhaps the result of a
7
+ # discovery process).
8
+ #
9
+ class Path < WithParams
10
+
11
+ #
12
+ # Finds (once) the application in the parent hierarchy.
13
+ #
14
+ def application
15
+ @application ||= parent.application if parent
16
+ end
17
+
18
+ #
19
+ # Delegated to the application object (see Application#child_class_for for details).
20
+ #
21
+ def child_class_for(instance, service, args)
22
+ application.child_class_for(instance, service, args)
23
+ end
24
+
25
+ #
26
+ # Generate a URI for this object, using application.uri_for (see Application#uri_for for details).
27
+ #
28
+ def uri
29
+ application.uri_for(service, params)
30
+ end
31
+
32
+ #
33
+ # Returns the http_client of the application; override if necessary. See also HTTPClient.
34
+ #
35
+ def http_client
36
+ @http_client ||= application.http_client
37
+ end
38
+
39
+ #
40
+ # GET request on this object's URI
41
+ #
42
+ def get(*args)
43
+ http_client.get(uri, *args)
44
+ end
45
+
46
+ #
47
+ # PUT request on this object's URI
48
+ #
49
+ def put(*args)
50
+ http_client.put(uri, *args)
51
+ end
52
+
53
+ #
54
+ # POST request on this object's URI
55
+ #
56
+ def post(*args)
57
+ http_client.post(uri, *args)
58
+ end
59
+
60
+ #
61
+ # DELETE request on this object's URI
62
+ #
63
+ def delete(*args)
64
+ http_client.delete(uri, *args)
65
+ end
66
+
67
+ def inspect #:nodoc:
68
+ "#{uri} #<#{self.class.name}:#{"0x%x" % object_id} service=#{service.inspect}, params=#{params.inspect}>"
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,91 @@
1
+ module PathTo
2
+ #
3
+ # Chaining parameter collection. Example:
4
+ #
5
+ # p = WithParams.new.foo(:bar => "baz").fee[:fi => "fo"] #=> <WithParams>
6
+ # p.service #=> :fee
7
+ # p.params #=> {:bar => "baz", :fi => "fo"}
8
+ #
9
+ class WithParams
10
+ # Parent object, presumably of type WithParams or descendant
11
+ attr_reader :parent
12
+
13
+ # Service identifier, typically a method symbol intercepted in #method_missing
14
+ attr_reader :service
15
+
16
+ # Parameter hash
17
+ attr_reader :params
18
+
19
+ #
20
+ # Initialize a new WithParams object. Parameters:
21
+ #
22
+ # [parent] Value for the parent attribute
23
+ # [service] Value for the service attribute
24
+ # [params] Value for the params attribute
25
+ #
26
+ def initialize(parent = nil, service = nil, params = {})
27
+ @parent, @service, @params = parent, service, params
28
+ end
29
+
30
+ #
31
+ # Creates a child instance. Parameters:
32
+ #
33
+ # [child_class] The class of the new instance, calls #child_class_for to determine this if none supplied
34
+ # [service] Value for the new instance's service attribute, inherited from self (the parent) if none supplied
35
+ # [params] The new instance's params, will be merged with self's (the parent's) params
36
+ #
37
+ def child(child_class = nil, service = nil, params = {})
38
+ child_class ||= child_class_for(instance, service, params)
39
+ service ||= self.service
40
+ params = self.params.merge(params)
41
+ child_class.new(self, service, params)
42
+ end
43
+
44
+ #
45
+ # Creates a child instance with new params. Subclasses might override this to take values instead of hashes, as follows:
46
+ #
47
+ # def [](value)
48
+ # super(:key => value)
49
+ # end
50
+ #
51
+ def [](params = {})
52
+ child(self.class, self.service, params)
53
+ end
54
+
55
+ #
56
+ # Determines the class of a new child, given the parent instance, service and params
57
+ #
58
+ def child_class_for(instance, service, params)
59
+ self.class
60
+ end
61
+
62
+ #
63
+ # Determines whether we can respond to method (missing or otherwise). We can respond to a missing method if #child_class_for
64
+ # returns a class for a new child.
65
+ #
66
+ def respond_to?(method)
67
+ child_class_for(self, method, params) || super
68
+ end
69
+
70
+ #
71
+ # Tries to respond to a missing method. We can do so if
72
+ #
73
+ # 1. any args are hashes (merged to make a params hash), and
74
+ # 2. #child_class_for returns a class or other factory object capable of creating a new child instance
75
+ #
76
+ # In all other cases and in the case of error we invoke super in the hope of avoiding any hard-to-debug behaviour!
77
+ #
78
+ def method_missing(method, *args)
79
+ begin
80
+ params = args.inject(Hash.new){|h, arg| h.merge(arg)}
81
+ if (child_class = child_class_for(self, method, params))
82
+ child(child_class, method, params)
83
+ else
84
+ super
85
+ end
86
+ rescue
87
+ super
88
+ end
89
+ end
90
+ end
91
+ end
data/lib/path-to.rb ADDED
@@ -0,0 +1,6 @@
1
+ module PathTo
2
+ VERSION = "0.0.1"
3
+ end
4
+
5
+ require "path-to/application"
6
+ require "path-to/path"
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/path-to.rb'}"
9
+ puts "Loading path-to gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,74 @@
1
+ require "test/unit"
2
+ require "path-to/application"
3
+
4
+ module PathTo
5
+ class TestApplication < Test::Unit::TestCase
6
+ attr_reader :simple_app, :bigger_app
7
+
8
+ class Users < Path
9
+ def [](user)
10
+ super(:user => user)
11
+ end
12
+ end
13
+
14
+ class Articles < Path
15
+ def [](slug)
16
+ super(:slug => slug)
17
+ end
18
+ end
19
+
20
+ def setup
21
+ @simple_app = Application.new(:users => "http://example.com/users/{user}")
22
+
23
+ @bigger_app = Application.new(
24
+ :users => "http://example.com/users/{user}",
25
+ :articles => "http://example.com/users/{user}/articles/{slug}") do |app|
26
+ def app.child_class_for(instance, method, params)
27
+ {
28
+ :users => Users,
29
+ :articles => Articles
30
+ }[method]
31
+ end
32
+ end
33
+ end
34
+
35
+ def test_uri_for
36
+ assert_equal("http://example.com/users/", simple_app.uri_for(:users))
37
+ assert_equal("http://example.com/users/", simple_app.uri_for(:users, :what => "ever"))
38
+ assert_equal("http://example.com/users/dojo", simple_app.uri_for(:users, :user => "dojo"))
39
+ end
40
+
41
+ def test_child_uri
42
+ assert_equal("http://example.com/users/", simple_app.users.uri)
43
+ assert_equal("http://example.com/users/", simple_app.users(:what => "ever").uri)
44
+ assert_equal("http://example.com/users/", simple_app.users[:what => "ever"].uri)
45
+ assert_equal("http://example.com/users/dojo", simple_app.users(:user => "dojo").uri)
46
+ assert_equal("http://example.com/users/dojo", simple_app.users[:user => "dojo"].uri)
47
+ end
48
+
49
+ def test_no_child
50
+ assert_raises(NoMethodError) {simple_app.flooby}
51
+ end
52
+
53
+ def test_bigger_app
54
+ assert_kind_of(Users, bigger_app.users)
55
+ assert_kind_of(Users, bigger_app.users["dojo"])
56
+
57
+ assert_kind_of(Articles, bigger_app.articles)
58
+ assert_kind_of(Articles, bigger_app.articles["a-title"])
59
+
60
+ assert_equal("http://example.com/users/", bigger_app.users.uri)
61
+ assert_equal("http://example.com/users/dojo", bigger_app.users["dojo"].uri)
62
+
63
+ assert_equal("http://example.com/users//articles/", bigger_app.articles.uri)
64
+ assert_equal("http://example.com/users/dojo/articles/", bigger_app.articles(:user => "dojo").uri)
65
+ assert_equal("http://example.com/users//articles/a-title", bigger_app.articles["a-title"].uri)
66
+
67
+ assert_equal("http://example.com/users/dojo/articles/a-title", bigger_app.articles(:user => "dojo", :slug => "a-title").uri)
68
+ assert_equal("http://example.com/users/dojo/articles/a-title", bigger_app.users["dojo"].articles["a-title"].uri)
69
+
70
+ assert_raises(NoMethodError) {bigger_app.flooby}
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,48 @@
1
+ require "test/unit"
2
+ require "mocha"
3
+ require "path-to/path"
4
+ require "path-to/application"
5
+
6
+ module PathTo
7
+ class TestPath < Test::Unit::TestCase
8
+ attr_reader :app, :users
9
+
10
+ class TestPath < Path
11
+ end
12
+
13
+ def setup
14
+ @app = Application.new(
15
+ :users => "http://example.com/users/{user}",
16
+ :articles => "http://example.com/users/{user}/articles/{slug}")
17
+ @users = @app.users
18
+ end
19
+
20
+ def test_application
21
+ assert_equal(app, users.application)
22
+ assert_equal(app, users.articles.application)
23
+ end
24
+
25
+ def test_nil_application
26
+ assert_nil(Path.new.application)
27
+ assert_nil(Path.new[].application)
28
+ end
29
+
30
+ def test_child_class_for
31
+ params = {:slug => "a-title"}
32
+ app.expects(:child_class_for).with(users, :articles, params).returns(TestPath)
33
+ assert_equal(TestPath, users.child_class_for(users, :articles, params))
34
+ end
35
+
36
+ def test_uri
37
+ assert_equal("http://example.com/users/dojo", users[:user => "dojo"].uri)
38
+ end
39
+
40
+ def test_http_methods
41
+ request_options = {:body => {:bar => :baz}}
42
+ [:get, :put, :post, :delete].each do |method|
43
+ app.http_client.expects(method).with("http://example.com/users/", request_options)
44
+ users.send(method, request_options)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,60 @@
1
+ require "test/unit"
2
+ require "path-to/with_params"
3
+
4
+ module PathTo
5
+
6
+ class TestWithParams < Test::Unit::TestCase
7
+ attr_reader :root, :s1
8
+
9
+ class WithParamsSubclass1 < WithParams
10
+ def child_class_for(instance, service, params)
11
+ WithParamsSubclass2
12
+ end
13
+ end
14
+
15
+ class WithParamsSubclass2 < WithParams
16
+ end
17
+
18
+ def setup
19
+ @root = WithParams.new(nil, :root, :x => 1)
20
+ @s1 = WithParamsSubclass1.new
21
+ end
22
+
23
+ def test_service
24
+ assert_nil(WithParams.new.service)
25
+ assert_equal(:root, root.service)
26
+ assert_equal(:root, root.child.service)
27
+ assert_equal(:child, root.child(nil, :child).service)
28
+ assert_equal(:child, root.child(nil, :child).child.service)
29
+ end
30
+
31
+ def test_params
32
+ assert_equal({}, WithParams.new.params)
33
+ assert_equal({:x => 1}, root.params)
34
+ assert_equal({:x => 1}, root.child.params)
35
+ assert_equal({:x => 2}, root.child(nil, nil, {:x => 2}).params)
36
+ assert_equal({:x => 2}, root.child(nil, nil, {:x => 2}).child!.params)
37
+ assert_equal({:x => 1, :y => 2}, root.child(nil, nil, {:y => 2}).params)
38
+ end
39
+
40
+ def test_child_type
41
+ assert_kind_of(WithParams, root.child)
42
+ assert_kind_of(WithParamsSubclass2, s1.child)
43
+ assert_kind_of(WithParamsSubclass2, s1.child.child)
44
+ end
45
+
46
+ def test_ary_params
47
+ assert_equal(:root, root[].service)
48
+ assert_equal({:x => 1}, root[].params)
49
+ assert_equal({:x => 2}, root[:x => 2].params)
50
+ assert_equal({:x => 1, :y => 2}, root[:y => 2].params)
51
+ end
52
+
53
+ def test_method_missing
54
+ assert_kind_of(WithParams, root.flooby)
55
+ assert_equal(:flooby, root.flooby.service)
56
+ assert_equal({:x => 1}, root.flooby.params)
57
+ assert_equal({:x => 1, :y => 2}, root.flooby[:y => 2].params)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/path-to'
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: path-to
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Mike Burrows (asplake)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-18 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: httparty
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.4.2
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: addressable
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.2
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: newgem
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.3.0
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: hoe
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.8.0
54
+ version:
55
+ description: |-
56
+ path-to allows web applications to be modelled via URI templates and then accessed through an application-specific Ruby API. It is
57
+ designed to be extended easily to support discovery mechanisms; support for XRD may be added at some future date.
58
+ email:
59
+ - mjb@asplake.co.uk
60
+ executables: []
61
+
62
+ extensions: []
63
+
64
+ extra_rdoc_files:
65
+ - History.txt
66
+ - Manifest.txt
67
+ - PostInstall.txt
68
+ - README.rdoc
69
+ files:
70
+ - History.txt
71
+ - LICENSE
72
+ - Manifest.txt
73
+ - PostInstall.txt
74
+ - README.rdoc
75
+ - Rakefile
76
+ - lib/path-to.rb
77
+ - lib/path-to/application.rb
78
+ - lib/path-to/path.rb
79
+ - lib/path-to/with_params.rb
80
+ - script/console
81
+ - script/destroy
82
+ - script/generate
83
+ - test/path-to/test_application.rb
84
+ - test/path-to/test_path.rb
85
+ - test/path-to/test_with_params.rb
86
+ - test/test_helper.rb
87
+ has_rdoc: true
88
+ homepage:
89
+ licenses: []
90
+
91
+ post_install_message: PostInstall.txt
92
+ rdoc_options:
93
+ - --main
94
+ - README.rdoc
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: "0"
102
+ version:
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: "0"
108
+ version:
109
+ requirements: []
110
+
111
+ rubyforge_project: path-to
112
+ rubygems_version: 1.3.2
113
+ signing_key:
114
+ specification_version: 3
115
+ summary: path-to allows web applications to be modelled via URI templates and then accessed through an application-specific Ruby API
116
+ test_files:
117
+ - test/path-to/test_application.rb
118
+ - test/path-to/test_path.rb
119
+ - test/path-to/test_with_params.rb
120
+ - test/test_helper.rb