http_spec 0.0.2 → 0.1.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.
@@ -11,15 +11,11 @@ module HTTPSpec
11
11
  def dispatch(request)
12
12
  opts = headers_to_env(request.headers)
13
13
  opts[:input] = request.body
14
- from_rack @session.request(request.method, request.path, opts)
14
+ @session.request(request.method, request.path, opts)
15
15
  end
16
16
 
17
17
  private
18
18
 
19
- def from_rack(response)
20
- Response.new(response.status, response.body, response.headers)
21
- end
22
-
23
19
  def headers_to_env(headers)
24
20
  return {} unless headers
25
21
  headers.inject({}) do |env, (k, v)|
@@ -0,0 +1,137 @@
1
+ require "http_spec/types"
2
+ require "raddocs"
3
+ require "fileutils"
4
+
5
+ module HTTPSpec
6
+ module Clients
7
+ class RaddocsProxy
8
+ def initialize(inner, metadata, dir = Raddocs.configuration.docs_dir)
9
+ @inner = inner
10
+ @resource_name = metadata.fetch(:resource_name)
11
+ @description = metadata[:description]
12
+ raise KeyError, "key not found :description" unless @description
13
+ @parameters = metadata[:parameters]
14
+ @explanation = metadata[:explanation]
15
+ @dir = dir
16
+ end
17
+
18
+ def dispatch(request)
19
+ write_index
20
+ response = @inner.dispatch(request)
21
+ write_example(request, response)
22
+ response
23
+ end
24
+
25
+ private
26
+
27
+ def write_index
28
+ filepath = File.join(@dir, "index.json")
29
+ index = load_or_new(Index, filepath)
30
+ index.add_example(@resource_name, @description, example_path)
31
+ File.open(filepath, "w") { |file| index.dump(file) }
32
+ end
33
+
34
+ def write_example(request, response)
35
+ filepath = File.join(@dir, example_path)
36
+ FileUtils.mkdir_p(File.dirname(filepath))
37
+ example = load_or_new(Example, filepath, @resource_name, @description)
38
+ example.explanation = @explanation
39
+ example.parameters = @parameters
40
+ example.add_request(request, response)
41
+ File.open(filepath, "w") { |file| example.dump(file) }
42
+ end
43
+
44
+ def example_path
45
+ dirname = @resource_name.gsub(/\s+/, '_').gsub(/\W/, '')
46
+ filename = @description.downcase.gsub(/\s+/, '_').gsub(/\W/, '')
47
+ File.join(dirname, filename + ".json")
48
+ end
49
+
50
+ def load_or_new(klass, filepath, *args)
51
+ if File.exists?(filepath)
52
+ File.open(filepath, "r") { |file| klass.load(file) }
53
+ else
54
+ klass.new(*args)
55
+ end
56
+ end
57
+
58
+ class Index
59
+ attr_reader :resources
60
+
61
+ def initialize(resources = [])
62
+ @resources = resources
63
+ end
64
+
65
+ def self.load(io, serializer = JSON)
66
+ content = serializer.load(io)
67
+ resources = content.fetch("resources")
68
+ new(resources)
69
+ end
70
+
71
+ def dump(io, serializer = JSON)
72
+ content = { "resources" => resources }
73
+ serializer.dump(content, io)
74
+ end
75
+
76
+ def add_example(resource_name, description, link)
77
+ resource = resources.find { |r| r["name"] == resource_name }
78
+ unless resource
79
+ resource = { "name" => resource_name, "examples" => [] }
80
+ resources.push(resource)
81
+ end
82
+ examples = resource.fetch("examples")
83
+ example = examples.find { |e| e["description"] == description }
84
+ unless example
85
+ example = { "description" => description, "link" => link }
86
+ examples.push(example)
87
+ end
88
+ end
89
+ end
90
+
91
+ class Example
92
+ attr_reader :resource_name, :description, :requests
93
+ attr_accessor :explanation, :parameters
94
+
95
+ def initialize(resource_name, description, requests = [])
96
+ @resource_name = resource_name
97
+ @description = description
98
+ @requests = requests
99
+ end
100
+
101
+ def self.load(io, serializer = JSON)
102
+ content = serializer.load(io)
103
+ resource_name = content.fetch("resource")
104
+ description = content.fetch("description")
105
+ requests = content.fetch("requests")
106
+ new(resource_name, description, requests).tap do |example|
107
+ example.explanation = content["explanation"]
108
+ example.parameters = content["parameters"]
109
+ end
110
+ end
111
+
112
+ def dump(io, serializer = JSON)
113
+ content = {
114
+ "resource" => resource_name,
115
+ "description" => description,
116
+ "explanation" => explanation,
117
+ "parameters" => parameters,
118
+ "requests" => requests
119
+ }
120
+ serializer.dump(content, io)
121
+ end
122
+
123
+ def add_request(request, response)
124
+ requests.push(
125
+ "request_headers" => request.headers || {},
126
+ "request_method" => request.method.upcase,
127
+ "request_path" => request.path,
128
+ "request_body" => request.body,
129
+ "response_status" => response.status,
130
+ "response_headers" => response.headers,
131
+ "response_body" => response.body
132
+ )
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -1,3 +1,4 @@
1
+ require "http_spec"
1
2
  require "http_spec/types"
