optionsful 0.1.7 → 0.1.8

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/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