path-to 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +3 -0
- data/lib/path-to/described_routes.rb +107 -0
- data/lib/path-to.rb +1 -1
- data/test/path-to/fixtures/described_routes_test.json +1 -0
- metadata +4 -1
data/Manifest.txt
CHANGED
@@ -6,13 +6,16 @@ README.rdoc
|
|
6
6
|
Rakefile
|
7
7
|
lib/path-to.rb
|
8
8
|
lib/path-to/application.rb
|
9
|
+
lib/path-to/described_routes.rb
|
9
10
|
lib/path-to/http_client.rb
|
10
11
|
lib/path-to/path.rb
|
11
12
|
lib/path-to/with_params.rb
|
12
13
|
script/console
|
13
14
|
script/destroy
|
14
15
|
script/generate
|
16
|
+
test/path-to/fixtures/described_routes_test.json
|
15
17
|
test/path-to/test_application.rb
|
18
|
+
test/path-to/test_described_routes.rb
|
16
19
|
test/path-to/test_path.rb
|
17
20
|
test/path-to/test_with_params.rb
|
18
21
|
test/test_helper.rb
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require "path-to"
|
2
|
+
require "described_routes"
|
3
|
+
|
4
|
+
module PathTo
|
5
|
+
module DescribedRoutes
|
6
|
+
class TemplatedPath < WithParams
|
7
|
+
attr_reader :resource_template
|
8
|
+
|
9
|
+
def initialize(parent, service, params, resource_template)
|
10
|
+
super(parent, service, params)
|
11
|
+
@resource_template = resource_template
|
12
|
+
|
13
|
+
missing_params = resource_template.params - params.keys
|
14
|
+
unless missing_params.empty?
|
15
|
+
raise ArgumentError.new(
|
16
|
+
"Missing params #{missing_params.join(', ')} " +
|
17
|
+
"(template #{resource_template.name.inspect}," +
|
18
|
+
" path_template #{resource_template.path_template.inspect}," +
|
19
|
+
" params #{params.inspect})")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def uri_template
|
24
|
+
@uri_template ||= application.base + resource_template.path_template
|
25
|
+
end
|
26
|
+
|
27
|
+
def uri
|
28
|
+
@uri ||= begin
|
29
|
+
string_keyed_params = params.keys.inject({}){|hash, key| hash[key.to_s] = params[key]; hash}
|
30
|
+
Addressable::URI.expand_template(uri_template, string_keyed_params).to_s
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Finds (once) the application in the parent hierarchy.
|
36
|
+
#
|
37
|
+
def application
|
38
|
+
@application ||= parent.application if parent
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Application < WithParams
|
43
|
+
# An Array of DescribedRoutes::Resource objects
|
44
|
+
attr_reader :resources
|
45
|
+
|
46
|
+
# A Class (or at least something with a #new method) from which child objects will be created
|
47
|
+
attr_reader :default_type
|
48
|
+
|
49
|
+
# An HTTParty or similar
|
50
|
+
attr_reader :http_client
|
51
|
+
|
52
|
+
attr_reader :base
|
53
|
+
|
54
|
+
def initialize(resources, base, params = {}, default_type = TemplatedPath, http_client = HTTPClient)
|
55
|
+
@base, @resources, @default_type, @http_client = base, resources, default_type, http_client
|
56
|
+
super(nil, nil, params)
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Tries to respond to a missing method. We can do so if
|
61
|
+
#
|
62
|
+
# 1. we have a resource template matching the method name
|
63
|
+
# 2. #child_class_for returns a class or other factory object capable of creating a new child instance
|
64
|
+
#
|
65
|
+
# Otherwise we invoke super in the hope of avoiding any hard-to-debug behaviour!
|
66
|
+
#
|
67
|
+
def method_missing(method, *args)
|
68
|
+
resource_template = resource_templates_by_name[method.to_s]
|
69
|
+
if resource_template && (child_class = child_class_for(self, method, params, resource_template))
|
70
|
+
params = args.inject(Hash.new){|h, arg| h.merge(arg)}
|
71
|
+
child(child_class, method, params, resource_template)
|
72
|
+
else
|
73
|
+
super
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Determines whether this application &/or its child objects should respond to the given method, and if so returns a class from
|
79
|
+
# which a new child instance (typically Path or a subclass thereof) will be created. This implementation (easily overridden)
|
80
|
+
# returns #default_type if there is a URI template defined for the method.
|
81
|
+
#
|
82
|
+
# Parameters:
|
83
|
+
#
|
84
|
+
# [instance] This application or (presumably) one of its child objects
|
85
|
+
# [method] The method invoked on the instance that has (presumably) been intercepted by instance#method_missing
|
86
|
+
# [params] The instance's params
|
87
|
+
#
|
88
|
+
def child_class_for(instance, method, params, template)
|
89
|
+
default_type
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Returns a hash of all ResourceTemplates (the tree flattened) keyed by name
|
94
|
+
#
|
95
|
+
def resource_templates_by_name
|
96
|
+
@resource_templates_by_name ||= ::DescribedRoutes.all_by_name(resources)
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# Returns self. See TemplatedPath#application.
|
101
|
+
#
|
102
|
+
def application
|
103
|
+
self
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/path-to.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
[{"name":"root","path_template":"\/"},{"name":"admin_products","resource_templates":[{"name":"admin_product","resource_templates":[{"name":"edit_admin_product","options":["GET"],"path_template":"\/admin\/products\/{product_id}\/edit{-prefix|.|format}","rel":"edit","optional_params":["format"],"params":["product_id"]}],"options":["GET","PUT","DELETE"],"path_template":"\/admin\/products\/{product_id}{-prefix|.|format}","optional_params":["format"],"params":["product_id"]},{"name":"new_admin_product","options":["GET"],"path_template":"\/admin\/products\/new{-prefix|.|format}","optional_params":["format"]}],"options":["GET","POST"],"path_template":"\/admin\/products{-prefix|.|format}","optional_params":["format"]},{"name":"pages","resource_templates":[{"name":"page","resource_templates":[{"name":"edit_page","options":["GET"],"path_template":"\/pages\/{page_id}\/edit{-prefix|.|format}","rel":"edit","optional_params":["format"],"params":["page_id"]},{"name":"summary_page","options":["GET"],"path_template":"\/pages\/{page_id}\/summary{-prefix|.|format}","rel":"summary","optional_params":["format"],"params":["page_id"]},{"name":"toggle_visibility_page","options":["POST"],"path_template":"\/pages\/{page_id}\/toggle_visibility{-prefix|.|format}","rel":"toggle_visibility","optional_params":["format"],"params":["page_id"]}],"options":["GET","PUT","DELETE"],"path_template":"\/pages\/{page_id}{-prefix|.|format}","optional_params":["format"],"params":["page_id"]},{"name":"new_page","options":["GET"],"path_template":"\/pages\/new{-prefix|.|format}","optional_params":["format"]}],"options":["GET","POST"],"path_template":"\/pages{-prefix|.|format}","optional_params":["format"]},{"name":"users","resource_templates":[{"name":"user","resource_templates":[{"name":"user_articles","resource_templates":[{"name":"user_article","resource_templates":[{"name":"edit_user_article","options":["GET"],"path_template":"\/users\/{user_id}\/articles\/{article_id}\/edit{-prefix|.|format}","rel":"edit","optional_params":["format"],"params":["user_id","article_id"]}],"options":["GET","PUT","DELETE"],"path_template":"\/users\/{user_id}\/articles\/{article_id}{-prefix|.|format}","optional_params":["format"],"params":["user_id","article_id"]},{"name":"new_user_article","options":["GET"],"path_template":"\/users\/{user_id}\/articles\/new{-prefix|.|format}","optional_params":["format"],"params":["user_id"]},{"name":"recent_user_articles","options":["GET"],"path_template":"\/users\/{user_id}\/articles\/recent{-prefix|.|format}","rel":"recent","optional_params":["format"],"params":["user_id"]}],"options":["GET","POST"],"path_template":"\/users\/{user_id}\/articles{-prefix|.|format}","rel":"articles","optional_params":["format"],"params":["user_id"]},{"name":"edit_user","options":["GET"],"path_template":"\/users\/{user_id}\/edit{-prefix|.|format}","rel":"edit","optional_params":["format"],"params":["user_id"]},{"name":"user_profile","resource_templates":[{"name":"edit_user_profile","options":["GET"],"path_template":"\/users\/{user_id}\/profile\/edit{-prefix|.|format}","rel":"edit","optional_params":["format"],"params":["user_id"]},{"name":"new_user_profile","options":["GET"],"path_template":"\/users\/{user_id}\/profile\/new{-prefix|.|format}","rel":"new","optional_params":["format"],"params":["user_id"]}],"options":["GET","PUT","DELETE","POST"],"path_template":"\/users\/{user_id}\/profile{-prefix|.|format}","rel":"profile","optional_params":["format"],"params":["user_id"]}],"options":["GET","PUT","DELETE"],"path_template":"\/users\/{user_id}{-prefix|.|format}","optional_params":["format"],"params":["user_id"]},{"name":"new_user","options":["GET"],"path_template":"\/users\/new{-prefix|.|format}","optional_params":["format"]}],"options":["GET","POST"],"path_template":"\/users{-prefix|.|format}","optional_params":["format"]}]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: path-to
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Burrows (asplake)
|
@@ -73,13 +73,16 @@ files:
|
|
73
73
|
- Rakefile
|
74
74
|
- lib/path-to.rb
|
75
75
|
- lib/path-to/application.rb
|
76
|
+
- lib/path-to/described_routes.rb
|
76
77
|
- lib/path-to/http_client.rb
|
77
78
|
- lib/path-to/path.rb
|
78
79
|
- lib/path-to/with_params.rb
|
79
80
|
- script/console
|
80
81
|
- script/destroy
|
81
82
|
- script/generate
|
83
|
+
- test/path-to/fixtures/described_routes_test.json
|
82
84
|
- test/path-to/test_application.rb
|
85
|
+
- test/path-to/test_described_routes.rb
|
83
86
|
- test/path-to/test_path.rb
|
84
87
|
- test/path-to/test_with_params.rb
|
85
88
|
- test/test_helper.rb
|