bbq-core 0.3.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4a48e0d7e2b08e20b007adafe0ead84e77bb54cc68bd4c8cdf7e5d68a1ae1fde
4
+ data.tar.gz: d8a944e766fb21bc119d771d28fcdee6e27a393e78ae4fded7bd403b420e613f
5
+ SHA512:
6
+ metadata.gz: 69a88b57acf34e2ec33f347a86d82f8c45f275f2ed25852e4a313fa4196ba9f6fc2fab33758f9059b67fa7b318a18ba2efd87ef4cc88bbb7114df4a84a47f6a6
7
+ data.tar.gz: f90be21ff429c510175e37d08fa438734053b97260b9979bb04b53e2caf3bc8edcd17d4b2458cd4cb7e50be74ff7efcccba963e28b1553dc526c1d9afa29261c
@@ -0,0 +1,14 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ bin/*
6
+ tmp/*
7
+ test/dummy/db/*.sqlite3
8
+ test/dummy/log/*.log
9
+ test/dummy/tmp/
10
+ test/dummy/test/acceptance/*
11
+ test/dummy/spec/acceptance/*
12
+ test/dope/test/acceptance/*
13
+ test/dope/spec/acceptance/*
14
+ nbproject/
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
4
+ - 2.1.0
@@ -0,0 +1,47 @@
1
+ 0.2.1 / 2013-08-22
2
+ ==================
3
+
4
+ * bugfix: Bbq::TestClient propagates NoMethodErrors from the controller of
5
+ tested app instead of rising unsupported method errors.
6
+
7
+ 0.2.0 / 2013-01-06
8
+ ==================
9
+
10
+ * Dropped support for Ruby 1.8.7
11
+ * Capybara 2.0 support
12
+
13
+ 0.1.0 / 2013-01-06
14
+ ==================
15
+
16
+ * Extracted Rails' URL helpers inclusion to separate module
17
+ * Include only Capybara::Session::DSL_METHODS in TestUser, not the whole Capybara::DSL
18
+ * Added Capybara sessions pool
19
+ * Moved Test::User default options to separate method
20
+ * Added Test::Client for testing REST APIs
21
+ * Renamed bbq/test.rb to bbq/test_unit.rb. You may want to fix your test_helper.
22
+ * Moved require bbq/test_user to generated test_user.rb. You may want to update your existing test_user.rb.
23
+ * Fixed Capybara 'within' scope for RSpec flavour
24
+
25
+ 0.0.4 / 2011-10-19
26
+ ==================
27
+
28
+ * Make Bbq work with Capybara 1.0 and 1.1
29
+ * Rails is development dependency
30
+
31
+ 0.0.3 / 2011-07-14
32
+ ==================
33
+
34
+ * Added support and tests for Sinatra
35
+ * Added Bbq.app and Bbq.app=
36
+
37
+ 0.0.2 / 2011-07-01
38
+ ==================
39
+
40
+ * Extracted Bbq::TestUser::Eyes module
41
+ * Added :within option to TestUser methods
42
+ * Fix tests for ree and ruby187
43
+
44
+ 0.0.1 / 2011-04-20
45
+ ==================
46
+
47
+ * Bbq introduced to the wild world!
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "jruby-openssl", :platforms => :jruby
@@ -0,0 +1,20 @@
1
+ Copyright 2011 DRUG, Dolnośląska Grupa Użytkowników Ruby
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,318 @@
1
+ # BBQ
2
+
3
+ [![Build Status](https://secure.travis-ci.org/drugpl/bbq-core.png)](http://travis-ci.org/drugpl/bbq-core) [![Dependency Status](https://gemnasium.com/drugpl/bbq-core.png)](https://gemnasium.com/drugpl/bbq-core) [![Code Climate](https://codeclimate.com/github/drugpl/bbq-core.png)](https://codeclimate.com/github/drugpl/bbq-core) [![Gem Version](https://badge.fury.io/rb/bbq-core.png)](http://badge.fury.io/rb/bbq-core)
4
+
5
+ Object oriented acceptance testing using personas.
6
+
7
+ * Ruby (no Gherkin)
8
+ * Objects and methods instead of steps
9
+ * Test framework independent (RSpec and Test::Unit support)
10
+ * Thins based on Capybara.
11
+ * DCI (Data Context Interaction) for roles/personas
12
+ * Opinionated
13
+
14
+ ## Setup
15
+
16
+ First, add BBQ to your apps `Gemfile`:
17
+
18
+ ```ruby
19
+ gem "bbq", "0.2.1"
20
+ ```
21
+
22
+ Run install generator:
23
+
24
+ ```
25
+ bundle exec rails generate bbq:install
26
+ ```
27
+
28
+ Require BBQ in test/test_helper.rb (in case of Test::Unit):
29
+
30
+ ```ruby
31
+ require "bbq/test_unit"
32
+ ```
33
+
34
+ Require BBQ in spec/spec_helper.rb (in case of RSpec):
35
+
36
+ ```ruby
37
+ require "bbq/rspec"
38
+ ```
39
+
40
+ ## Feature generator
41
+
42
+ ```
43
+ bundle exec rails g bbq:test MyFeatureName
44
+ ```
45
+
46
+ ## Running features
47
+
48
+ For Test::Unit flavour:
49
+
50
+ ```
51
+ bundle exec rake test:acceptance
52
+ ```
53
+
54
+ For RSpec flavour:
55
+
56
+ ```
57
+ bundle exec rake spec:acceptance
58
+ ```
59
+
60
+ ## Examples
61
+
62
+ ### Roles and Devise integration
63
+
64
+ ```ruby
65
+ class TestUser < Bbq::TestUser
66
+ include Bbq::Devise
67
+
68
+ def update_ticket(summary, comment)
69
+ show_ticket(summary)
70
+ fill_in "Comment", :with => comment
71
+ click_on "Add update"
72
+ end
73
+
74
+ def open_application
75
+ visit '/'
76
+ end
77
+
78
+ module TicketReporter
79
+ def open_tickets_listing
80
+ open_application
81
+ click_link 'Tickets'
82
+ end
83
+
84
+ def open_ticket(summary, description)
85
+ open_tickets_listing
86
+ click_on "Open a new ticket"
87
+ fill_in "Summary", :with => summary
88
+ fill_in "Description", :with => description
89
+ click_on "Open ticket"
90
+ end
91
+
92
+ def show_ticket(summary)
93
+ open_tickets_listing
94
+ click_on summary
95
+ end
96
+ end
97
+
98
+ module TicketManager
99
+ def open_administration
100
+ visit '/admin'
101
+ end
102
+
103
+ def open_tickets_listing
104
+ open_administration
105
+ click_link 'Tickets'
106
+ end
107
+
108
+ def close_ticket(summary, comment = nil)
109
+ open_tickets_listing
110
+ click_on summary
111
+ fill_in "Comment", :with => comment if comment
112
+ click_on "Close ticket"
113
+ end
114
+
115
+ def show_ticket(summary)
116
+ open_tickets_listing
117
+ click_on summary
118
+ end
119
+ end
120
+ end
121
+ ```
122
+
123
+ ```ruby
124
+ class AdminTicketsTest < Bbq::TestCase
125
+ background do
126
+ admin = Factory(:admin)
127
+ @email, @password = admin.email, admin.password
128
+ end
129
+
130
+ scenario "admin can browse all user tickets" do
131
+ summaries = ["Forgot my password", "Page is not displayed correctly"]
132
+ descriptions = ["I lost my yellow note with password under the table!",
133
+ "My IE renders crap instead of crispy fonts!"]
134
+
135
+ alice = TestUser.new
136
+ alice.roles(:ticket_reporter)
137
+ alice.register_and_login
138
+ alice.open_ticket(summaries.first, descriptions.first)
139
+
140
+ bob = TestUser.new
141
+ bob.roles(:ticket_reporter)
142
+ bob.register_and_login
143
+ bob.open_ticket(summaries.second, descriptions.second)
144
+
145
+ charlie = TestUser.new(:email => @email, :password => @password)
146
+ charlie.login # charlie was already "registered" in factory as admin
147
+ charlie.roles(:ticket_manager)
148
+ charlie.open_tickets_listing
149
+ charlie.see!(*summaries)
150
+
151
+ charlie.click_on(summaries.second)
152
+ charlie.see!(summaries.second, descriptions.second)
153
+ charlie.not_see!(summaries.first, descriptions.first)
154
+ end
155
+ end
156
+ ```
157
+
158
+ ### RSpec integration
159
+
160
+ ```ruby
161
+ class TestUser < Bbq::TestUser
162
+ def email
163
+ @options[:email] || "buyer@example.com"
164
+ end
165
+
166
+ module Buyer
167
+ def ask_question(question)
168
+ fill_in "question", :with => question
169
+ fill_in "email", :with => email
170
+ click_on("Ask")
171
+ end
172
+
173
+ def go_to_page_and_open_widget(page_url, &block)
174
+ go_to_page(page_url)
175
+ open_widget &block
176
+ end
177
+
178
+ def go_to_page(page_url)
179
+ visit page_url
180
+ wait_until { page.find("iframe") }
181
+ end
182
+
183
+ def open_widget
184
+ within_widget do
185
+ page.find("#widget h3").click
186
+ yield if block_given?
187
+ end
188
+ end
189
+
190
+ ef within_widget(&block)
191
+ within_frame(widget_frame, &block)
192
+ end
193
+
194
+ def widget_frame
195
+ page.evaluate_script("document.getElementsByTagName('iframe')[0].id")
196
+ end
197
+ end
198
+ end
199
+ ```
200
+
201
+ ```ruby
202
+ feature "ask question widget" do
203
+ let(:user) {
204
+ user = TestUser.new(:driver => :webkit)
205
+ user.roles('buyer')
206
+ user
207
+ }
208
+
209
+ scenario "as a guest user, I should be able to ask a question" do
210
+ user.go_to_page_and_open_widget("/widget") do
211
+ user.ask_question "my question"
212
+ user.see!("Thanks!")
213
+ end
214
+ end
215
+ end
216
+ ```
217
+
218
+ ## Testing REST APIs
219
+
220
+ Bbq provides `Bbq::TestClient`, similar to `Bbq::TestUser`, but intended for testing APIs.
221
+ It's a thin wrapper around `Rack::Test` which allows you to send requests and run assertions
222
+ against responses.
223
+
224
+ ```ruby
225
+ class ApiTest < Bbq::TestCase
226
+ background do
227
+ headers = {'HTTP_ACCEPT' => 'application/json'}
228
+ @client = TestClient.new(:headers => headers)
229
+ end
230
+
231
+ scenario "admin can browse all user tickets" do
232
+ @client.get "/unicorn" do |response|
233
+ assert_equal 200, response.status
234
+ assert_equal "pink", response.body["unicorn"]["color"]
235
+ end
236
+ @client.post "/ponies", { :name => "Miracle" } do |response|
237
+ assert_equal 200, response.status
238
+ end
239
+ end
240
+ end
241
+ ```
242
+
243
+ ## Rails URL Helpers
244
+
245
+ Using url helpers from Rails in integration tests is not recommended.
246
+ Testing routes is part of integration test, so you should actually use only
247
+
248
+ ```ruby
249
+ visit '/'
250
+ ```
251
+
252
+ in your integration test. Use links and buttons in order to get to other pages in your app.
253
+
254
+ If you really need url helpers in your test user, just include them in your TestUser class:
255
+
256
+ ```ruby
257
+ require 'bbq/rails/routes'
258
+
259
+ class TestUser < Bbq::TestUser
260
+ include Bbq::Rails::Routes
261
+ end
262
+ ```
263
+ or just
264
+
265
+ ```ruby
266
+ class TestUser < Bbq::TestUser
267
+ include ::ActionDispatch::Routing::UrlFor
268
+ include ::Rails.application.routes.url_helpers
269
+ include ::ActionDispatch::Routing::RouteSet::MountedHelpers unless ::Rails.version < "3.1"
270
+ end
271
+ ```
272
+
273
+ ## Devise support
274
+
275
+ ```ruby
276
+ require "bbq/test_user"
277
+ require "bbq/devise"
278
+
279
+ class TestUser < Bbq::TestUser
280
+ include Bbq::Devise
281
+ end
282
+ ```
283
+
284
+ After that TestUser have *login*, *logout*, *register*, *register_and_login* methods.
285
+
286
+ ```ruby
287
+ test "user register with devise" do
288
+ user = TestUser.new # or TestUser.new(:email => "email@example.com", :password => "secret")
289
+ user.register_and_login
290
+ user.see!("Stuff after auth")
291
+ end
292
+ ```
293
+
294
+ ## Caveats
295
+
296
+ ### Timeout::Error
297
+
298
+ If you simulate multiple users in your tests and spawn multiple browsers with selenium it might
299
+ be a good idea to use Thin instead of Webrick to create application server.
300
+ We have experienced some problems with Webrick that lead to `Timeout::Error` exception
301
+ when user/browser that was inactive for some time (due to other users/browsers
302
+ activities) was requested to execute an action.
303
+
304
+ Capybara will use Thin instead of Webrick when it's available, so you only need to add Thin to you Gemfile:
305
+
306
+ ```ruby
307
+ # In test group if you want it to
308
+ # be used only in tests and not in your development mode
309
+ # ex. when running 'rails s'
310
+
311
+ gem 'thin', :require => false
312
+ ```
313
+
314
+ ## Additional information
315
+
316
+ * [2 problems with Cucumber](http://andrzejonsoftware.blogspot.com/2011/03/2-problems-with-cucumber.html)
317
+ * [Object oriented acceptance testing](http://andrzejonsoftware.blogspot.com/2011/04/object-oriented-acceptance-testing.html)
318
+
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ t.test_files = FileList['test/*_test.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ task default: :test
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "bbq/core/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "bbq-core"
7
+ s.version = Bbq::Core::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["DRUG - Dolnośląska Grupa Użytkowników Ruby"]
10
+ s.email = ["bbq@drug.org.pl"]
11
+ s.homepage = ""
12
+ s.description = %q{Objected oriented acceptance testing for Rails, using personas.}
13
+ s.summary = %q{Objected oriented acceptance testing for Rails, using personas.}
14
+
15
+ s.rubyforge_project = "bbq-core"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency "capybara", ">= 2.0"
23
+ s.add_dependency "activesupport", ">= 2.0"
24
+
25
+ s.add_development_dependency "rake"
26
+ s.add_development_dependency "rdoc", "~> 3.7"
27
+ s.add_development_dependency "minitest", "~> 5.0"
28
+ end
@@ -0,0 +1,7 @@
1
+ module Bbq
2
+ module Core
3
+ class << self
4
+ attr_accessor :app
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ require 'bbq/core/util'
2
+
3
+ module Bbq
4
+ module Core
5
+ module Roles
6
+ def roles(*names)
7
+ names.each do |name|
8
+ module_obj = Bbq::Core::Util.find_module(name, self)
9
+ self.extend(module_obj)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,64 @@
1
+ require 'bbq/core'
2
+
3
+ module Bbq
4
+ module Core
5
+ module Session
6
+ extend self
7
+
8
+ def next(options = {})
9
+ driver = options.delete(:driver)
10
+ pool = options.delete(:pool)
11
+
12
+ if pool
13
+ pool.next(driver)
14
+ else
15
+ create(driver)
16
+ end
17
+ end
18
+
19
+ def create(driver)
20
+ Capybara::Session.new(driver, Bbq::Core.app)
21
+ end
22
+
23
+ def pool
24
+ @pool ||= Pool.new
25
+ end
26
+
27
+ class Pool
28
+ attr_accessor :idle, :taken
29
+
30
+ def initialize
31
+ @idle = []
32
+ @taken = []
33
+ end
34
+
35
+ def next(driver)
36
+ take_idle(driver) || create(driver)
37
+ end
38
+
39
+ def release
40
+ taken.each(&:reset!)
41
+ idle.concat(taken)
42
+ taken.clear
43
+ end
44
+
45
+ private
46
+
47
+ def take_idle(driver)
48
+ idle.find { |s| s.mode == driver }.tap do |session|
49
+ if session
50
+ idle.delete(session)
51
+ taken.push(session)
52
+ end
53
+ end
54
+ end
55
+
56
+ def create(driver)
57
+ Bbq::Core::Session.create(driver).tap do |session|
58
+ taken.push(session)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,97 @@
1
+ require 'bbq/core/roles'
2
+
3
+ module Bbq
4
+ module Core
5
+ class TestClient
6
+ class UnsupportedMethodError < StandardError; end
7
+
8
+ include Bbq::Core::Roles
9
+
10
+ def initialize(options = {})
11
+ @options = options
12
+ end
13
+
14
+ HTTP_METHODS = %w(get post put delete head options patch)
15
+
16
+ HTTP_METHODS.each do |method|
17
+ class_eval <<-RUBY
18
+ def #{method}(path, params = {}, headers = {})
19
+ unless driver.respond_to? :#{method}
20
+ raise UnsupportedMethodError, "Your driver does not support #{method.upcase} method"
21
+ end
22
+
23
+ response = driver.#{method}(path, params, default_headers.merge(headers))
24
+ parsed_response = parse_response(response)
25
+ yield parsed_response if block_given?
26
+ parsed_response
27
+ end
28
+ RUBY
29
+ end
30
+
31
+ protected
32
+ def app
33
+ @options[:app] || Bbq::Core.app
34
+ end
35
+
36
+ def default_headers
37
+ @options[:headers] || {}
38
+ end
39
+
40
+ def driver
41
+ @driver ||= RackTest.new(app)
42
+ end
43
+
44
+ def parse_response(response)
45
+ case response.headers["Content-Type"]
46
+ when /^application\/(.*\+)?json/
47
+ response.extend(JsonBody)
48
+ when /^application\/(.*\+)?x-yaml/
49
+ response.extend(YamlBody)
50
+ else
51
+ response
52
+ end
53
+ end
54
+
55
+ class RackTest
56
+ attr_accessor :app
57
+
58
+ def initialize(app)
59
+ self.app = app
60
+ end
61
+
62
+ module ConvertHeaders
63
+ HTTP_METHODS.each do |method|
64
+ class_eval <<-RUBY
65
+ def #{method}(path, params = {}, headers = {})
66
+ super(path, params, to_env_headers(headers))
67
+ end
68
+ RUBY
69
+ end
70
+
71
+ def to_env_headers(http_headers)
72
+ http_headers.map do |k, v|
73
+ k = k.upcase.gsub("-", "_")
74
+ k = "HTTP_#{k}" unless ["CONTENT_TYPE", "CONTENT_LENGTH"].include?(k)
75
+ { k => v }
76
+ end.inject({}, :merge)
77
+ end
78
+ end
79
+
80
+ include Rack::Test::Methods
81
+ include ConvertHeaders
82
+ end
83
+
84
+ module JsonBody
85
+ def body
86
+ @parsed_body ||= super.empty?? super : JSON.parse(super)
87
+ end
88
+ end
89
+
90
+ module YamlBody
91
+ def body
92
+ @parsed_body ||= YAML.load(super)
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,33 @@
1
+ require 'bbq/core/session'
2
+ require 'bbq/core/roles'
3
+ require 'bbq/core/test_user/capybara_dsl'
4
+ require 'bbq/core/test_user/eyes'
5
+ require 'bbq/core/test_user/within'
6
+
7
+ module Bbq
8
+ module Core
9
+ class TestUser
10
+ include Bbq::Core::TestUser::CapybaraDsl
11
+ include Bbq::Core::TestUser::Eyes
12
+ include Bbq::Core::TestUser::Within
13
+ include Bbq::Core::Roles
14
+
15
+ attr_reader :options
16
+
17
+ def initialize(options = {})
18
+ @options = default_options.merge(options)
19
+ end
20
+
21
+ def default_options
22
+ {
23
+ :pool => Bbq::Core::Session.pool,
24
+ :driver => ::Capybara.default_driver
25
+ }
26
+ end
27
+
28
+ def page
29
+ @page ||= options[:session] || Bbq::Core::Session.next(:driver => options[:driver], :pool => options[:pool])
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ require 'capybara/dsl'
2
+
3
+ module Bbq
4
+ module Core
5
+ class TestUser
6
+ module CapybaraDsl
7
+ ::Capybara::Session::DSL_METHODS.each do |method|
8
+ class_eval <<-RUBY, __FILE__, __LINE__+1
9
+ def #{method}(*args, &block)
10
+ page.#{method}(*args, &block)
11
+ end
12
+ RUBY
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module Bbq
2
+ module Core
3
+ class TestUser
4
+ module Eyes
5
+ def see?(*args)
6
+ args.all? { |arg| has_content?(arg) }
7
+ end
8
+
9
+ def not_see?(*args)
10
+ args.all? { |arg| has_no_content?(arg) }
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ require 'active_support/core_ext/array/extract_options'
2
+
3
+ module Bbq
4
+ module Core
5
+ class TestUser
6
+ module Within
7
+ METHODS_USING_WITHIN = [
8
+ :see?, :not_see?,
9
+ :attach_file, :check, :choose, :click_link_or_button, :click_button,
10
+ :click_link, :click_on, :fill_in, :select, :uncheck, :unselect
11
+ ]
12
+
13
+ METHODS_USING_WITHIN.each do |method_name|
14
+ class_eval <<-RUBY
15
+ def #{method_name}(*args)
16
+ using_within(args) { super }
17
+ end
18
+ RUBY
19
+ end
20
+
21
+ def using_within(args)
22
+ options = args.extract_options!
23
+ locator = options.delete(:within)
24
+ args.push(options) unless options.empty?
25
+
26
+ if locator
27
+ within(locator) { yield }
28
+ else
29
+ yield
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+
3
+ module Bbq
4
+ module Core
5
+ class Util
6
+ def self.find_module(name, scope = nil)
7
+ namespace = case scope
8
+ when String, Symbol
9
+ "::#{scope.to_s.camelize}"
10
+ when Class
11
+ "::#{scope.name}"
12
+ when NilClass
13
+ nil
14
+ else
15
+ "::#{scope.class.name}"
16
+ end
17
+ "#{namespace}::#{name.to_s.camelize}".constantize
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ module Bbq
2
+ module Core
3
+ VERSION = '0.3.0'
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new("test:acceptance") do |t|
4
+ t.libs << 'test'
5
+ t.pattern = 'test/acceptance/**/*_test.rb'
6
+ t.verbose = false
7
+ end if File.exists?('test/acceptance')
8
+
9
+ begin
10
+ require 'rspec/core/rake_task'
11
+ RSpec::Core::RakeTask.new('spec:acceptance') do |spec|
12
+ spec.pattern = FileList['spec/acceptance/**/*_spec.rb']
13
+ end if File.exists?('spec/acceptance')
14
+ rescue LoadError
15
+ end
@@ -0,0 +1,44 @@
1
+ require 'test_helper'
2
+ require 'bbq/core/test_user'
3
+
4
+ class SessionPoolTest < Minitest::Test
5
+
6
+ def setup
7
+ Bbq::Core::Session.instance_variable_set(:@pool, nil)
8
+ end
9
+
10
+ def test_reuses_sessions
11
+ pool = Bbq::Core::Session::Pool.new
12
+ user1 = Bbq::Core::TestUser.new(:pool => pool).tap { |u| u.page }
13
+ pool.release
14
+ user2 = Bbq::Core::TestUser.new(:pool => pool).tap { |u| u.page }
15
+
16
+ assert_same user1.page, user2.page
17
+ end
18
+
19
+ def test_has_default_pool
20
+ user1 = Bbq::Core::TestUser.new.tap { |u| u.page }
21
+ Bbq::Core::Session::pool.release
22
+ user2 = Bbq::Core::TestUser.new.tap { |u| u.page }
23
+
24
+ assert_same user1.page, user2.page
25
+ end
26
+
27
+ def test_without_pool
28
+ user1 = Bbq::Core::TestUser.new(:pool => false).tap { |u| u.page }
29
+ Bbq::Core::Session::pool.release
30
+ user2 = Bbq::Core::TestUser.new(:pool => false).tap { |u| u.page }
31
+
32
+ refute_same user1.page, user2.page
33
+ end
34
+
35
+ def test_pool_returns_correct_driver
36
+ pool = Bbq::Core::Session::Pool.new
37
+ pool.next(:rack_test)
38
+ pool.next(:rack_test_the_other)
39
+ pool.release
40
+
41
+ assert_equal :rack_test, pool.next(:rack_test).mode
42
+ end
43
+
44
+ end
@@ -0,0 +1,30 @@
1
+ require 'test_helper'
2
+ require 'bbq/core/test_client'
3
+
4
+ class TestClientTest < Minitest::Test
5
+
6
+ def test_rack_test_to_env_headers_for_empty_hash
7
+ test_client = Bbq::Core::TestClient::RackTest.new(:app)
8
+ assert_equal({}, test_client.to_env_headers({}))
9
+ end
10
+
11
+ def test_rack_test_to_env_headers_for_content_type_or_content_length
12
+ test_client = Bbq::Core::TestClient::RackTest.new(:app)
13
+ result = test_client.to_env_headers({
14
+ "content-type" => "text/plain",
15
+ "content-length" => "40"
16
+ })
17
+ assert_includes(result.keys, "CONTENT_TYPE")
18
+ assert_includes(result.keys, "CONTENT_LENGTH")
19
+ end
20
+
21
+ def test_rack_test_to_env_headers_for_other_headers
22
+ test_client = Bbq::Core::TestClient::RackTest.new(:app)
23
+ result = test_client.to_env_headers({
24
+ "silly-header" => "silly-value"
25
+ })
26
+ assert_includes(result.keys, "HTTP_SILLY_HEADER")
27
+ end
28
+
29
+ end
30
+
@@ -0,0 +1,8 @@
1
+ require 'minitest/autorun'
2
+ require 'capybara'
3
+
4
+ Capybara.register_driver :rack_test_the_other do |app|
5
+ Capybara::RackTest::Driver.new(app)
6
+ end
7
+
8
+
@@ -0,0 +1,112 @@
1
+ require 'test_helper'
2
+ require 'bbq/core/test_user'
3
+
4
+
5
+ def text(output)
6
+ end
7
+
8
+ def html(output)
9
+ ->{ ['200', {'Content-Type' => 'text/html'}, [output]] }
10
+ end
11
+
12
+ TestApp = Rack::Builder.new do
13
+ map '/' do
14
+ run ->(env) { ['200', {'Content-Type' => 'text/plain'}, ['BBQ']] }
15
+ end
16
+
17
+ map '/miracle' do
18
+ run ->(env) { ['200', {'Content-Type' => 'text/plain'}, ['MIRACLE']] }
19
+ end
20
+
21
+ map '/ponycorns' do
22
+ run ->(env) { ['200', {'Content-Type' => 'text/html'}, [<<HTML
23
+ <ul id="unicorns">
24
+ <li>Pink</li>
25
+ </ul>
26
+ <ul id="ponies">
27
+ <li>Violet</li>
28
+ </ul>
29
+ <div id="new_pony">
30
+ <input type="text" name="color" value="" />
31
+ </div>
32
+ <a href="#">More ponycorns</a>
33
+ HTML
34
+ ]] }
35
+ end
36
+ end
37
+
38
+
39
+ class TestUser < Bbq::Core::TestUser
40
+ module Commenter
41
+ def comment
42
+ end
43
+ end
44
+
45
+ module VideoUploader
46
+ def upload
47
+ end
48
+ end
49
+
50
+ module CommentModerator
51
+ def moderate
52
+ end
53
+ end
54
+ end
55
+
56
+ class TestUserTest < Minitest::Test
57
+
58
+ def setup
59
+ Bbq::Core.app = TestApp
60
+ end
61
+
62
+ def teardown
63
+ Bbq::Core.app = nil
64
+ end
65
+
66
+ def test_capybara_dsl_methods
67
+ user = TestUser.new
68
+ Capybara::Session::DSL_METHODS.each do |m|
69
+ assert user.respond_to?(m)
70
+ end
71
+ end
72
+
73
+ def test_driver_option
74
+ user = TestUser.new(:driver => :rack_test_the_other)
75
+ assert_equal :rack_test_the_other, user.page.mode
76
+ end
77
+
78
+ def test_roles
79
+ user = TestUser.new
80
+ %w(comment upload moderate).each { |m| assert !user.respond_to?(m) }
81
+
82
+ user.roles(:commenter, "comment_moderator")
83
+ %w(comment moderate).each { |m| assert user.respond_to?(m) }
84
+ assert !user.respond_to?(:upload)
85
+
86
+ user.roles(:video_uploader)
87
+ %w(comment upload moderate).each { |m| assert user.respond_to?(m) }
88
+ end
89
+
90
+ def test_explicit_user_eyes
91
+ @user = TestUser.new
92
+ @user.visit "/miracle"
93
+ assert @user.not_see?("BBQ")
94
+ assert @user.see?("MIRACLE")
95
+ end
96
+
97
+ def test_user_eyes_within_scope
98
+ @user = TestUser.new
99
+ @user.visit "/ponycorns"
100
+ assert @user.see?("Pink", :within => "#unicorns")
101
+ assert ! @user.see?("Violet", :within => "#unicorns")
102
+ assert @user.not_see?("Violet", :within => "#unicorns")
103
+ assert ! @user.not_see?("Pink", :within => "#unicorns")
104
+
105
+ @user.fill_in "color", :with => "red", :within => "#new_pony"
106
+ assert_raises Capybara::ElementNotFound do
107
+ @user.fill_in "color", :with => "red", :within => "#new_unicorn"
108
+ end
109
+ @user.click_link "More ponycorns"
110
+ end
111
+
112
+ end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+ require 'bbq/core/util'
3
+
4
+ class User
5
+ module Commenter
6
+ end
7
+ end
8
+
9
+ module Commenter
10
+ end
11
+
12
+ class UtilTest < Minitest::Test
13
+
14
+ def test_find_module_in_object_namespace
15
+ assert_commenter(User.new, User::Commenter)
16
+ end
17
+
18
+ def test_find_module_in_class_namespace
19
+ assert_commenter(User, User::Commenter)
20
+ end
21
+
22
+ def test_find_module_in_string_namespace
23
+ assert_commenter("User", User::Commenter)
24
+ end
25
+
26
+ def test_find_global_module
27
+ assert_commenter(nil, ::Commenter)
28
+ end
29
+
30
+ def assert_commenter(namespace, result)
31
+ [:commenter, "commenter"].each do |name|
32
+ assert_equal Bbq::Core::Util.find_module(name, namespace), result
33
+ end
34
+ end
35
+
36
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bbq-core
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - DRUG - Dolnośląska Grupa Użytkowników Ruby
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-03-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capybara
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rdoc
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.7'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
83
+ description: Objected oriented acceptance testing for Rails, using personas.
84
+ email:
85
+ - bbq@drug.org.pl
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".travis.yml"
92
+ - CHANGELOG
93
+ - Gemfile
94
+ - MIT-LICENSE
95
+ - README.md
96
+ - Rakefile
97
+ - bbq-core.gemspec
98
+ - lib/bbq/core.rb
99
+ - lib/bbq/core/roles.rb
100
+ - lib/bbq/core/session.rb
101
+ - lib/bbq/core/test_client.rb
102
+ - lib/bbq/core/test_user.rb
103
+ - lib/bbq/core/test_user/capybara_dsl.rb
104
+ - lib/bbq/core/test_user/eyes.rb
105
+ - lib/bbq/core/test_user/within.rb
106
+ - lib/bbq/core/util.rb
107
+ - lib/bbq/core/version.rb
108
+ - lib/tasks/bbq.rake
109
+ - test/session_pool_test.rb
110
+ - test/test_client_test.rb
111
+ - test/test_helper.rb
112
+ - test/test_user_test.rb
113
+ - test/util_test.rb
114
+ homepage: ''
115
+ licenses: []
116
+ metadata: {}
117
+ post_install_message:
118
+ rdoc_options: []
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ requirements: []
132
+ rubygems_version: 3.0.3
133
+ signing_key:
134
+ specification_version: 4
135
+ summary: Objected oriented acceptance testing for Rails, using personas.
136
+ test_files:
137
+ - test/session_pool_test.rb
138
+ - test/test_client_test.rb
139
+ - test/test_helper.rb
140
+ - test/test_user_test.rb
141
+ - test/util_test.rb