optionsful 0.3.2 → 0.4.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/.gitignore +2 -0
- data/README.textile +109 -0
- data/Rakefile +0 -1
- data/VERSION +1 -1
- data/lib/baurets/optionsful/config.rb +26 -31
- data/lib/baurets/optionsful/introspections.rb +86 -6
- data/lib/baurets/optionsful/server.rb +11 -6
- data/optionsful.gemspec +7 -8
- data/samples/optionsful.yml.sample +20 -0
- data/samples/optionsful_bug.yml +1 -0
- data/samples/optionsful_true.yml +20 -0
- data/spec/optionsful_config_spec.rb +49 -20
- data/spec/optionsful_server_spec.rb +40 -8
- data/spec/spec.opts +1 -1
- data/spec/spec_helper.rb +1 -0
- data/tasks/optionsful.rake +1 -1
- metadata +10 -11
- data/README.rdoc +0 -17
- data/config/optionsful.yml +0 -18
- data/spec/config/optionsful.yml +0 -18
- data/spec/config/optionsful_host_auto.yml +0 -18
- data/spec/config/optionsful_link_false.yml +0 -18
data/.gitignore
CHANGED
data/README.textile
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
h1. *O p t i o n s f u l*
|
2
|
+
|
3
|
+
Provide HTTP OPTIONS support for the Ruby on Rails framework.
|
4
|
+
|
5
|
+
* Note for the impatient: installation instructions below.
|
6
|
+
* Note for the dummies: change host names and paths properly.
|
7
|
+
* Note for the unfaithful: run @rake routes@ to validate the results.
|
8
|
+
|
9
|
+
** *WARNING*: If your application is Rails 2.x please go to "optionsful2":http://github.com/kayaman/optionsful2
|
10
|
+
|
11
|
+
h1. "-No! No! No! *-Show me the code!*"
|
12
|
+
|
13
|
+
h3. Retrieving an HTTP OPTIONS request via telnet:
|
14
|
+
|
15
|
+
<pre>
|
16
|
+
$ telnet localhost 3000
|
17
|
+
OPTIONS /posts HTTP/1.1
|
18
|
+
Host: http://localhost:3000
|
19
|
+
|
20
|
+
HTTP/1.1 204 No Content
|
21
|
+
Allow: GET, POST
|
22
|
+
Connection: close
|
23
|
+
Date: Thu, 22 Jul 2010 17:20:27 GMT
|
24
|
+
Link: "<http://localhost:3000/api/posts>; type=text/html; rel=help"
|
25
|
+
|
26
|
+
OPTIONS /posts/1 HTTP/1.1
|
27
|
+
Host: http://localhost:3000
|
28
|
+
|
29
|
+
HTTP/1.1 204 No Content
|
30
|
+
Allow: GET, PUT, DELETE
|
31
|
+
Connection: close
|
32
|
+
Date: Thu, 22 Jul 2010 18:14:24 GMT
|
33
|
+
Link: "<http://localhost:3000/api/posts/1/>; type=text/html; rel=help"
|
34
|
+
|
35
|
+
OPTIONS /posts/1/comments HTTP/1.1
|
36
|
+
Host: http://localhost:3000
|
37
|
+
|
38
|
+
HTTP/1.1 204 No Content
|
39
|
+
Allow: GET, POST
|
40
|
+
Connection: close
|
41
|
+
Date: Thu, 22 Jul 2010 18:12:43 GMT
|
42
|
+
Link: "<http://localhost:3000/api/posts/1/comments>; type=text/html; rel=help"
|
43
|
+
|
44
|
+
</pre>
|
45
|
+
~Note the empty line which is part of the HTTP protocol.~
|
46
|
+
|
47
|
+
h3. Well, I agree. Telnet is the geekest way.. ;-)
|
48
|
+
|
49
|
+
This is for testing purposes. You would like better to use an HTTP client software. I use "HTTP Client":http://ditchnet.org/httpclient/ on Mac OS X. And on real life, There is a lot of possible usage scenarios.
|
50
|
+
|
51
|
+
h1. INSTALLATION:
|
52
|
+
|
53
|
+
# Change directory to your Ruby on Rails web application,
|
54
|
+
# Add gem dependency to @config/application.rb@:
|
55
|
+
<pre>config.gem "optionsful"</pre>
|
56
|
+
# To install it, run @rake gems:install@ or:
|
57
|
+
<pre>$ gem install optionsful</pre>
|
58
|
+
# Enjoy! And give feedback! :)
|
59
|
+
|
60
|
+
h2. Setting up the @Link@ header
|
61
|
+
|
62
|
+
* To enable and setup the response's @Link@ header, install and edit the configuration file:
|
63
|
+
** run @rake optionsful:yml@
|
64
|
+
** edit the 'optionsful.yml' file at your application's 'config' folder.
|
65
|
+
* Example:
|
66
|
+
<pre>development:
|
67
|
+
link: true
|
68
|
+
host: auto
|
69
|
+
base_path: /api
|
70
|
+
propagate: true</pre>
|
71
|
+
|
72
|
+
h3. Possible values and effects: (the bold values are the default ones)
|
73
|
+
|
74
|
+
** @link@
|
75
|
+
*** *false*: Do not include any "Link" header in the response.
|
76
|
+
*** true: Do include it. Build the URI based on the 'host', 'base_path', and 'propagate' values, explained below.
|
77
|
+
|
78
|
+
** @host@
|
79
|
+
*** *auto*: Use the application's own address and port.
|
80
|
+
*** private.mycompany.com: point it to another location. For instance: www.baurets.net. (Do not include http://).
|
81
|
+
|
82
|
+
|
83
|
+
** @base_path@
|
84
|
+
*** the path to be appended to the host. Default is */api*.
|
85
|
+
*** to disable it, use @/@
|
86
|
+
*** Example: /my_company/my_project/resources/api
|
87
|
+
|
88
|
+
** @propagate@
|
89
|
+
*** false: Do not append the request's path info to the URI.
|
90
|
+
*** *true*: Do append it, as it is.
|
91
|
+
|
92
|
+
Generated Link example:
|
93
|
+
(link: true, host: auto)
|
94
|
+
<pre>Link: "<http://localhost:3000/api/posts/1/comments>; type=text/html; rel=help"</pre>
|
95
|
+
* *Note*: @Allow@ and @Link@ are expected headers on a response to an HTTP OPTIONS request.
|
96
|
+
|
97
|
+
h2. KNOWN ISSUES
|
98
|
+
* Rails route recognition still need some work
|
99
|
+
* Platform: *Rails 3.0.0.rc* !!!
|
100
|
+
|
101
|
+
h2. Get involved
|
102
|
+
* Mailing list: http://groups.google.com/group/optionsful
|
103
|
+
* Bug tracker : http://kayaman.lighthouseapp.com/projects/56438-optionsful/overview
|
104
|
+
|
105
|
+
h2. CONTRIBUTORS
|
106
|
+
* Me, myself and I, so far.
|
107
|
+
* You are welcome, do it. ;-)
|
108
|
+
|
109
|
+
Copyright (c) 2010 Marco Antonio Gonzalez Junior, kayaman@baurets.net, released under the MIT license.
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -1,54 +1,49 @@
|
|
1
|
+
|
2
|
+
require 'yaml'
|
3
|
+
|
1
4
|
module Baurets
|
2
5
|
module Optionsful
|
3
6
|
class Config
|
4
7
|
|
5
|
-
DEFAULT = { :link => false, :host => 'auto', :base_path => "/
|
8
|
+
DEFAULT = { :link => false, :host => 'auto', :base_path => "/api", :propagate => true }
|
6
9
|
|
7
10
|
def initialize(file = nil, options = {})
|
8
|
-
|
9
|
-
|
10
|
-
else
|
11
|
-
begin
|
12
|
-
if (defined? Rails && File.exist?(File.join(Rails.root, 'config', 'optionsful.yml')))
|
13
|
-
envs = YAML::load_file(File.join(Rails.root, 'config', 'optionsful.yml')).symbolize_keys
|
14
|
-
@config = envs[get_env].symbolize_keys
|
15
|
-
end
|
16
|
-
rescue
|
17
|
-
end
|
11
|
+
if file.nil?
|
12
|
+
file = File.join(Rails.root, 'config', 'optionsful.yml')
|
18
13
|
end
|
19
|
-
|
20
|
-
|
14
|
+
config = load_yaml(file, get_env)
|
15
|
+
config = DEFAULT if config.nil? or config.empty?
|
16
|
+
config.merge!(options) unless options.empty?
|
17
|
+
@config = config
|
18
|
+
config
|
21
19
|
end
|
22
20
|
|
23
21
|
def get_env
|
24
|
-
if
|
25
|
-
|
26
|
-
|
27
|
-
env = :production if Rails.env.production?
|
28
|
-
else
|
29
|
-
env = :development
|
30
|
-
end
|
31
|
-
env
|
22
|
+
:test if Rails.env.test?
|
23
|
+
:development if Rails.env.development?
|
24
|
+
:production if Rails.env.production?
|
32
25
|
end
|
33
26
|
|
34
|
-
def
|
27
|
+
def load_yaml(file, environment)
|
35
28
|
config = nil
|
36
|
-
require 'yaml'
|
37
29
|
if File.exist?(file)
|
38
30
|
begin
|
39
|
-
envs = YAML::load_file(file)
|
40
|
-
|
41
|
-
|
42
|
-
|
31
|
+
envs = YAML::load_file(file)
|
32
|
+
raise "Could not parse the YAML." if (envs.empty? or (not envs.kind_of?(Hash)))
|
33
|
+
envs = envs.symbolize_keys if envs
|
34
|
+
config = envs[environment].symbolize_keys if (envs && envs[environment])
|
35
|
+
rescue
|
36
|
+
config = nil
|
43
37
|
end
|
38
|
+
config
|
44
39
|
end
|
45
|
-
config
|
46
|
-
end
|
47
40
|
|
48
|
-
def method_missing(name, *args)
|
49
|
-
return @config[name.to_sym]
|
50
41
|
end
|
51
42
|
|
43
|
+
def method_missing(name, *args)
|
44
|
+
return @config[name.to_sym]
|
52
45
|
end
|
46
|
+
|
53
47
|
end
|
54
48
|
end
|
49
|
+
end
|
@@ -3,20 +3,100 @@ module Baurets
|
|
3
3
|
module Introspections
|
4
4
|
|
5
5
|
def self.do_the_matches(path_info)
|
6
|
-
routes =
|
7
|
-
routes.reject!{ |r| r.path == "/rails/info/properties" } # skip the route if it's internal info route
|
6
|
+
routes = gimme_routes
|
8
7
|
allow = ""
|
9
|
-
|
8
|
+
allow = match_verbs_tabajara(path_info)
|
9
|
+
if allow.empty?
|
10
|
+
allow = do_rails_recognition(path_info)
|
11
|
+
end
|
12
|
+
allow
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def self.do_rails_recognition(path_info)
|
18
|
+
allow = ""
|
19
|
+
gimme_routes.each do |route|
|
10
20
|
if path_info =~ route.conditions[:path_info]
|
11
21
|
if route.verb
|
12
22
|
allow += (route.verb.to_s.upcase + "|") unless allow.include?(route.verb.to_s.upcase)
|
13
23
|
else
|
14
|
-
# TODO
|
15
|
-
allow = "GET"
|
24
|
+
allow = "GET" # TODO Return 'ANY' doesn't sound ANY good to me.. ;p
|
16
25
|
end
|
17
26
|
end
|
18
27
|
end
|
19
|
-
allow = allow.split("|").join(", ")
|
28
|
+
allow = allow.split("|").join(", ")
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.match_verbs_tabajara(path_info)
|
32
|
+
routes_paths = build_static_paths
|
33
|
+
route_guess = guess_route(routes_paths,path_info)
|
34
|
+
allow = ""
|
35
|
+
routes_paths.each do |route|
|
36
|
+
if route.first == route_guess
|
37
|
+
allow += (route[1].to_s + "|") unless allow.include?(route[1].to_s.upcase)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
allow = allow.split("|").join(", ")
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.guess_route(routes, path)
|
44
|
+
guess = []
|
45
|
+
parts = prepare_request_path(path)
|
46
|
+
index = 0
|
47
|
+
parts.each do |part|
|
48
|
+
if is_part_static?(routes, index, part)
|
49
|
+
guess << part
|
50
|
+
else
|
51
|
+
guess << :dynamic
|
52
|
+
end
|
53
|
+
index += 1
|
54
|
+
end
|
55
|
+
guess
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.prepare_request_path(path)
|
59
|
+
path_parts = []
|
60
|
+
path = path[0..(path.rindex('.')-1)] if path.include?('.')
|
61
|
+
path_parts = path.split("/")
|
62
|
+
path_parts.delete("")
|
63
|
+
path_parts
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.is_part_static?(routes, index, value)
|
67
|
+
routes.each do |route|
|
68
|
+
return true if route[0][index] == value
|
69
|
+
end
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.build_static_paths
|
74
|
+
# outputs [["paths"], "VERB"]
|
75
|
+
routes_paths = []
|
76
|
+
gimme_routes.each do |route|
|
77
|
+
raw_parts = route.conditions[:path_info].inspect.split("\/")
|
78
|
+
# TODO Check this carefully
|
79
|
+
raw_parts.delete("")
|
80
|
+
raw_parts.delete("\\A\\")
|
81
|
+
raw_parts.delete("([^\\")
|
82
|
+
raw_parts.pop
|
83
|
+
path_parts = []
|
84
|
+
raw_parts.each do |part|
|
85
|
+
if part =~ /\A(\w+)/
|
86
|
+
path_parts << $1
|
87
|
+
else
|
88
|
+
path_parts << :dynamic
|
89
|
+
end
|
90
|
+
end
|
91
|
+
routes_paths << [path_parts, route.verb.to_s.upcase]
|
92
|
+
end
|
93
|
+
routes_paths
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.gimme_routes
|
97
|
+
routes = Rails.application.routes.routes
|
98
|
+
routes.reject!{ |r| r.path == "/rails/info/properties" } # skip the route if it's internal info route
|
99
|
+
routes
|
20
100
|
end
|
21
101
|
|
22
102
|
end
|
@@ -2,11 +2,17 @@ module Baurets
|
|
2
2
|
module Optionsful
|
3
3
|
class Server
|
4
4
|
|
5
|
+
##
|
6
|
+
# Wakes up!
|
7
|
+
#
|
5
8
|
def initialize(app)
|
6
9
|
@app = app
|
7
10
|
@config = Config.new
|
8
11
|
end
|
9
12
|
|
13
|
+
##
|
14
|
+
# Handle HTTP OPTIONS requests.
|
15
|
+
#
|
10
16
|
def call(env)
|
11
17
|
unless env["REQUEST_METHOD"] == "OPTIONS"
|
12
18
|
@app.call(env)
|
@@ -17,6 +23,10 @@ module Baurets
|
|
17
23
|
end
|
18
24
|
|
19
25
|
private
|
26
|
+
|
27
|
+
def extract_options_information
|
28
|
+
allows = ::Baurets::Optionsful::Introspections.do_the_matches(@env["PATH_INFO"])
|
29
|
+
end
|
20
30
|
|
21
31
|
def build_response
|
22
32
|
allows = extract_options_information
|
@@ -26,7 +36,7 @@ module Baurets
|
|
26
36
|
unless allows.empty?
|
27
37
|
headers.merge!({"Allow" => allows})
|
28
38
|
status = 204
|
29
|
-
if @config.link
|
39
|
+
if @config.link == true
|
30
40
|
headers.merge!({"Link" => build_link_header})
|
31
41
|
end
|
32
42
|
else
|
@@ -51,15 +61,10 @@ module Baurets
|
|
51
61
|
if @config.propagate == true
|
52
62
|
link += @env["PATH_INFO"]
|
53
63
|
end
|
54
|
-
|
55
64
|
link += ">; type=text/html; rel=help\""
|
56
65
|
link
|
57
66
|
end
|
58
67
|
|
59
|
-
def extract_options_information
|
60
|
-
allows = ::Baurets::Optionsful::Introspections.do_the_matches(@env["PATH_INFO"])
|
61
|
-
end
|
62
|
-
|
63
68
|
end
|
64
69
|
end
|
65
70
|
end
|
data/optionsful.gemspec
CHANGED
@@ -5,26 +5,25 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{optionsful}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Marco Antonio Gonzalez Junior"]
|
12
|
-
s.date = %q{2010-08-
|
12
|
+
s.date = %q{2010-08-07}
|
13
13
|
s.description = %q{Help building RESTful web services by supporting the HTTP OPTIONS verb on Ruby on Rails applications.}
|
14
14
|
s.email = %q{kayaman@baurets.net}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
"README.
|
17
|
+
"README.textile"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".autotest",
|
21
21
|
".document",
|
22
22
|
".gitignore",
|
23
23
|
"LICENSE",
|
24
|
-
"README.
|
24
|
+
"README.textile",
|
25
25
|
"Rakefile",
|
26
26
|
"VERSION",
|
27
|
-
"config/optionsful.yml",
|
28
27
|
"features/optionsful.feature",
|
29
28
|
"features/step_definitions/optionsful3_steps.rb",
|
30
29
|
"features/support/env.rb",
|
@@ -34,9 +33,9 @@ Gem::Specification.new do |s|
|
|
34
33
|
"lib/optionsful.rb",
|
35
34
|
"optionsful.gemspec",
|
36
35
|
"rails/init.rb",
|
37
|
-
"
|
38
|
-
"
|
39
|
-
"
|
36
|
+
"samples/optionsful.yml.sample",
|
37
|
+
"samples/optionsful_bug.yml",
|
38
|
+
"samples/optionsful_true.yml",
|
40
39
|
"spec/fake_app.rb",
|
41
40
|
"spec/optionsful_config_spec.rb",
|
42
41
|
"spec/optionsful_server_spec.rb",
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Optionsful custom settings
|
2
|
+
|
3
|
+
# Link header configuration
|
4
|
+
development:
|
5
|
+
link: false
|
6
|
+
host: auto
|
7
|
+
base_path: /api
|
8
|
+
propagate: true
|
9
|
+
|
10
|
+
test:
|
11
|
+
link: false
|
12
|
+
host: auto
|
13
|
+
base_path: /api
|
14
|
+
propagate: false
|
15
|
+
|
16
|
+
production:
|
17
|
+
link: false
|
18
|
+
host: auto
|
19
|
+
base_path: /api
|
20
|
+
propagate: false
|
@@ -0,0 +1 @@
|
|
1
|
+
> 62532532836523ugwsgvzbvciueyrouoskzjh %=$ ;;;'''
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Optionsful custom settings
|
2
|
+
|
3
|
+
# Link header configuration
|
4
|
+
development:
|
5
|
+
link: true
|
6
|
+
host: auto
|
7
|
+
base_path: /api
|
8
|
+
propagate: true
|
9
|
+
|
10
|
+
test:
|
11
|
+
link: true
|
12
|
+
host: auto
|
13
|
+
base_path: /api
|
14
|
+
propagate: false
|
15
|
+
|
16
|
+
production:
|
17
|
+
link: true
|
18
|
+
host: auto
|
19
|
+
base_path: /api
|
20
|
+
propagate: false
|
@@ -1,46 +1,75 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
|
4
3
|
describe Baurets::Optionsful::Config do
|
5
4
|
|
6
5
|
include Rack::Test::Methods
|
7
6
|
|
8
7
|
context "Config carries specific settings" do
|
9
|
-
|
10
|
-
describe "when there's
|
11
|
-
|
8
|
+
|
9
|
+
describe "when there's NO custom config file, use expected default settings" do
|
10
|
+
|
12
11
|
it "the Link header generation must be disabled" do
|
13
12
|
config = Baurets::Optionsful::Config.new("file_error.txt")
|
14
13
|
config.link.should be false
|
15
14
|
end
|
16
|
-
|
15
|
+
|
17
16
|
end
|
18
|
-
|
17
|
+
|
19
18
|
describe "when there is a custom config file, load the settings from it" do
|
20
|
-
|
19
|
+
|
20
|
+
before(:each) do
|
21
|
+
@config = nil
|
22
|
+
end
|
23
|
+
|
21
24
|
it "the Link header generation must be disabled" do
|
22
|
-
|
23
|
-
config
|
24
|
-
|
25
|
+
@config = Baurets::Optionsful::Config.new()
|
26
|
+
@config.link.should be false
|
27
|
+
end
|
28
|
+
|
29
|
+
it "the Link header generation must be disabled (file found but looks corrupted!)" do
|
30
|
+
FileUtils.cp File.join(Rails.root, 'samples', 'optionsful_bug.yml'), File.join(Rails.root, 'config', 'optionsful.yml')
|
31
|
+
@config = Baurets::Optionsful::Config.new
|
32
|
+
@config.link.should == false
|
33
|
+
end
|
34
|
+
|
35
|
+
it "the Link header generation must be disabled (file given but looks corrupted!)" do
|
36
|
+
@config = Baurets::Optionsful::Config.new(File.join(Rails.root, 'samples', 'optionsful_bug.yml'))
|
37
|
+
@config.link.should be false
|
25
38
|
end
|
26
39
|
|
27
40
|
it "the Link header generation must be enabled" do
|
28
|
-
config = Baurets::Optionsful::Config.new(
|
29
|
-
config.link.should be true
|
41
|
+
@config = Baurets::Optionsful::Config.new(nil, {:link => true})
|
42
|
+
@config.link.should be true
|
30
43
|
end
|
31
|
-
|
44
|
+
|
45
|
+
it "the Link header generation must be enabled (file found)" do
|
46
|
+
FileUtils.cp File.join(Rails.root, 'samples', 'optionsful_true.yml'), File.join(Rails.root, 'config', 'optionsful.yml')
|
47
|
+
@config = Baurets::Optionsful::Config.new()
|
48
|
+
@config.link.should be true
|
49
|
+
end
|
50
|
+
|
32
51
|
it "if the Link header generation is enabled, host value must be set" do
|
33
|
-
config = Baurets::Optionsful::Config.new(File.join(
|
34
|
-
config.link.should be true
|
35
|
-
config.host.empty?.should_not be true
|
52
|
+
@config = Baurets::Optionsful::Config.new(File.join(Rails.root, 'samples', 'optionsful_true.yml'))
|
53
|
+
@config.link.should be true
|
54
|
+
@config.host.empty?.should_not be true
|
36
55
|
end
|
37
|
-
|
56
|
+
|
38
57
|
it "if the Link header generation is enabled, host value accepts 'auto'" do
|
39
|
-
config = Baurets::Optionsful::Config.new(File.join(File.dirname(__FILE__), 'config', 'optionsful_host_auto.yml'))
|
40
|
-
config.link.should be true
|
41
|
-
config.host.should == "auto"
|
58
|
+
@config = Baurets::Optionsful::Config.new(File.join(File.dirname(__FILE__), 'config', 'optionsful_host_auto.yml'))
|
59
|
+
@config.link.should be true
|
60
|
+
@config.host.should == "auto"
|
61
|
+
end
|
62
|
+
|
63
|
+
after(:each) do
|
64
|
+
FileUtils.rm [File.join(Rails.root, 'config', 'optionsful.yml')] if File.exist? File.join(Rails.root, 'config', 'optionsful.yml')
|
65
|
+
@config = nil
|
42
66
|
end
|
43
67
|
|
68
|
+
after(:all) do
|
69
|
+
FileUtils.rm [File.join(Rails.root, 'config', 'optionsful.yml')] if File.exist? File.join(Rails.root, 'config', 'optionsful.yml')
|
70
|
+
@config = nil
|
71
|
+
end
|
72
|
+
|
44
73
|
end
|
45
74
|
|
46
75
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
include Rack::Test::Methods
|
3
|
-
require 'fileutils'
|
4
3
|
|
5
4
|
describe "Optionsful" do
|
6
5
|
|
@@ -177,7 +176,6 @@ describe "Optionsful" do
|
|
177
176
|
end
|
178
177
|
|
179
178
|
it "the parent resource collection have an entry point for creating a new entry" do
|
180
|
-
pending "check regexp"
|
181
179
|
response = http_options_request("/products/new")
|
182
180
|
validate_response(response)
|
183
181
|
response[0].should be 204
|
@@ -247,7 +245,6 @@ describe "Optionsful" do
|
|
247
245
|
end
|
248
246
|
|
249
247
|
it "the sub-resource collection have an entry point for creating a new entry" do
|
250
|
-
pending "check regexp"
|
251
248
|
response = http_options_request("/products/123/sales/new")
|
252
249
|
validate_response(response)
|
253
250
|
response[0].should be 204
|
@@ -391,11 +388,9 @@ describe "Optionsful" do
|
|
391
388
|
|
392
389
|
end
|
393
390
|
|
394
|
-
|
395
|
-
|
396
391
|
end
|
397
392
|
|
398
|
-
context "Link" do
|
393
|
+
context "the Link header" do
|
399
394
|
|
400
395
|
describe "should not be present" do
|
401
396
|
|
@@ -403,12 +398,12 @@ describe "Optionsful" do
|
|
403
398
|
rails_app.routes.draw do
|
404
399
|
resources :posts
|
405
400
|
end
|
401
|
+
::Baurets::Optionsful::Config.new
|
406
402
|
end
|
407
403
|
|
408
404
|
it "if no directions were given" do
|
409
|
-
|
405
|
+
Baurets::Optionsful::Config.new(nil, {:link => false})
|
410
406
|
response = http_options_request("/posts")
|
411
|
-
FileUtils.mv File.join(Rails.root, 'optionsful.yml'), File.join(Rails.root, 'config', 'optionsful.yml')
|
412
407
|
validate_response(response)
|
413
408
|
response[0].should be 204
|
414
409
|
response[1]["Link"].should be nil
|
@@ -429,12 +424,49 @@ describe "Optionsful" do
|
|
429
424
|
end
|
430
425
|
|
431
426
|
it "the Link header MUST be quoted if it contains a semicolon or comma" do
|
427
|
+
Baurets::Optionsful::Config.new(nil, {:link => true})
|
432
428
|
response = http_options_request("/posts")
|
433
429
|
validate_response(response)
|
434
430
|
response[0].should be 204
|
435
431
|
link = response[1]["Link"]
|
436
432
|
link.should match /\A\".+\"\z/
|
437
433
|
end
|
434
|
+
|
435
|
+
it "the Link header may use its very current host" do
|
436
|
+
Baurets::Optionsful::Config.new(nil, {:link => true, :host => 'auto'})
|
437
|
+
response = http_options_request("/posts")
|
438
|
+
validate_response(response)
|
439
|
+
response[0].should be 204
|
440
|
+
link = response[1]["Link"]
|
441
|
+
link.should match /\A\"<http:\/\/localhost.+\"\z/
|
442
|
+
end
|
443
|
+
|
444
|
+
it "the Link header may use a custom host value" do
|
445
|
+
Baurets::Optionsful::Config.new(nil, {:link => true, :host => 'www.baurets.net'})
|
446
|
+
response = http_options_request("/posts")
|
447
|
+
validate_response(response)
|
448
|
+
response[0].should be 204
|
449
|
+
link = response[1]["Link"]
|
450
|
+
link.should match /\A\"<http:\/\/www.baurets.net.+\"\z/
|
451
|
+
end
|
452
|
+
|
453
|
+
it "the Link header may use a custom base path value" do
|
454
|
+
Baurets::Optionsful::Config.new(nil, {:link => true, :host => 'www.baurets.net', :base_path => "/private/api/"})
|
455
|
+
response = http_options_request("/posts")
|
456
|
+
validate_response(response)
|
457
|
+
response[0].should be 204
|
458
|
+
link = response[1]["Link"]
|
459
|
+
link.should match /\A\"<http:\/\/www.baurets.net\/private\/api\/.+\"\z/
|
460
|
+
end
|
461
|
+
|
462
|
+
it "the Link header may propagate original path info" do
|
463
|
+
Baurets::Optionsful::Config.new(nil, {:link => true, :host => 'www.baurets.net', :base_path => "/private/api/", :propagate => true})
|
464
|
+
response = http_options_request("/posts")
|
465
|
+
validate_response(response)
|
466
|
+
response[0].should be 204
|
467
|
+
link = response[1]["Link"]
|
468
|
+
link.should match /\A\"<http:\/\/www.baurets.net\/private\/api\/\/posts.+\"\z/
|
469
|
+
end
|
438
470
|
|
439
471
|
after(:all) do
|
440
472
|
Rails.application.reload_routes!
|
data/spec/spec.opts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
--color
|
1
|
+
--color --debugger
|
data/spec/spec_helper.rb
CHANGED
data/tasks/optionsful.rake
CHANGED
@@ -4,7 +4,7 @@ require 'rake'
|
|
4
4
|
namespace :optionsful do
|
5
5
|
desc "Install 'config/optionsful.yml'"
|
6
6
|
task :yml do
|
7
|
-
FileUtils.cp File.join(Baurets::Optionsful::LIB_ROOT, '..','
|
7
|
+
FileUtils.cp File.join(Baurets::Optionsful::LIB_ROOT, '..','samples', 'optionsful.yml.sample'), File.join(Rails.root, 'config', 'optionsful.yml')
|
8
8
|
puts "\nNow you are able to configure Link hader generation settings"
|
9
9
|
puts "\nEdit the file 'config/optionsful.yml' on your Rails application."
|
10
10
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: optionsful
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 0.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Marco Antonio Gonzalez Junior
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-08-
|
18
|
+
date: 2010-08-07 00:00:00 -03:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -87,16 +87,15 @@ extensions: []
|
|
87
87
|
|
88
88
|
extra_rdoc_files:
|
89
89
|
- LICENSE
|
90
|
-
- README.
|
90
|
+
- README.textile
|
91
91
|
files:
|
92
92
|
- .autotest
|
93
93
|
- .document
|
94
94
|
- .gitignore
|
95
95
|
- LICENSE
|
96
|
-
- README.
|
96
|
+
- README.textile
|
97
97
|
- Rakefile
|
98
98
|
- VERSION
|
99
|
-
- config/optionsful.yml
|
100
99
|
- features/optionsful.feature
|
101
100
|
- features/step_definitions/optionsful3_steps.rb
|
102
101
|
- features/support/env.rb
|
@@ -106,9 +105,9 @@ files:
|
|
106
105
|
- lib/optionsful.rb
|
107
106
|
- optionsful.gemspec
|
108
107
|
- rails/init.rb
|
109
|
-
-
|
110
|
-
-
|
111
|
-
-
|
108
|
+
- samples/optionsful.yml.sample
|
109
|
+
- samples/optionsful_bug.yml
|
110
|
+
- samples/optionsful_true.yml
|
112
111
|
- spec/fake_app.rb
|
113
112
|
- spec/optionsful_config_spec.rb
|
114
113
|
- spec/optionsful_server_spec.rb
|
data/README.rdoc
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
= optionsful3
|
2
|
-
|
3
|
-
Description goes here.
|
4
|
-
|
5
|
-
== Note on Patches/Pull Requests
|
6
|
-
|
7
|
-
* Fork the project.
|
8
|
-
* Make your feature addition or bug fix.
|
9
|
-
* Add tests for it. This is important so I don't break it in a
|
10
|
-
future version unintentionally.
|
11
|
-
* Commit, do not mess with rakefile, version, or history.
|
12
|
-
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
-
* Send me a pull request. Bonus points for topic branches.
|
14
|
-
|
15
|
-
== Copyright
|
16
|
-
|
17
|
-
Copyright (c) 2010 Marco Antonio Gonzalez Junior. See LICENSE for details.
|
data/config/optionsful.yml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
|
2
|
-
development:
|
3
|
-
link: true
|
4
|
-
host: auto
|
5
|
-
base_path: /blopts
|
6
|
-
propagate: false
|
7
|
-
|
8
|
-
test:
|
9
|
-
link: true
|
10
|
-
host: auto
|
11
|
-
base_path: /blopts
|
12
|
-
propagate: false
|
13
|
-
|
14
|
-
production:
|
15
|
-
link: true
|
16
|
-
host: auto
|
17
|
-
base_path: /blopts
|
18
|
-
propagate: false
|
data/spec/config/optionsful.yml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
|
2
|
-
development:
|
3
|
-
link: true
|
4
|
-
host: auto
|
5
|
-
base_path: /blopts
|
6
|
-
propagate: false
|
7
|
-
|
8
|
-
test:
|
9
|
-
link: true
|
10
|
-
host: auto
|
11
|
-
base_path: /blopts
|
12
|
-
propagate: false
|
13
|
-
|
14
|
-
production:
|
15
|
-
link: true
|
16
|
-
host: auto
|
17
|
-
base_path: /blopts
|
18
|
-
propagate: false
|
@@ -1,18 +0,0 @@
|
|
1
|
-
|
2
|
-
development:
|
3
|
-
link: true
|
4
|
-
host: auto
|
5
|
-
base_path: /blopts
|
6
|
-
propagate: false
|
7
|
-
|
8
|
-
test:
|
9
|
-
link: true
|
10
|
-
host: auto
|
11
|
-
base_path: /blopts
|
12
|
-
propagate: false
|
13
|
-
|
14
|
-
production:
|
15
|
-
link: true
|
16
|
-
host: auto
|
17
|
-
base_path: /blopts
|
18
|
-
propagate: false
|
@@ -1,18 +0,0 @@
|
|
1
|
-
|
2
|
-
development:
|
3
|
-
link: false
|
4
|
-
host: auto
|
5
|
-
base_path: /blopts
|
6
|
-
propagate: false
|
7
|
-
|
8
|
-
test:
|
9
|
-
link: false
|
10
|
-
host: auto
|
11
|
-
base_path: /blopts
|
12
|
-
propagate: false
|
13
|
-
|
14
|
-
production:
|
15
|
-
link: false
|
16
|
-
host: auto
|
17
|
-
base_path: /blopts
|
18
|
-
propagate: false
|