optionsful 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -20,7 +20,7 @@ HTTP/1.1 204 No Content
20
20
  Allow: GET, POST
21
21
  Connection: close
22
22
  Date: Thu, 22 Jul 2010 17:20:27 GMT
23
- Link: <http://localhost:3000/opts/posts>; type=text/html; rel=help
23
+ Link: <http://localhost:3000/optionsful/posts>; type=text/html; rel=help
24
24
 
25
25
  OPTIONS /posts/1 HTTP/1.1
26
26
  Host: http://localhost:3000
@@ -29,7 +29,7 @@ HTTP/1.1 204 No Content
29
29
  Allow: GET, PUT, DELETE
30
30
  Connection: close
31
31
  Date: Thu, 22 Jul 2010 18:14:24 GMT
32
- Link: <http://localhost:3000/opts/posts/1/>; type=text/html; rel=help
32
+ Link: <http://localhost:3000/optionsful/posts/1/>; type=text/html; rel=help
33
33
 
34
34
  OPTIONS /posts/1/comments HTTP/1.1
35
35
  Host: http://localhost:3000
@@ -38,7 +38,7 @@ HTTP/1.1 204 No Content
38
38
  Allow: GET, POST
39
39
  Connection: close
40
40
  Date: Thu, 22 Jul 2010 18:12:43 GMT
41
- Link: <http://localhost:3000/opts/posts/1/comments>; type=text/html; rel=help
41
+ Link: <http://localhost:3000/optionsful/posts/1/comments>; type=text/html; rel=help
42
42
 
43
43
  </pre>
44
44
  ~Note the empty line which is part of the HTTP protocol.~
@@ -46,7 +46,7 @@ Link: <http://localhost:3000/opts/posts/1/comments>; type=text/html; rel=help
46
46
  h3. Retrieving the resource/service documentation right from your browser:
47
47
 
48
48
  * Access the given Link header through your preferable browser. Yeah, via an HTTP GET request.
49
- * @http://localhost:3000/opts/posts/1/comments@ for instance.
49
+ * @http://localhost:3000/optionsful/posts/1/comments@ for instance.
50
50
  * Try up adding some RDoc-like comments above your actions definitions on the appropriate controllers.
51
51
  * Refresh the page and your documentation and have fun!
52
52
  * There's a lot of helpful things we can do with this extracted 'on-the-fly' information (metadata).
@@ -1,35 +1,49 @@
1
1
  module Baurets
2
2
  module Optionsful
3
-
4
3
  class Config
5
4
 
6
- def initialize
7
- # Initialize default settings- May be overriden if RAILS_ROOT/config/optionsful.yml exists.
8
- @config = { :http => {:base_path => "/optionsful"} }
5
+ def initialize(options = {})
6
+ @config = configure_options(options)
9
7
  setup
8
+ self
9
+ end
10
+
11
+ def base_path
12
+ @config[:http][:base_path]
13
+ end
14
+
15
+ private
16
+
17
+ def configure_options(options = {})
18
+ default_opts = { :http => { :base_path => "/optionsful"}, :file => "", :environment => "development" }
19
+ conf = {}
20
+ if defined? RAILS_ROOT
21
+ conf = default_opts.merge!({:file => (File.join(RAILS_ROOT, 'config', 'optionsful.yml'))})
22
+ else
23
+ conf = default_opts.merge!({ :http => { :base_path => "/optionsful"} })
24
+ end
25
+ conf = conf.merge!(options) unless options.empty?
26
+ conf
10
27
  end
11
28
 
12
29
  def setup
13
30
  require "yaml"
31
+ yaml_file = @config[:file]
14
32
  begin
15
- yaml_file = File.join(RAILS_ROOT, "config", "optionsful.yml")
16
33
  if File.exist? yaml_file
17
- conf = YAML::load_file(yaml_file)[RAILS_ENV].symbolize_keys
34
+ conf = YAML::load_file(yaml_file)[@config[:environment]].symbolize_keys
18
35
  configure(conf) if conf
19
36
  end
20
37
  rescue
21
38
  end
22
39
  end
40
+
23
41
  def configure(conf)
24
- @config[:http][:base_path] = conf[:http][:base_path] if (conf[:http] && conf[:http][:base_path])
42
+ @config[:http][:base_path] = conf[:http]["base_path"] if (conf[:http] && conf[:http]["base_path"])
43
+ @config[:file] = conf[:file] if conf[:file]
44
+ @config[:environment] = conf[:environment] if conf[:environment]
25
45
  end
26
46
 
