riot-gear 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore 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