dressing 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in dressing.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Eric J. Holmes
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,42 @@
1
+ # Dressing
2
+
3
+ > A lighter weight alternative to sauce.
4
+
5
+ Dressing is a Ruby gem for running [Capybara](https://github.com/jnicklas/capybara) scenarios with [Sauce Labs](https://saucelabs.com).
6
+ It's an alternative to the official `sauce` gem, which is clunky, bloated and difficult to use.
7
+
8
+ ## Usage
9
+
10
+ ### RSpec + Capybara
11
+
12
+ ```ruby
13
+ require 'dressing/rspec'
14
+
15
+ RSpec.configure do |config|
16
+ config.include Capybara::DSL
17
+ config.include Dressing::RSpec
18
+ end
19
+ ```
20
+
21
+ That's it, you're done. Each test will be run in it's own session on Sauce Labs and you'll be able to see whether
22
+ the test failed or passed in the Sauce Labs UI.
23
+
24
+ ## Configuration
25
+
26
+ ```ruby
27
+ Dressing.configure do |config|
28
+ config.browser = 'Chrome'
29
+ config.os = 'Windows 7'
30
+ config.version = 27
31
+
32
+ config.tunnel_identifier = ENV['TRAVIS_JOB_NUMBER']
33
+ end
34
+ ```
35
+
36
+ ## Contributing
37
+
38
+ 1. Fork it
39
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
40
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
41
+ 4. Push to the branch (`git push origin my-new-feature`)
42
+ 5. Create new Pull Request
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ task :default => [:spec]
5
+
6
+ require 'rspec/core/rake_task'
7
+ desc "Run specs"
8
+ RSpec::Core::RakeTask.new do |t|
9
+ t.pattern = 'spec/**/*_spec.rb'
10
+ end
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+
3
+
4
+ # Wait for Connect to be ready before exiting
5
+ while [ ! -f $SAUCE_CONNECT_READY_FILE ]; do
6
+ sleep .5
7
+ done
@@ -0,0 +1,46 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ # Setup and start Sauce Connect for your TravisCI build
6
+ # This script requires your .travis.yml to include the following two private env variables:
7
+ # SAUCE_USERNAME
8
+ # SAUCE_ACCESS_KEY
9
+ # Follow the steps at https://saucelabs.com/opensource/travis to set that up.
10
+ #
11
+ # Curl and run this script as part of your .travis.yml before_script section:
12
+ # before_script:
13
+ # - curl https://gist.github.com/santiycr/5139565/raw/sauce_connect_setup.sh | bash
14
+
15
+ CONNECT_URL="http://saucelabs.com/downloads/Sauce-Connect-latest.zip"
16
+ CONNECT_DIR="/tmp/sauce-connect-$RANDOM"
17
+ CONNECT_DOWNLOAD="Sauce_Connect.zip"
18
+
19
+ CONNECT_LOG="$LOGS_DIR/sauce-connect"
20
+ CONNECT_STDOUT="$LOGS_DIR/sauce-connect.stdout"
21
+ CONNECT_STDERR="$LOGS_DIR/sauce-connect.stderr"
22
+
23
+ # Get Connect and start it
24
+ mkdir -p $CONNECT_DIR
25
+ cd $CONNECT_DIR
26
+ curl $CONNECT_URL -o $CONNECT_DOWNLOAD 2> /dev/null 1> /dev/null
27
+ unzip $CONNECT_DOWNLOAD > /dev/null
28
+ rm $CONNECT_DOWNLOAD
29
+
30
+ ARGS=""
31
+
32
+ # Set tunnel-id only on Travis, to make local testing easier.
33
+ if [ ! -z "$TRAVIS_JOB_NUMBER" ]; then
34
+ ARGS="$ARGS --tunnel-identifier $TRAVIS_JOB_NUMBER"
35
+ fi
36
+ if [ ! -z "$SAUCE_CONNECT_READY_FILE" ]; then
37
+ ARGS="$ARGS --readyfile $SAUCE_CONNECT_READY_FILE"
38
+ fi
39
+
40
+
41
+ echo "Starting Sauce Connect in the background, logging into:"
42
+ echo " $CONNECT_LOG"
43
+ echo " $CONNECT_STDOUT"
44
+ echo " $CONNECT_STDERR"
45
+ java -jar Sauce-Connect.jar $ARGS $SAUCE_USERNAME $SAUCE_ACCESS_KEY \
46
+ --logfile $CONNECT_LOG 2> $CONNECT_STDERR 1> $CONNECT_STDOUT &
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dressing/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'dressing'
8
+ spec.version = Dressing::VERSION
9
+ spec.authors = ['Eric J. Holmes']
10
+ spec.email = ['eric@ejholmes.net']
11
+ spec.description = %q{A Capybara driver for Sauce Labs}
12
+ spec.summary = %q{A Capybara driver for Sauce Labs}
13
+ spec.homepage = 'https://github.com/ejholmes/dressing'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_dependency 'selenium-webdriver'
21
+ spec.add_dependency 'sauce_whisk'
22
+ spec.add_dependency 'net-http-persistent'
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.3'
25
+ spec.add_development_dependency 'rspec'
26
+ spec.add_development_dependency 'capybara'
27
+ spec.add_development_dependency 'rake'
28
+ end
@@ -0,0 +1,61 @@
1
+ require 'selenium/webdriver'
2
+ require 'selenium/webdriver/remote/http/persistent'
3
+
4
+ require 'dressing/version'
5
+
6
+ module Dressing
7
+ autoload :Configuration, 'dressing/configuration'
8
+ autoload :RSpec, 'dressing/rspec'
9
+
10
+ module Runner
11
+ autoload :Base, 'dressing/runner/base'
12
+ autoload :RSpec, 'dressing/runner/rspec'
13
+ end
14
+
15
+ module Capabilities
16
+ autoload :Base, 'dressing/capabilities/base'
17
+ autoload :RSpec, 'dressing/capabilities/rspec'
18
+ end
19
+
20
+ module Capybara
21
+ autoload :Driver, 'dressing/capybara/driver'
22
+ autoload :Session, 'dressing/capybara/session'
23
+ end
24
+
25
+ class << self
26
+ attr_accessor :current_session
27
+
28
+ def current_session
29
+ @current_session ||= ::Capybara.current_session
30
+ end
31
+
32
+ def using_driver(driver)
33
+ old_session = current_session
34
+ Dressing.current_session = Capybara::Session.new driver
35
+ yield
36
+ ensure
37
+ driver.quit
38
+ Dressing.current_session = old_session
39
+ end
40
+
41
+ def app
42
+ ::Capybara.app
43
+ end
44
+
45
+ def http_client
46
+ @http_client ||= begin
47
+ client = Selenium::WebDriver::Remote::Http::Persistent.new
48
+ client.timeout = configuration.http_timeout
49
+ client
50
+ end
51
+ end
52
+
53
+ def configuration
54
+ @configuration ||= Configuration.new
55
+ end
56
+
57
+ def configure
58
+ yield configuration
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,26 @@
1
+ module Dressing
2
+ module Capabilities
3
+ class Base
4
+ attr_reader :example
5
+
6
+ def initialize(example)
7
+ @example = example
8
+ end
9
+
10
+ def to_h
11
+ { 'job-name' => job_name }.merge(configuration.to_capabilities)
12
+ end
13
+
14
+ def job_name
15
+ raise NotImplementedError
16
+ end
17
+
18
+ private
19
+
20
+ def configuration
21
+ Dressing.configuration
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ module Dressing
2
+ module Capabilities
3
+ class RSpec < Base
4
+
5
+ def job_name
6
+ metadata[:full_description]
7
+ end
8
+
9
+ private
10
+
11
+ def metadata
12
+ example.metadata
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module Dressing
2
+ module Capybara
3
+ class Driver < ::Capybara::Selenium::Driver
4
+ def initialize(app, options = {})
5
+ options.merge!(
6
+ url: Dressing.configuration.remote_url,
7
+ http_client: Dressing.http_client
8
+ )
9
+ super
10
+ end
11
+
12
+ def browser
13
+ @browser ||= Selenium::WebDriver.for(:remote, options.reject { |key,val| SPECIAL_OPTIONS.include?(key) })
14
+ end
15
+
16
+ def session_id
17
+ browser.__send__(:bridge).session_id
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,12 @@
1
+ module Dressing
2
+ module Capybara
3
+ class Session < ::Capybara::Session
4
+ attr_reader :driver
5
+
6
+ def initialize(driver)
7
+ @driver = driver
8
+ super nil, driver.app
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,67 @@
1
+ module Dressing
2
+ class Configuration
3
+ attr_accessor :browser
4
+ attr_accessor :os
5
+ attr_accessor :version
6
+
7
+ attr_accessor :username
8
+ attr_accessor :access_key
9
+
10
+ POTENTIAL_PORTS = [
11
+ 3000, 3001, 3030, 3210, 3333, 4000, 4001, 4040, 4321, 4502, 4503, 5000,
12
+ 5001, 5050, 5555, 5432, 6000, 6001, 6060, 6666, 6543, 7000, 7070, 7774,
13
+ 7777, 8000, 8001, 8003, 8031, 8080, 8081, 8765, 8888, 9000, 9001, 9080,
14
+ 9090, 9876, 9999, 49221, 55001, 80, 443, 888, 2000, 2001, 2020, 2109,
15
+ 2222, 2310
16
+ ]
17
+
18
+ SAUCE_OPTIONS = %w(record-video record-screenshots capture-html tags
19
+ sauce-advisor single-window user-extensions-url firefox-profile-url
20
+ max-duration idle-timeout build custom-data tunnel-identifier
21
+ selenium-version command-timeout prerun prerun-args screen-resolution
22
+ disable-popup-handler avoid-proxy public name)
23
+
24
+ SAUCE_OPTIONS.each do |option|
25
+ attr_accessor :"#{option.gsub('-', '_')}"
26
+ end
27
+
28
+ def initialize
29
+ self.browser = ENV['SAUCE_BROWSER'] || 'Chrome'
30
+ self.os = ENV['SAUCE_OS'] || 'Windows 7'
31
+ self.version = ENV['SAUCE_VERSION']
32
+
33
+ self.username = ENV['SAUCE_USERNAME']
34
+ self.access_key = ENV['SAUCE_ACCESS_KEY']
35
+
36
+ self.tunnel_identifier = ENV['SAUCE_TUNNEL_IDENTIFIER'] || ENV['TRAVIS_JOB_NUMBER']
37
+
38
+ self.build = ENV['SAUCE_BUILD'] || ENV['TRAVIS_BUILD_NUMBER']
39
+ self.tags = ENV['SAUCE_TAGS'] || travis_tags
40
+ end
41
+
42
+ def remote_url
43
+ "http://#{username}:#{access_key}@ondemand.saucelabs.com/wd/hub"
44
+ end
45
+
46
+ def http_timeout
47
+ 300
48
+ end
49
+
50
+ def to_capabilities
51
+ { 'browserName' => browser,
52
+ 'platform' => os,
53
+ 'version' => version }.merge(
54
+ Hash[SAUCE_OPTIONS.map { |option| [option, __send__(:"#{option.gsub('-', '_')}")] }]
55
+ ).keep_if { |key, value| !value.nil? }
56
+ end
57
+
58
+ def travis_tags
59
+ return nil unless ENV['TRAVIS']
60
+ tags = ['travis']
61
+ tags << "branch:#{ENV['TRAVIS_BRANCH']}"
62
+ tags << "repo:#{ENV['TRAVIS_REPO_SLUG']}"
63
+ tags << "commit:#{ENV['TRAVIS_COMMIT']}"
64
+ tags
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,15 @@
1
+ require 'dressing'
2
+ require 'rspec'
3
+ require 'capybara/rspec'
4
+
5
+ module Dressing
6
+ module RSpec
7
+ def page
8
+ Dressing.current_session
9
+ end
10
+
11
+ def self.included(config)
12
+ config.around { |test| Runner::RSpec.run test, example }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,60 @@
1
+ require 'sauce_whisk'
2
+
3
+ module Dressing
4
+ module Runner
5
+ class Base
6
+ attr_reader :test
7
+
8
+ def self.run(*args)
9
+ new(*args).run
10
+ end
11
+
12
+ def initialize(test)
13
+ @test = test
14
+ end
15
+
16
+ def run
17
+ Dressing.using_driver driver do
18
+ run_test
19
+ update_status
20
+ end
21
+ end
22
+
23
+ def run_test
24
+ raise NotImplementedError
25
+ end
26
+
27
+ def passed?
28
+ raise NotImplementedError
29
+ end
30
+
31
+ private
32
+
33
+ def app
34
+ Dressing.app
35
+ end
36
+
37
+ def driver
38
+ @driver ||= Capybara::Driver.new app, desired_capabilities: capabilities
39
+ end
40
+
41
+ def session_id
42
+ driver.session_id
43
+ end
44
+
45
+ def update_status
46
+ SauceWhisk::Jobs.change_status driver.session_id, passed?
47
+ end
48
+
49
+ def capabilities
50
+ capabilities_class.new(test).to_h
51
+ end
52
+
53
+ def capabilities_class
54
+ klass = :"#{self.class.to_s.gsub(/.*::/, '')}"
55
+ Capabilities.const_get klass
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,20 @@
1
+ module Dressing
2
+ module Runner
3
+ class RSpec < Base
4
+ attr_reader :example
5
+
6
+ def initialize(test, example)
7
+ @example = example
8
+ super test
9
+ end
10
+
11
+ def run_test
12
+ test.run
13
+ end
14
+
15
+ def passed?
16
+ example.exception.nil?
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module Dressing
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'capybara/rspec'
3
+ require 'dressing/rspec'
4
+
5
+ def app
6
+ lambda { |env| [200, {'Content-Type' => 'text/html'}, ['<body><h1>Hello world</h1><a href="#">Button</a></body>']] }
7
+ end
8
+
9
+ Capybara.app = app
10
+ Capybara.server_port = 9999
11
+
12
+ RSpec.configure do |config|
13
+ config.include Capybara::DSL
14
+ config.include Dressing::RSpec
15
+ end
16
+
17
+ describe 'page' do
18
+ 2.times do |i|
19
+ it "runs the page on sauce labs ##{i}" do
20
+ visit '/'
21
+ expect(page).to have_content 'Hello world'
22
+ end
23
+ end
24
+
25
+ it 'clicks buttons' do
26
+ visit '/'
27
+ click_on 'Button'
28
+ end
29
+ end
@@ -0,0 +1 @@
1
+ Bundler.require :default, :test
metadata ADDED
@@ -0,0 +1,186 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dressing
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Eric J. Holmes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: selenium-webdriver
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: sauce_whisk
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: net-http-persistent
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: bundler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '1.3'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '1.3'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: capybara
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'
126
+ description: A Capybara driver for Sauce Labs
127
+ email:
128
+ - eric@ejholmes.net
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - .gitignore
134
+ - Gemfile
135
+ - LICENSE.txt
136
+ - README.md
137
+ - Rakefile
138
+ - bin/sauce_connect_block.sh
139
+ - bin/sauce_connect_setup.sh
140
+ - dressing.gemspec
141
+ - lib/dressing.rb
142
+ - lib/dressing/capabilities/base.rb
143
+ - lib/dressing/capabilities/rspec.rb
144
+ - lib/dressing/capybara/driver.rb
145
+ - lib/dressing/capybara/session.rb
146
+ - lib/dressing/configuration.rb
147
+ - lib/dressing/rspec.rb
148
+ - lib/dressing/runner/base.rb
149
+ - lib/dressing/runner/rspec.rb
150
+ - lib/dressing/version.rb
151
+ - spec/capybara_spec.rb
152
+ - spec/spec_helper.rb
153
+ homepage: https://github.com/ejholmes/dressing
154
+ licenses:
155
+ - MIT
156
+ post_install_message:
157
+ rdoc_options: []
158
+ require_paths:
159
+ - lib
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ segments:
167
+ - 0
168
+ hash: 134270101903359235
169
+ required_rubygems_version: !ruby/object:Gem::Requirement
170
+ none: false
171
+ requirements:
172
+ - - ! '>='
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ segments:
176
+ - 0
177
+ hash: 134270101903359235
178
+ requirements: []
179
+ rubyforge_project:
180
+ rubygems_version: 1.8.23
181
+ signing_key:
182
+ specification_version: 3
183
+ summary: A Capybara driver for Sauce Labs
184
+ test_files:
185
+ - spec/capybara_spec.rb
186
+ - spec/spec_helper.rb