27
-
28
- def base_path
29
- @config[:http][:base_path]
30
- end
31
-
32
47
  end
33
-
34
48
  end
35
49
  end
@@ -4,19 +4,16 @@ module Baurets
4
4
 
5
5
  def initialize(app)
6
6
  @app = app
7
- @config = ::Baurets::Optionsful::Config.new
7
+ @config = Baurets::Optionsful::Config.new
8
8
  end
9
9
 
10
10
  def call(env)
11
- unless env["PATH_INFO"].index(@config.base_path) == 0
12
- @app.call(env)
11
+ unless env["PATH_INFO"].index(@config.base_path) == 0
12
+ response = @app.call(env)
13
13
  else
14
- begin
15
- return extract_documentation(env)
16
- rescue => e
17
- [500, {}, e.backtrace.join("\n")]
18
- end
14
+ response = extract_documentation(env)
19
15
  end
16
+ response
20
17
  end
21
18
 
22
19
  private
@@ -25,6 +22,10 @@ module Baurets
25
22
  require 'yaml'
26
23
  require 'RedCloth'
27
24
 
25
+ def verify_path(env)
26
+
27
+ end
28
+
28
29
  def extract_documentation(env)
29
30
  path = env["PATH_INFO"]
30
31
  path = path.gsub(@config.base_path, '')
@@ -43,40 +44,47 @@ module Baurets
43
44
  controller_actions << [verb, relate_action_to_method(path_parts, verb)]
44
45
  end
45
46
  controller_actions.delete_if {|pair| pair[1].empty? }
46
-
47
- controller_name = ::Baurets::Optionsful::Introspections.discover_controller_name(path_parts) + "_controller"
48
- file = File.join(RAILS_ROOT, "app", "controllers", controller_name + ".rb")
49
- controller_class = controller_name.camelize
50
-
51
- service_doc = extract_comments_above(file, find_line_for(file, controller_class, :class))
52
-
53
- methods_docs = []
54
- controller_actions.each do |info|
55
- methods_docs << [info, extract_comments_above(file, find_line_for(file, info[1], :method)).join("\n")]
47
+ controller_name = (::Baurets::Optionsful::Introspections.discover_controller_name(path_parts) + "_controller" ) if ::Baurets::Optionsful::Introspections.discover_controller_name(path_parts)
48
+ file = ""
49
+ file = File.join(RAILS_ROOT, "app", "controllers", controller_name + ".rb") if controller_name
50
+ if File.exist? file
51
+ controller_class = controller_name.camelize
52
+ service_doc = extract_comments_above(file, find_line_for(file, controller_class, :class))
53
+ methods_docs = []
54
+ controller_actions.each do |info|
55
+ methods_docs << [info, extract_comments_above(file, find_line_for(file, info[1], :method)).join("\n")]
56
+ end
57
+ body = build_html(service_doc, methods_docs)
58
+ [200, {"Content-Type" => "text/html"}, body]
59
+ else
60
+ [404, {}, " "]
56
61
  end
57
-
58
- body = build_html(service_doc, methods_docs)
59
-
60
- [200, {"Content-Type" => "text/html"}, body]
61
62
  end
62
63
 
