riot-gear 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -7,4 +7,5 @@ pkg/*
7
7
  .watchr
8
8
  .yardoc
9
9
  Gemfile.lock
10
+ *.gem
10
11
 
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ before_install:
3
+ - gem update --system
4
+ - gem --version
5
+ bundler_args: --without development
6
+ rvm:
7
+ - 1.9.3
8
+ - 2.0.0
9
+
data/CHANGELOG CHANGED
@@ -1,5 +1,27 @@
1
1
  # @markup markdown
2
2
 
3
+ # 0.0.10
4
+
5
+ * Defines a new setup block called `once`. Useful for running a single block before assertions, but only inside the context it was defined in [jaknowlden]
6
+
7
+ ```ruby
8
+ context ThingsMaker do
9
+ once do
10
+ topic.post "/things/make", :query => { :name => "Jacques" }
11
+ end
12
+
13
+ format :json
14
+ get "/things/1"
15
+
16
+ asserts_json("name").equals("Jacques")
17
+
18
+ context "makes no more things" do
19
+ get "/things/2"
20
+ asserts_status(404) # becuase the post didn't run again ... see ... yeah
21
+ end
22
+ end
23
+ ```
24
+
3
25
  # 0.0.9
4
26
 
5
27
  * get, post, put, delete can have responses saved for use in other requests within the same (or nested) context [jaknowlden]
data/Gemfile CHANGED
@@ -4,6 +4,6 @@ gemspec
4
4
 
5
5
  group "test" do
6
6
  gem "rake", ">=0.8.7"
7
- gem "webmock", ">=1.6.1"
7
+ gem "webmock", ">=1.15.0"
8
8
  end
9
9
 
@@ -0,0 +1,42 @@
1
+ class Riot::Gear::OnceRunnable < Riot::RunnableBlock
2
+ def initialize(description, &definition)
3
+ super("[once] #{description}", &definition)
4
+ @ran = false
5
+ end
6
+
7
+ # Applies the provided +&definition+ to the +situation+. But, it only
8
+ # does so once.
9
+ #
10
+ # @param [Riot::Situation] situation An instance of a {Riot::Situation}
11
+ # @return [Array<Symbol>]
12
+ def run(situation)
13
+ if @ran
14
+ [:once_ignored]
15
+ else
16
+ @ran = true
17
+ situation.evaluate(&definition)
18
+ [:once]
19
+ end
20
+ end
21
+ end
22
+
23
+ module Riot::Gear::OnceContextHelper
24
+ # A setup helper that will only run once and only in the context it
25
+ # was defined in. This will not be run in any of its sub-contexts
26
+ # and it will run before any assertions ... the same as any other
27
+ # setup block.
28
+ #
29
+ # once "doing this one thing" do
30
+ # topic.post "/user/things", :query => {"name" => "x"}
31
+ # end
32
+ #
33
+ # @param [String] description A description of what the block is for
34
+ # @param [lambda] &definition The block that will be executed once
35
+ # @return [Riot::Gear::OnceRunnable]
36
+ def once(description="", &definition)
37
+ @setups << Riot::Gear::OnceRunnable.new(description, &definition)
38
+ end
39
+ end
40
+
41
+ Riot::Context.instance_eval { include Riot::Gear::OnceContextHelper }
42
+
@@ -1,3 +1,4 @@
1
+ require 'riot/gear/context/once'
1
2
  require 'riot/gear/context/persist_cookie'
2
3
  require 'riot/gear/context/asserts_status'
3
4
  require 'riot/gear/context/asserts_header'
@@ -1,173 +1,172 @@
1
1
  require 'httparty'
2
2
 
3
- module Riot
4
- module Gear
5
- # Here we prepare a {Riot::Context} to have HTTParty bound to it. Basically, this means that you can
6
- # use HTTParty within a context the same way you would inside any class or you would normally use it in.
7
- # Anything you can do with HTTParty, you can do within a context ... and then you can test it :)
8
- #
9
- # Great pains are made to ensure that the HTTParty setup bound to one context does not interfere setup
10
- # bound to another context.
11
- class RiotPartyMiddleware < ::Riot::ContextMiddleware
12
- register
3
+ # Here we prepare a {Riot::Context} to have HTTParty bound to it. Basically, this means that you can
4
+ # use HTTParty within a context the same way you would inside any class or you would normally use it in.
5
+ # Anything you can do with HTTParty, you can do within a context ... and then you can test it :)
6
+ #
7
+ # Great pains are made to ensure that the HTTParty setup bound to one context does not interfere setup
8
+ # bound to another context.
9
+ class Riot::Gear::RiotPartyMiddleware < ::Riot::ContextMiddleware
10
+ register
13
11
 
14
- # Prepares the context for HTTParty support.
15
- #
16
- # @param [Riot::Context] context the context to prepare
17
- def call(context)
18
- setup_faux_class(context)
19
- setup_helpers(context)
20
- proxy_action_methods(context)
21
- proxy_httparty_hookups(context)
22
- middleware.call(context)
23
- end
24
-
25
- private
12
+ # Prepares the context for HTTParty support.
13
+ #
14
+ # @param [Riot::Context] context the context to prepare
15
+ def call(context)
16
+ setup_faux_class(context)
17
+ setup_helpers(context)
18
+ proxy_action_methods(context)
19
+ proxy_httparty_hookups(context)
20
+ middleware.call(context)
21
+ end
26
22
 
27
- # Only cluttering anonymous classes with HTTParty stuff. Keeps each context safe from collision ... in
28
- # theory.
29
- #
30
- # @param [Riot::Context] context the context to create the setup for
31
- # @todo Fix this so that settings like +base_uri+ can be inherited
32
- def setup_faux_class(context)
33
- context.setup(true) do
34
- @saved_responses = {}
23
+ private
35
24
 
36
- Class.new do
37
- include HTTParty
38
- # debug_output $stderr
39
- end
40
- end
25
+ # Only cluttering anonymous classes with HTTParty stuff. Keeps each context safe from collision ... in
26
+ # theory.
27
+ #
28
+ # @param [Riot::Context] context the context to create the setup for
29
+ # @todo Fix this so that settings like +base_uri+ can be inherited
30
+ def setup_faux_class(context)
31
+ context.setup(true) do
32
+ if topic
33
+ topic
34
+ else
35
+ @saved_responses = {}
36
+ Class.new { include HTTParty }
37
+ end
38
+ end
41
39
 
42
- context.helper(:response) do |name=nil|
43
- @saved_responses[name] || @smoke_response
44
- end
45
- end # setup_faux_class
40
+ context.helper(:response) do |name=nil|
41
+ @saved_responses[name] || @smoke_response
42
+ end
43
+ end # setup_faux_class
46
44
 
47
- # Returns the list of methods that do something; like make a network call.
48
- #
49
- # @return [Array<Symbol>]
50
- def actionable_methods; [:get, :post, :put, :delete, :head]; end
45
+ # Returns the list of methods that do something; like make a network call.
46
+ #
47
+ # @return [Array<Symbol>]
48
+ def actionable_methods; [:get, :post, :put, :delete, :head]; end
51
49
 
52
- # Returns the list of methods that configure actionable HTTParty methods. The {HTTParty.options} and
53
- # {HTTParty.default_options} methods are explicitly excluded from this list
54
- #
55
- # @return [Array<Symbol>]
56
- def proxiable_methods
57
- methods = HTTParty::ClassMethods.instance_methods.map { |m| m.to_s.to_sym }
58
- methods - actionable_methods - [:options, :default_options]
59
- end
50
+ # Returns the list of methods that configure actionable HTTParty methods. The {HTTParty.options} and
51
+ # {HTTParty.default_options} methods are explicitly excluded from this list
52
+ #
53
+ # @return [Array<Symbol>]
54
+ def proxiable_methods
55
+ methods = HTTParty::ClassMethods.instance_methods.map { |m| m.to_s.to_sym }
56
+ methods - actionable_methods - [:options, :default_options]
57
+ end
60
58
 
61
- # Bind the set of actionable methods to a given context.
62
- #
63
- # Basically, we're just passing standard HTTParty setup methods onto situation via hookups. These
64
- # hookups - so long as the topic hasn't changed yet - are bound to an anonymous class that has
65
- # HTTParty included to it. Meaning, this is how you call get, post, put, delete from within a
66
- # test.
67
- #
68
- # There are couple of different forms for these actions. As you would expect, there's:
69
- #
70
- # get "/path", :query => {...}, ...
71
- #
72
- # But you can also record the response for use later in the test:
73
- #
74
- # post(:new_thing) do
75
- # { :path => "/things", :body => ... }
76
- # end
77
- #
78
- # get do # this response will be used for assertions since it's last
79
- # { :path => "/things/#{response(:new_thing).id}/settings" }
80
- # end
81
- #
82
- # @param [Riot::Context] context the context to add the helper to
83
- def proxy_action_methods(context)
84
- context_eigen = (class << context; self; end)
85
- actionable_methods.each do |method_name|
86
- context_eigen.__send__(:define_method, method_name) do |*args, &settings_block|
87
- hookup do
88
- if settings_block
89
- name = args.first
90
- options = instance_eval(&settings_block)
91
- path = options.delete(:path) || "/"
92
- else
93
- name = nil
94
- path, options = *args
95
- end
96
- result = topic.__send__(method_name, path, options || {})
97
- @saved_responses[name] = result
98
- @smoke_response = result # TODO remove this after it's certain no usages in the wild
99
- end
59
+ # Bind the set of actionable methods to a given context.
60
+ #
61
+ # Basically, we're just passing standard HTTParty setup methods onto situation via hookups. These
62
+ # hookups - so long as the topic hasn't changed yet - are bound to an anonymous class that has
63
+ # HTTParty included to it. Meaning, this is how you call get, post, put, delete from within a
64
+ # test.
65
+ #
66
+ # There are couple of different forms for these actions. As you would expect, there's:
67
+ #
68
+ # get "/path", :query => {...}, ...
69
+ #
70
+ # But you can also record the response for use later in the test:
71
+ #
72
+ # post(:new_thing) do
73
+ # { :path => "/things", :body => ... }
74
+ # end
75
+ #
76
+ # get do # this response will be used for assertions since it's last
77
+ # { :path => "/things/#{response(:new_thing).id}/settings" }
78
+ # end
79
+ #
80
+ # @param [Riot::Context] context the context to add the helper to
81
+ def proxy_action_methods(context)
82
+ context_eigen = (class << context; self; end)
83
+ actionable_methods.each do |method_name|
84
+ context_eigen.__send__(:define_method, method_name) do |*args, &settings_block|
85
+ hookup do
86
+ if settings_block
87
+ name = args.first
88
+ options = instance_eval(&settings_block)
89
+ path = options.delete(:path) || "/"
90
+ else
91
+ name = nil
92
+ path, options = *args
100
93
  end
101
- end # methods.each
94
+ #debug_start = Time.now
95
+ result = topic.__send__(method_name, path, options || {})
96
+ #puts "TIME #{(Time.now - debug_start) * 1000.0}ms #{topic.base_uri}#{path}"
97
+ @saved_responses[name] = result
98
+ @smoke_response = result # TODO remove this after it's certain no usages in the wild
99
+ end
102
100
  end
101
+ end # methods.each
102
+ end
103
103
 
104
- # Bind the set of proxiable (non-action) methods to a given context.
105
- #
106
- # @param [Riot::Context] context the context to add the helper to
107
- def proxy_httparty_hookups(context)
108
- context_eigen = (class << context; self; end)
109
- proxiable_methods.each do |method_name|
110
- context_eigen.__send__(:define_method, method_name) do |*args|
111
- hookup { topic.__send__(method_name, *args) }
112
- end
113
- end # methods.each
104
+ # Bind the set of proxiable (non-action) methods to a given context.
105
+ #
106
+ # @param [Riot::Context] context the context to add the helper to
107
+ def proxy_httparty_hookups(context)
108
+ context_eigen = (class << context; self; end)
109
+ proxiable_methods.each do |method_name|
110
+ context_eigen.__send__(:define_method, method_name) do |*args|
111
+ hookup { topic.__send__(method_name, *args) }
114
112
  end
113
+ end # methods.each
114
+ end
115
115
 
116
- #
117
- # Helpful helpers
116
+ #
117
+ # Helpful helpers
118
118
 
119
- def setup_helpers(context)
120
- helper_json_path(context)
121
- helper_cookie_value(context)
122
- end
119
+ def setup_helpers(context)
120
+ helper_json_path(context)
121
+ helper_cookie_value(context)
122
+ end
123
123
 
124
- # Maps a JSON string to a Hash tree. For instance, give this hash:
125
- #
126
- # json_object = {"a" => {"b" => {"c" => {"d" => "foo"}}}}
127
- #
128
- # You could retrieve the value of 'd' via JSON notation in any of the following ways:
129
- #
130
- # json_path(json_object, "a.b.c.d")
131
- # => "foo"
132
- # json_path(json_object, "a['b'].c['d']")
133
- # => "foo"
134
- #
135
- # You can even work with array indexes
136
- #
137
- # json_object = {"a" => {"b" => "c" => ["foo", {"d" => "bar"}]}}
138
- # json_path(json_object, "a[b].c[1].d")
139
- # => "bar"
140
- #
141
- # @param [Riot::Context] context the context to add the helper to
142
- def helper_json_path(context)
143
- context.helper(:json_path) do |dictionary, path|
144
- return nil if path.to_s.empty?
145
- path.scan(/[^\[\].'"]+/).inject(dictionary) do |dict,key|
146
- dict[key =~ /^\d+$/ ? key.to_i : key.strip]
147
- end
148
- end
124
+ # Maps a JSON string to a Hash tree. For instance, give this hash:
125
+ #
126
+ # json_object = {"a" => {"b" => {"c" => {"d" => "foo"}}}}
127
+ #
128
+ # You could retrieve the value of 'd' via JSON notation in any of the following ways:
129
+ #
130
+ # json_path(json_object, "a.b.c.d")
131
+ # => "foo"
132
+ # json_path(json_object, "a['b'].c['d']")
133
+ # => "foo"
134
+ #
135
+ # You can even work with array indexes
136
+ #
137
+ # json_object = {"a" => {"b" => "c" => ["foo", {"d" => "bar"}]}}
138
+ # json_path(json_object, "a[b].c[1].d")
139
+ # => "bar"
140
+ #
141
+ # @param [Riot::Context] context the context to add the helper to
142
+ def helper_json_path(context)
143
+ context.helper(:json_path) do |dictionary, path|
144
+ return nil if path.to_s.empty?
145
+ path.scan(/[^\[\].'"]+/).inject(dictionary) do |dict,key|
146
+ dict[key =~ /^\d+$/ ? key.to_i : key.strip]
149
147
  end
148
+ end
149
+ end
150
150
 
151
- # Splits up the cookies found in the Set-Cookie header. I'm sure I could use HTTParty for this somehow,
152
- # but this seemed just as straightforward. You will get back a hash of the
153
- # {cookie-name => cookie-bits} pairs
154
- #
155
- # {
156
- # "session_cookie" => {"value => "fooberries", "path" => "/", ...},
157
- # "stupid_marketing_tricks" => {"value" => "personal-information", ...},
158
- # ...
159
- # }
160
- #
161
- # @param [Riot::Context] context the context to add the helper to
162
- def helper_cookie_value(context)
163
- context.helper(:cookie_values) do
164
- response.header["set-cookie"].split("\n").inject({}) do |jar, cookie_str|
165
- (name, value), *bits = cookie_str.split(/; ?/).map { |bit| bit.split('=') }
166
- jar.merge!(name => bits.inject({"value" => value}) { |h, (k,v)| h.merge!(k => v) })
167
- end
168
- end
151
+ # Splits up the cookies found in the Set-Cookie header. I'm sure I could use HTTParty for this somehow,
152
+ # but this seemed just as straightforward. You will get back a hash of the
153
+ # {cookie-name => cookie-bits} pairs
154
+ #
155
+ # {
156
+ # "session_cookie" => {"value => "fooberries", "path" => "/", ...},
157
+ # "stupid_marketing_tricks" => {"value" => "personal-information", ...},
158
+ # ...
159
+ # }
160
+ #
161
+ # @param [Riot::Context] context the context to add the helper to
162
+ def helper_cookie_value(context)
163
+ context.helper(:cookie_values) do
164
+ response.header["set-cookie"].split("\n").inject({}) do |jar, cookie_str|
165
+ (name, value), *bits = cookie_str.split(/; ?/).map { |bit| bit.split('=') }
166
+ jar.merge!(name => bits.inject({"value" => value}) { |h, (k,v)| h.merge!(k => v) })
169
167
  end
168
+ end
169
+ end
170
+
171
+ end # Riot::Gear::RiotPartyMiddleware
170
172
 
171
- end # Middleware
172
- end # Gear
173
- end # Riot
@@ -1 +1,2 @@
1
- require 'riot/gear/middleware/riotparty'
1
+ require 'riot/gear/middleware/riotparty'
2
+
@@ -1,6 +1,6 @@
1
1
  module Riot
2
2
  module Gear
3
- VERSION = "0.0.9"
3
+ VERSION = "0.0.10"
4
4
  end
5
5
  end
6
6
 
data/lib/riot/gear.rb CHANGED
@@ -1,3 +1,8 @@
1
1
  require 'riot'
2
+
3
+ module Riot
4
+ module Gear; end
5
+ end
6
+
2
7
  require 'riot/gear/context'
3
8
  require 'riot/gear/middleware'
data/riot-gear.gemspec CHANGED
@@ -13,9 +13,9 @@ Gem::Specification.new do |s|
13
13
  s.files = `git ls-files`.split("\n")
14
14
  s.homepage = %q{http://github.com/thumblemonks/riot-gear}
15
15
  s.require_paths = ["lib"]
16
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.test_files = `git ls-files -- test/*`.split("\n")
17
17
 
18
- s.add_dependency 'riot', '>=0.12.5'
19
- s.add_dependency 'httparty', '>=0.6.0'
18
+ s.add_dependency 'riot', '>=0.12.6'
19
+ s.add_dependency 'httparty', '>=0.12.0'
20
20
  end
21
21
 
@@ -0,0 +1,21 @@
1
+ require 'teststrap'
2
+
3
+ context "[Context] A once block:" do
4
+ once do
5
+ @instance_var_x = "foo"
6
+ end
7
+
8
+ asserts("var x defined in same context as once block") { @instance_var_x }.equals("foo")
9
+
10
+ context "inner-context A" do
11
+ asserts("var x defined in out context") { @instance_var_x }.nil
12
+ asserts("var y defined in once block from this context") { @instance_var_y }.equals("bar")
13
+
14
+ # defining this below the asserts just for fun, to make sure it
15
+ # is eval'ed before the asserts are run
16
+ once do
17
+ @instance_var_y = "bar"
18
+ end
19
+ end
20
+ end
21
+
@@ -74,10 +74,13 @@ context "A Riot Gear context" do
74
74
  end.raises(HTTParty::UnsupportedFormat, "':json' Must be one of: nothing")
75
75
 
76
76
  context "with a custom parser that supports a provided format" do
77
- parser(OpenStruct.new(:supports_format? => true))
77
+ HappyPartyParser = Class.new do
78
+ def supports_format?(fmt) true; end
79
+ end
78
80
 
81
+ parser(HappyPartyParser.new)
79
82
  setup { topic.default_options[:parser] }
80
- asserts_topic.kind_of(OpenStruct)
83
+ asserts_topic.kind_of(HappyPartyParser)
81
84
  end # with a custom parser that supports a provided format
82
85
 
83
86
  default_timeout 100000
data/test/teststrap.rb CHANGED
@@ -3,6 +3,7 @@ require 'pathname'
3
3
  $:.unshift((Pathname(__FILE__).dirname + ".." + "lib").to_s)
4
4
 
5
5
  require 'rubygems'
6
+ require 'bundler/setup'
6
7
  require 'json'
7
8
  require 'riot'
8
9
  require 'webmock'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riot-gear
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
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: 2013-10-17 00:00:00.000000000 Z
12
+ date: 2013-10-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: riot
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 0.12.5
21
+ version: 0.12.6
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
- version: 0.12.5
29
+ version: 0.12.6
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: httparty
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -34,7 +34,7 @@ dependencies:
34
34
  requirements:
35
35
  - - ! '>='
36
36
  - !ruby/object:Gem::Version
37
- version: 0.6.0
37
+ version: 0.12.0
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +42,7 @@ dependencies:
42
42
  requirements:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
- version: 0.6.0
45
+ version: 0.12.0
46
46
  description: Riot + HTTParty smoke testing framework. You'd use it for integration
47
47
  testing with real HTTP requests and responses
48
48
  email: gus@gusg.us
@@ -51,6 +51,7 @@ extensions: []
51
51
  extra_rdoc_files: []
52
52
  files:
53
53
  - .gitignore
54
+ - .travis.yml
54
55
  - .yardopts
55
56
  - CHANGELOG
56
57
  - Gemfile
@@ -62,6 +63,7 @@ files:
62
63
  - lib/riot/gear/context/asserts_header.rb
63
64
  - lib/riot/gear/context/asserts_json.rb
64
65
  - lib/riot/gear/context/asserts_status.rb
66
+ - lib/riot/gear/context/once.rb
65
67
  - lib/riot/gear/context/persist_cookie.rb
66
68
  - lib/riot/gear/middleware.rb
67
69
  - lib/riot/gear/middleware/riotparty.rb
@@ -74,6 +76,7 @@ files:
74
76
  - test/assertions/asserts_json_test.rb
75
77
  - test/helpers/cookie_values_test.rb
76
78
  - test/helpers/json_path_test.rb
79
+ - test/once_block_test.rb
77
80
  - test/riotparty_proxy_methods_test.rb
78
81
  - test/setting_up_gear_context_test.rb
79
82
  - test/teststrap.rb
@@ -109,6 +112,7 @@ test_files:
109
112
  - test/assertions/asserts_json_test.rb
110
113
  - test/helpers/cookie_values_test.rb
111
114
  - test/helpers/json_path_test.rb
115
+ - test/once_block_test.rb
112
116
  - test/riotparty_proxy_methods_test.rb
113
117
  - test/setting_up_gear_context_test.rb
114
118
  - test/teststrap.rb