2
3
 
3
4
  module HTTPSpec
@@ -7,7 +8,7 @@ module HTTPSpec
7
8
  methods.each do |method|
8
9
  define_method(method) do |path, body=nil, headers=nil|
9
10
  request = Request.new(method, path, body, headers)
10
- client.dispatch(request)
11
+ HTTPSpec.dispatch(request)
11
12
  end
12
13
  end
13
14
  end
@@ -0,0 +1,35 @@
1
+ module HTTPSpec
2
+ module DSL
3
+ module Parameters
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ base.metadata[:parameters] = []
7
+ end
8
+
9
+ module ClassMethods
10
+ def parameter(name, description, extra = {})
11
+ param = extra.merge(:name => name, :description => description)
12
+ copy_superclass_metadata(:parameters)
13
+ metadata[:parameters].push(param)
14
+ end
15
+
16
+ def copy_superclass_metadata(key)
17
+ return unless superclass_metadata && superclass_metadata[key]
18
+ if superclass_metadata[key].equal?(metadata[key])
19
+ metadata[key] = superclass_metadata[key].dup
20
+ end
21
+ end
22
+ end
23
+
24
+ def params
25
+ return {} unless example.metadata[:parameters]
26
+ @params ||= {}
27
+ example.metadata[:parameters].each do |param|
28
+ name = param[:name]
29
+ @params[name] ||= send(name) if respond_to?(name)
30
+ end
31
+ @params
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,4 @@
1
+ require "http_spec"
1
2
  require "http_spec/types"
2
3
 
3
4
  module HTTPSpec
@@ -5,30 +6,24 @@ module HTTPSpec
5
6
  module Resource
6
7
  def self.included(base)
7
8
  base.extend(ClassMethods)
9
+ base.metadata[:default_headers] = {}
8
10
  end
9
11
 
10
12
  module ClassMethods
11
13
  def self.define_actions(*methods)
12
14
  methods.each do |method|
13
- define_method(method) do |route, &block|
15
+ define_method(method) do |route, metadata = {}, &block|
14
16
  description = "#{method.to_s.upcase} #{route}"
15
- request = Request.new(method, route)
16
- context(description, :request => request, &block)
17
+ metadata[:request] = Request.new(method, route)
18
+ context(description, metadata, &block)
17
19
  end
18
20
  end
19
21
  end
20
22
 
21
23
  define_actions :get, :post, :put, :patch, :delete, :options, :head
22
24
 