63
-
64
- def build_html(comment, methods)
65
- comments = comment.join("\n").gsub(/^#+\s/, '')
66
- resource = YAML::parse(comments)
64
+ def build_html(srvc, methods)
67
65
  html = "<html><head></head><body>"
68
- resource_title = resource["resource"]["title"].value
69
-
70
- title = "h1. " + resource_title.to_s if resource_title
71
-
72
- html += RedCloth.new(title).to_html
73
-
74
- html += RedCloth.new("#{resource["resource"]["description"].value}").to_html
75
-
76
- methods.each do |meth|
77
- meth_verb = meth[0][0]
78
- #TODO
79
- html += RedCloth.new("*" + meth_verb).to_html
66
+ comments = srvc.join("\n").gsub(/^#+\s/, '')
67
+ srvc_doc = YAML::parse(comments)
68
+ if srvc_doc && srvc_doc["service"]
69
+ resource_title = srvc_doc["service"]["title"].value
70
+ title = "h1. " + resource_title.to_s if resource_title
71
+ html += RedCloth.new(title).to_html
72
+ html += RedCloth.new("#{srvc_doc["service"]["description"].value}").to_html
73
+ html += "\n<link rel=\"replies\" href=\"\" </link>"
74
+ methods.each do |meth|
75
+ meth_verb = meth[0][0]
76
+ method_comms = meth[1].gsub(/^#+\s/, '') unless meth[1].empty?
77
+ resource = YAML::parse(method_comms)
78
+ html += RedCloth.new("h2. " + meth_verb).to_html
79
+ if resource && resource["resource"]
80
+ html += RedCloth.new(resource["resource"]["title"].value).to_html
81
+ html += RedCloth.new(resource["resource"]["identifier"].value).to_html
82
+ else
83
+ html += RedCloth.new("Could not find or understand any annotated metadata related to method #{meth_verb}.").to_html
84
+ end
85
+ end
86
+ else
87
+ html += RedCloth.new("Could not understand anything.").to_html
80
88
  end
81
89
  html += "</body></html>"
82
90
  html
@@ -22,7 +22,7 @@ module Baurets
22
22
  if allows.empty?
23
23
  [404, {}, "Not found."]
24
24
  else
25
- [204, {"Allow" => allows, "Link" => build_help_link(env)}, ""]
25
+ [204, {"Allow" => allows, "Link" => "\"#{build_help_link(env)}\""}, ""]
26
26
  end
27
27
  end
28
28
 
@@ -4,7 +4,7 @@ module Baurets
4
4
 
5
5
  MAJOR = 0
6
6
  MINOR = 1
7
- TINY = 7
7
+ TINY = 8
8
8
 
9
9
  def self.to_s
10
10
  "#{MAJOR}.#{MINOR}.#{TINY}"
@@ -0,0 +1,11 @@
1
+ development:
2
+ http:
3
+ base_path: /blopts
4
+
5
+ test:
6
+ http:
7
+ base_path: /test
8
+
9
+ production:
10
+ http:
11
+ base_path: /blopts
File without changes
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+
4
+ describe Baurets::Optionsful::Config do
5
+
6
+ include Rack::Test::Methods
7
+
8
+ describe "Config carries specific settings" do
9
+
10
+ describe "by default, try to find the custom configuration file" do
11
+
12
+ it "if the custom configuration file exist, try to load settings from it" do
13
+ config = Baurets::Optionsful::Config.new( {:file => File.join(File.dirname(__FILE__), 'fixtures', 'optionsful.yml'), :environment => "test" })
14
+ config.base_path.should == "/test"
15
+ end
16
+
17
+ it "if the custom configuration file exist and is not valid, keep the default settings" do
18
+ config = Baurets::Optionsful::Config.new( {:file => File.join(File.dirname(__FILE__), 'fixtures', 'optionsful_bug.yml'), :environment => "test" })
19
+ config.base_path.should == "/optionsful"
20
+ end
21
+
22
+ it "if no configuration file is informed or found, do load the default settings" do
23
+ config = Baurets::Optionsful::Config.new
24
+ config.base_path.should == "/optionsful"
25
+ end
26
+
27
+ it "if RAILS_ROOT is defined, look for the custom configuration file on its config folder" do
28
+ Baurets::Optionsful::Config.const_set(:RAILS_ROOT, File.dirname(__FILE__))
29
+ config = Baurets::Optionsful::Config.new
30
+ config.base_path.should == "/optionsful"
31
+ end
32
+
33
+ end
34
+
35
+ describe "if a custom configuration file is informed "
36
+
37
+ it "and does not exist, keep default settings" do
38
+ config = Baurets::Optionsful::Config.new( {:file => File.join(File.dirname(__FILE__), 'fixtures', 'optionsful_xxx.yml'), :environment => "test" })
39
+ config.base_path.should == "/optionsful"
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -5,8 +5,9 @@ describe Baurets::Optionsful::Documentator do
5
5
 
6
6
  include Rack::Test::Methods
7
7
 
8
- config = ::Baurets::Optionsful::Config.new
9
- path = config.base_path
8
+ Baurets::Optionsful::Documentator.send(:remove_const, :RAILS_ROOT) if Baurets::Optionsful::Documentator.const_defined?(:RAILS_ROOT)
9
+ Baurets::Optionsful::Documentator.const_set(:RAILS_ROOT, File.join(File.dirname(__FILE__), 'samples' ) )
10
+ base_path = ::Baurets::Optionsful::Config.new.base_path
10
11
 
11
12
  describe "as a Rack middleware" do
12
13
 
@@ -14,13 +15,19 @@ config = ::Baurets::Optionsful::Config.new
14
15
  assert ::Baurets::Optionsful::Documentator.new(app).respond_to? :call
15
16
  end
16
17
 
18
+ before do
19
+ ActionController::Routing::Routes.draw do |map|
20
+ map.resources :posts, :has_many => :comments
21
+ end
22
+ end
23
+
17
24
  it "takes exactly one argument, (the environment) and returns an Array;" do
18
- response = ::Baurets::Optionsful::Documentator.new(app).call(mock_env({"REQUEST_METHOD" => "GET", "PATH_INFO" => path}))
25
+ response = ::Baurets::Optionsful::Documentator.new(app).call(mock_env({"REQUEST_METHOD" => "GET", "PATH_INFO" => (base_path + "/posts")}))
19
26
  assert response.kind_of?(Array)
20
27
  end
21
28
 
22
29
  it "the returned Array must have exactly three values: the status, the headers and the body;" do
23
- response = ::Baurets::Optionsful::Documentator.new(app).call(mock_env({"REQUEST_METHOD" => "GET", "PATH_INFO" => path}))
30
+ response = ::Baurets::Optionsful::Documentator.new(app).call(mock_env({"REQUEST_METHOD" => "GET", "PATH_INFO" => (base_path + "/posts")}))
24
31
  assert response.size.should == 3
25
32
  assert response[0].kind_of? Fixnum
26
33
  assert response[1].kind_of? Hash
@@ -37,4 +44,74 @@ config = ::Baurets::Optionsful::Config.new
37
44
 
38
45
  end
39
46
 
47
+ describe "extracts metadata information about a resource" do
48
+
49
+ describe "MUST override Rails routing recognition successfully" do
50
+
51
+ before(:all) do
52
+ ActionController::Routing::Routes.draw do |map|
53
+ map.resources :posts, :has_many => :comments
54
+ map.resources :notes
55
+ map.resources :stuff
56
+ map.resources :trips
57
+ map.resources :teams
58
+ end
59
+ end
60
+
61
+ it "may let the request go through if base path doesn't match" do
62
+ pending
63
+ # req_path = "/xyz"
64
+ # response = http_get_request(req_path)
65
+ # assert response[0].kind_of? Fixnum
66
+ # assert response[0].should_not == 500
67
+ end
68
+
69
+
70
+ it "MAY find proper structured information and build an html response" do
71
+ Baurets::Optionsful::Documentator.send(:remove_const, :RAILS_ROOT) if Baurets::Optionsful::Documentator.const_defined?(:RAILS_ROOT)
72
+ Baurets::Optionsful::Documentator.const_set(:RAILS_ROOT, File.join(File.dirname(__FILE__), 'samples' ) )
73
+ req_path = base_path + "/posts"
74
+ response = http_get_request(req_path)
75
+
76
+ assert response[0].kind_of? Fixnum
77
+ assert response[0].should == 200
78
+ end
79
+
80
+ it "MAY NOT find proper structured information and build an html response" do
81
+ req_path = base_path + "/notes"
82
+ response = http_get_request(req_path)
83
+ assert response.kind_of?(Array)
84
+ assert response[0].kind_of? Fixnum
85
+ end
86
+
87
+ it "MAY NOT find controller file and build an html response" do
88
+ req_path = base_path + "/stuff"
89
+ response = http_get_request(req_path)
90
+ assert response.kind_of?(Array)
91
+ assert response[0].kind_of? Fixnum
92
+ end
93
+
94
+ it "MAY NOT understand anything" do
95
+ req_path = base_path + "/trips"
96
+ response = http_get_request(req_path)
97
+ assert response.kind_of?(Array)
98
+ assert response[0].kind_of? Fixnum
99
+ end
100
+
101
+ it "MAY NOT understand anything" do
102
+ req_path = base_path + "/teams"
103
+ response = http_get_request(req_path)
104
+ assert response.kind_of?(Array)
105
+ assert response[0].kind_of? Fixnum
106
+ end
107
+
108
+
109
+ after(:all) do
110
+ ActionController::Routing::Routes.reload!
111
+ end
112
+
113
+ end
114
+
115
+ end
116
+
40
117
  end
@@ -5,13 +5,6 @@ describe Baurets::Optionsful::Server do
5
5
 
6
6
  include Rack::Test::Methods
7
7
 
8
- before(:all) do
9
- ActionController::Routing::Routes.draw do |map|
10
- map.resources :posts, :has_many => :comments
11
- end
12
- end
13
-
14
-
15
8
  describe "as a Rack middleware" do
16
9
 
17
10
  it "is a Ruby object that responds to call;" do
@@ -31,6 +24,12 @@ describe Baurets::Optionsful::Server do
31
24
  assert response[2].kind_of? String
32
25
  end
33
26
 
27
+ before do
28
+ ActionController::Routing::Routes.draw do |map|
29
+ map.resources :posts, :has_many => :comments
30
+ end
31
+ end
32
+
34
33
  it "must be nice, acting somewhere on a Rack middleware stack." do
35
34
  response = fake_opts_app.call(mock_env({"REQUEST_METHOD" => "OPTIONS", "PATH_INFO" => "/posts"}))
36
35
  assert response.size.should == 3
@@ -40,14 +39,27 @@ describe Baurets::Optionsful::Server do
40
39
  assert response[1]["Allow"]
41
40
  end
42
41
 
42
+ it "must let the request go through the stack, if it has nothing to it" do
43
+ response = fake_opts_app.call(mock_env({"REQUEST_METHOD" => "GET", "PATH_INFO" => "/lobster"}))
44
+ assert response.size.should == 3
45
+ assert response[0].kind_of? Fixnum
46
+ assert response[0].should == 200
47
+ assert response[1].kind_of? Hash
48
+ end
49
+
43
50
  end
44
51
 
52
+ describe "is intended to provide HTTP OPTIONS calls for Rails RESTful resources" do
45
53
 
46
- describe "to collect the allowed HTTP methods" do
54
+ describe "to collect the allowed HTTP methods, it overrides Rails routing recognition, so it must understand" do
47
55
 
48
- describe "overrides Rails routing recognition " do
56
+ describe "the default Rails resource routing: " do
49
57
 
50
- describe "must understand the default Rails resource routing: " do
58
+ before(:all) do
59
+ ActionController::Routing::Routes.draw do |map|
60
+ map.resources :posts, :has_many => :comments
61
+ end
62
+ end
51
63
 
52
64
  it "the index action displays a list of all posts in response of a GET request;" do
53
65
  response = http_options_request("/posts")
@@ -90,36 +102,68 @@ describe Baurets::Optionsful::Server do
90
102
  assert response.kind_of?(Array)
91
103
  assert allows?(response[1], "DELETE")
92
104
  end
93
-
105
+
94
106
  it "not found a path" do
95
107
  response = http_options_request("/sblingers/sblongers")
96
108
  assert response.kind_of?(Array)
97
109
  assert response[0].should == 404
98
110
  end
99
-
111
+
112
+ # Note that extension relation types are REQUIRED to be absolute URIs
113
+ # in Link headers, and MUST be quoted if they contain a semicolon (";")
114
+ # or comma (",") (as these characters are used as delimiters in the
115
+ # header itself).
116
+
117
+ it "the Link header MUST be quoted if it contains a semicolon or comma" do
118
+ response = http_options_request("/posts")
119
+ assert response.kind_of?(Array)
120
+ link = response[1]["Link"]
121
+
122
+ assert link.should =~ /\A"{1}.+"\z/
123
+
124
+ end
125
+
100
126
  it "not finding a path, pretend you're dead and.. let it goes through" do
101
127
  pending
102
128
  end
103
129
 
104
130
  end
105
131
 
106
- end
132
+ describe "must understand Rails named routes" do
107
133
 
108
- end
134
+ before(:each) do
135
+ ActionController::Routing::Routes.draw do |map|
136
+ map.login 'login', :controller => 'accounts', :action => 'login'
137
+ end
138
+ end
109
139
 
110
- describe " dispatch the call to the application unless HTTP method equals OPTIONS " do
140
+ it "must understand" do
141
+ pending
142
+ end
111
143
 
112
- it " method GET example" do
113
- complex_env = mock_env({"REQUEST_METHOD" => "GET", "PATH_INFO" => "/lobster" })
114
- response = fake_opts_app.call(complex_env)
115
- assert response.kind_of?(Array)
116
- assert response.size.should == 3
117
- end
118
144
 
119
- end
120
145
 
121
- after(:all) do
122
- ActionController::Routing::Routes.reload!
146
+ end
147
+
148
+ describe "Rails custom route" do
149
+
150
+ end
151
+
152
+ describe "Rails route globbing" do
153
+
154
+ end
155
+
156
+ describe "Pretty URLs" do
157
+ end
158
+
159
+ describe "Regular Expressions and parameters" do
160
+ end
161
+
162
+ end
163
+
123
164
  end
124
165
 
125
166
  end
167
+
168
+
169
+
@@ -0,0 +1,86 @@
1
+ # ---
2
+ # service:
3
+ # title: Post comments controller
4
+ # entrypoint: /posts/:post/comments
5
+ # support: kayaman@baurets.net
6
+ # description: Comments Service allow you say shit about anything you dislike!
7
+ class CommentsController < ApplicationController
8
+
9
+ # ---
10
+ # resource:
11
+ # title: list
12
+ # identifier: /posts/{:post}/comments
13
+ # support: kayaman@baurets.net
14
+ # description: Create new comments over a post instance.
15
+ # source-link: research
16
+ # alternates:
17
+ # - one
18
+ # - two
19
+ # representation:
20
+ # media-types:
21
+ # - application/xml
22
+ # - application/json
23
+ # last-modified: 2010-07-23
24
+ # control:
25
+ # cache: no-cache
26
+ def index
27
+ end
28
+
29
+ # ---
30
+ # resource:
31
+ # title: create
32
+ # identifier: /
33
+ # support: kayaman@baurets.net
34
+ # description: Create new posts.
35
+ # source-link: research
36
+ # alternates:
37
+ # - one
38
+ # - two
39
+ # representation:
40
+ # media-types:
41
+ # - application/xml
42
+ # - application/json
43
+ # last-modified: 2010-07-23
44
+ # control:
45
+ # cache: no-cache
46
+ def show
47
+ end
48
+
49
+
50
+ def new
51
+ end
52
+
53
+
54
+ def update
55
+ end
56
+
57
+
58
+ def delete
59
+ end
60
+
61
+ # ---
62
+ # resource:
63
+ # title: create
64
+ # identifier: /
65
+ # support: kayaman@baurets.net
66
+ # description: Create new posts.
67
+ # source-link: research
68
+ # alternates:
69
+ # - one
70
+ # - two
71
+ # representation:
72
+ # media-types:
73
+ # - application/xml
74
+ # - application/json
75
+ # last-modified: 2010-07-23
76
+ # control:
77
+ # cache: no-cache
78
+ def create
79
+ @post = Post.find(params[:post_id])
80
+ @comment = @post.comments.create!(params[:comment])
81
+ respond_to do |format|
82
+ format.html { redirect_to @post }
83
+ format.js
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,6 @@
1
+ class NotesController < ApplicationController
2
+
3
+
4
+
5
+
6
+ end
@@ -0,0 +1,185 @@
1
+ # ---
2
+ # service:
3
+ # title: Posts front controller
4
+ # entrypoint: /posts
5
+ # support: kayaman@baurets.net
6
+ # description: The Posts sevices let you list, create, update, and delete Posts from our application.
7
+ class PostsController < ApplicationController
8
+ before_filter :authenticate, :except => [:index, :show]
9
+
10
+ # ---
11
+ # resource:
12
+ # title: Listing
13
+ # identifier: /
14
+ # support: kayaman@baurets.net
15
+ # description: List posts.
16
+ # source-link: research
17
+ # alternates:
18
+ # - one
19
+ # - two
20
+ # representation:
21
+ # media-types:
22
+ # - application/xml
23
+ # - application/json
24
+ # last-modified: 2010-07-23
25
+ # control:
26
+ # cache: cache-control
27
+ def index
28
+ @posts = Post.find(:all)
29
+
30
+ respond_to do |format|
31
+ format.html # index.html.erb
32
+ format.xml { render :xml => @posts }
33
+ format.json { render :json => @posts }
34
+ format.atom
35
+ end
36
+ end
37
+
38
+ # ---
39
+ # resource:
40
+ # title: Posts front controller
41
+ # identifier: /posts
42
+ # support: kayaman@baurets.net
43
+ # description: Retuns all posts.
44
+ # representation:
45
+ # media-types:
46
+ # - application/xml
47
+ # - application/json
48
+ # last-modified: 2010-07-23
49
+ def show
50
+ @post = Post.find(params[:id])
51
+
52
+ respond_to do |format|
53
+ format.html # show.html.erb
54
+ format.xml { render :xml => @post }
55
+ end
56
+ end
57
+
58
+ # ---
59
+ # resource:
60
+ # title: Posts front controller
61
+ # identifier: /posts
62
+ # support: kayaman@baurets.net
63
+ # description: Retuns all posts.
64
+ # representation:
65
+ # media-types:
66
+ # - application/xml
67
+ # - application/json
68
+ # last-modified: 2010-07-23
69
+ def new
70
+ @post = Post.new
71
+
72
+ respond_to do |format|
73
+ format.html # new.html.erb
74
+ format.xml { render :xml => @post }
75
+ end
76
+ end
77
+
78
+ # ---
79
+ # resource:
80
+ # title: create
81
+ # identifier: /
82
+ # support: kayaman@baurets.net
83
+ # description: Create new posts.
84
+ # source-link: research
85
+ # alternates:
86
+ # - one
87
+ # - two
88
+ # representation:
89
+ # media-types:
90
+ # - application/xml
91
+ # - application/json
92
+ # last-modified: 2010-07-23
93
+ # control:
94
+ # cache: no-cache
95
+ def edit
96
+ @post = Post.find(params[:id])
97
+ end
98
+
99
+ # ---
100
+ # resource:
101
+ # title: create
102
+ # identifier: /
103
+ # support: kayaman@baurets.net
104
+ # description: Create new posts.
105
+ # source-link: research
106
+ # alternates:
107
+ # - one
108
+ # - two
109
+ # representation:
110
+ # media-types:
111
+ # - application/xml
112
+ # - application/json
113
+ # last-modified: 2010-07-23
114
+ # control:
115
+ # cache: no-cache
116
+ def create
117
+ @post = Post.new(params[:post])
118
+
119
+ respond_to do |format|
120
+ if @post.save
121
+ flash[:notice] = 'Post was successfully created.'
122
+ format.html { redirect_to(@post) }
123
+ format.xml { render :xml => @post, :status => :created, :location => @post }
124
+ else
125
+ format.html { render :action => "new" }
126
+ format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
127
+ end
128
+ end
129
+ end
130
+
131
+ # ---
132
+ # resource:
133
+ # title: Posts front controller
134
+ # identifier: /posts
135
+ # support: kayaman@baurets.net
136
+ # description: Retuns all posts.
137
+ # representation:
138
+ # media-types:
139
+ # - application/xml
140
+ # - application/json
141
+ # last-modified: 2010-07-23
142
+ def update
143
+ @post = Post.find(params[:id])
144
+
145
+ respond_to do |format|
146
+ if @post.update_attributes(params[:post])
147
+ flash[:notice] = 'Post was successfully updated.'
148
+ format.html { redirect_to(@post) }
149
+ format.xml { head :ok }
150
+ else
151
+ format.html { render :action => "edit" }
152
+ format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
153
+ end
154
+ end
155
+ end
156
+
157
+ # ---
158
+ # resource:
159
+ # title: Posts front controller
160
+ # identifier: /posts
161
+ # support: kayaman@baurets.net
162
+ # description: Retuns all posts.
163
+ # representation:
164
+ # media-types:
165
+ # - application/xml
166
+ # - application/json
167
+ # last-modified: 2010-07-23
168
+ def destroy
169
+ @post = Post.find(params[:id])
170
+ @post.destroy
171
+
172
+ respond_to do |format|
173
+ format.html { redirect_to(posts_url) }
174
+ format.xml { head :ok }
175
+ end
176
+ end
177
+
178
+ private
179
+
180
+ def authenticate
181
+ authenticate_or_request_with_http_basic do |name, password|
182
+ name == "admin" && password == "secret"
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,33 @@
1
+ # ---
2
+ # service:
3
+ # title: Teams controller
4
+ # entrypoint: /posts/:post/comments
5
+ # support: kayaman@baurets.net
6
+ # description: Comments Service allow you say shit about anything you dislike!
7
+ class TripsController < ApplicationController
8
+
9
+ # !! something wrong ? &
10
+ # & ^% !@#
11
+ def index
12
+ end
13
+
14
+ def show
15
+ end
16
+
17
+
18
+ def new
19
+ end
20
+
21
+
22
+ def update
23
+ end
24
+
25
+
26
+ def delete
27
+ end
28
+
29
+
30
+ def create
31
+
32
+ end
33
+ end
@@ -0,0 +1,82 @@
1
+ ##
2
+ # sjdhsdjhsdhhjdhjjdhsjhsdhsdjhjshdjhsdshd
3
+ class TripsController < ApplicationController
4
+
5
+ # ---
6
+ # resource:
7
+ # title: list
8
+ # identifier: /posts/{:post}/comments
9
+ # support: kayaman@baurets.net
10
+ # description: Create new comments over a post instance.
11
+ # source-link: research
12
+ # alternates:
13
+ # - one
14
+ # - two
15
+ # representation:
16
+ # media-types:
17
+ # - application/xml
18
+ # - application/json
19
+ # last-modified: 2010-07-23
20
+ # control:
21
+ # cache: no-cache
22
+ def index
23
+ end
24
+
25
+ # ---
26
+ # resource:
27
+ # title: create
28
+ # identifier: /
29
+ # support: kayaman@baurets.net
30
+ # description: Create new posts.
31
+ # source-link: research
32
+ # alternates:
33
+ # - one
34
+ # - two
35
+ # representation:
36
+ # media-types:
37
+ # - application/xml
38
+ # - application/json
39
+ # last-modified: 2010-07-23
40
+ # control:
41
+ # cache: no-cache
42
+ def show
43
+ end
44
+
45
+
46
+ def new
47
+ end
48
+
49
+
50
+ def update
51
+ end
52
+
53
+
54
+ def delete
55
+ end
56
+
57
+ # ---
58
+ # resource:
59
+ # title: create
60
+ # identifier: /
61
+ # support: kayaman@baurets.net
62
+ # description: Create new posts.
63
+ # source-link: research
64
+ # alternates:
65
+ # - one
66
+ # - two
67
+ # representation:
68
+ # media-types:
69
+ # - application/xml
70
+ # - application/json
71
+ # last-modified: 2010-07-23
72
+ # control:
73
+ # cache: no-cache
74
+ def create
75
+ @post = Post.find(params[:post_id])
76
+ @comment = @post.comments.create!(params[:comment])
77
+ respond_to do |format|
78
+ format.html { redirect_to @post }
79
+ format.js
80
+ end
81
+ end
82
+ end
data/spec/spec_helper.rb CHANGED
@@ -73,6 +73,12 @@ DEFAULT_ENV = { "rack.version" => Rack::VERSION, "rack.input" => StringIO.new, "
73
73
  response = Baurets::Optionsful::Server.new(app).call(complex_env)
74
74
  end
75
75
 
76
+ def http_get_request(path)
77
+ complex_env = mock_env({"REQUEST_METHOD" => "GET", "PATH_INFO" => path })
78
+ response = Baurets::Optionsful::Documentator.new(app).call(complex_env)
79
+ end
80
+
81
+
76
82
  def allows?(headers, method)
77
83
  headers["Allow"].include?(method)
78
84
  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: 21
4
+ hash: 11
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 7
10
- version: 0.1.7
9
+ - 8
10
+ version: 0.1.8
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-07-22 00:00:00 -03:00
18
+ date: 2010-07-26 00:00:00 -03:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -34,7 +34,7 @@ dependencies:
34
34
  version: 4.2.2
35
35
  type: :runtime
36
36
  version_requirements: *id001
37
- description: Optionsful provide dynamic information via HTTP's OPTION method.
37
+ description: Optionsful provide dynamic information and HTTP's OPTION method support.
38
38
  email: kayaman@baurets.net
39
39
  executables: []
40
40
 
@@ -45,21 +45,29 @@ extra_rdoc_files: []
45
45
  files:
46
46
  - README.textile
47
47
  - MIT-LICENSE
48
- - lib/baurets/optionsful/server.rb
49
- - rails/init.rb
50
- - lib/tasks/optionsful.rake
51
48
  - Rakefile
52
- - spec/optionsful_server_spec.rb
53
- - spec/spec.opts
54
- - spec/spec_helper.rb
49
+ - lib/optionsful.rb
55
50
  - lib/baurets/optionsful/documentator.rb
51
+ - lib/baurets/optionsful/server.rb
56
52
  - lib/baurets/optionsful/introspections.rb
57
- - lib/baurets/optionsful/version.rb
58
53
  - lib/baurets/optionsful/config.rb
59
- - lib/optionsful.rb
54
+ - lib/baurets/optionsful/version.rb
55
+ - lib/tasks/optionsful.rake
56
+ - rails/init.rb
57
+ - spec/fixtures/optionsful.yml
58
+ - spec/fixtures/optionsful_bug.yml
59
+ - spec/samples/app/controllers/comments_controller.rb
60
+ - spec/samples/app/controllers/notes_controller.rb
61
+ - spec/samples/app/controllers/posts_controller.rb
62
+ - spec/samples/app/controllers/teams_controller.rb
63
+ - spec/samples/app/controllers/trips_controller.rb
64
+ - spec/optionsful_server_spec.rb
60
65
  - spec/optionsful_documentator_spec.rb
66
+ - spec/optionsful_config_spec.rb
67
+ - spec/spec.opts
68
+ - spec/spec_helper.rb
61
69
  has_rdoc: true
62
- homepage: http://optionsful.rubyforge.org
70
+ homepage: http://github.com/kayaman/optionsful
63
71
  licenses: []
64
72
 
65
73
  post_install_message:
@@ -91,6 +99,6 @@ rubyforge_project:
91
99
  rubygems_version: 1.3.7
92
100
  signing_key:
93
101
  specification_version: 3
94
- summary: Optionsful provide dynamic information via HTTP's OPTION method over a Ruby on Rails applications.
102
+ summary: Optionsful gives HTTP's OPTION method support for Ruby on Rails applications. Also extract dynamic information for easily documenting RESTful web services.
95
103
  test_files: []
96
104