23
- def parameter(name, description, extra = {})
24
- copy_superclass_metadata(:parameters)
25
- metadata[:parameters] ||= {}
26
- metadata[:parameters][name] = extra.merge(:description => description)
27
- end
28
-
29
25
  def header(name, value)
30
26
  copy_superclass_metadata(:default_headers)
31
- metadata[:default_headers] ||= {}
32
27
  metadata[:default_headers][name] = value
33
28
  end
34
29
 
@@ -41,21 +36,11 @@ module HTTPSpec
41
36
  end
42
37
 
43
38
  def do_request(options = {})
44
- request = example.metadata[:request]
45
- request.body = options[:body]
46
- request.headers = default_headers(options[:headers])
47
- request.parameters = example.metadata[:parameters]
48
- build_path(request)
49
- @last_response = client.dispatch(request)
50
- end
51
-
52
- def params
53
- return {} unless example.metadata[:parameters]
54
- params = {}
55
- example.metadata[:parameters].each_key do |name|
56
- params[name] = send(name) if respond_to?(name)
57
- end
58
- params
39
+ request = example.metadata[:request].dup
40
+ request.body = options.delete(:body)
41
+ request.headers = default_headers(options.delete(:headers))
42
+ build_path(request, options)
43
+ @last_response = HTTPSpec.dispatch(request)
59
44
  end
60
45
 
61
46
  def status
@@ -73,9 +58,11 @@ module HTTPSpec
73
58
 
74
59
  private
75
60
 
76
- def build_path(request)
61
+ def build_path(request, options)
77
62
  request.path.gsub!(/:(\w+)/) do |match|
78
- if respond_to?($1)
63
+ if options.key?($1.to_sym)
64
+ options[$1.to_sym]
65
+ elsif respond_to?($1)
79
66
  send($1)
80
67
  else
81
68
  match
@@ -1,4 +1,9 @@
1
1
  module HTTPSpec
2
- Request = Struct.new(:method, :path, :body, :headers, :parameters)
2
+ Request = Struct.new(:method, :path, :body, :headers) do
3
+ def dup
4
+ Request.new(method, path.dup, body, headers)
5
+ end
6
+ end
7
+
3
8
  Response = Struct.new(:status, :body, :headers)
4
9
  end
data/lib/http_spec.rb ADDED
@@ -0,0 +1,9 @@
1
+ module HTTPSpec
2
+ class << self
3
+ attr_accessor :client
4
+
5
+ def dispatch(request)
6
+ client.dispatch(request)
7
+ end
8
+ end
9
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http_spec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-24 00:00:00.000000000 Z
12
+ date: 2012-08-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -91,6 +91,38 @@ dependencies:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: raddocs
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rake
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
94
126
  - !ruby/object:Gem::Dependency
95
127
  name: simplecov
96
128
  requirement: !ruby/object:Gem::Requirement
@@ -123,6 +155,38 @@ dependencies:
123
155
  - - ! '>='
124
156
  - !ruby/object:Gem::Version
125
157
  version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: capybara
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ - !ruby/object:Gem::Dependency
175
+ name: aruba
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ! '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
126
190
  description:
127
191
  email:
128
192
  executables: []
@@ -132,10 +196,13 @@ files:
132
196
  - lib/http_spec/clients/faraday.rb
133
197
  - lib/http_spec/clients/fdoc_proxy.rb
134
198
  - lib/http_spec/clients/rack.rb
199
+ - lib/http_spec/clients/raddocs_proxy.rb
135
200
  - lib/http_spec/clients/webmachine.rb
136
201
  - lib/http_spec/dsl/methods.rb
202
+ - lib/http_spec/dsl/parameters.rb
137
203
  - lib/http_spec/dsl/resource.rb
138
204
  - lib/http_spec/types.rb
205
+ - lib/http_spec.rb
139
206
  homepage: https://github.com/smartlogic/http_spec
140
207
  licenses: []
141
208
  post_install_message: