elabs_matchers 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +61 -0
- data/README.rdoc +45 -0
- data/Rakefile +17 -0
- data/doc/ElabsMatchers.html +106 -0
- data/doc/ElabsMatchers/Matchers.html +93 -0
- data/doc/ElabsMatchers/Matchers/Capybara.html +81 -0
- data/doc/ElabsMatchers/Matchers/Rspec.html +81 -0
- data/doc/_index.html +140 -0
- data/doc/class_list.html +36 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +53 -0
- data/doc/css/style.css +318 -0
- data/doc/file.README.html +102 -0
- data/doc/file_list.html +38 -0
- data/doc/frames.html +13 -0
- data/doc/index.html +102 -0
- data/doc/js/app.js +203 -0
- data/doc/js/full_list.js +149 -0
- data/doc/js/jquery.js +16 -0
- data/doc/method_list.html +35 -0
- data/doc/top-level-namespace.html +88 -0
- data/elabs_matchers.gemspec +27 -0
- data/lib/elabs_matchers.rb +19 -0
- data/lib/elabs_matchers/cucumber/common.rb +57 -0
- data/lib/elabs_matchers/helpers/capybara.rb +24 -0
- data/lib/elabs_matchers/helpers/common.rb +27 -0
- data/lib/elabs_matchers/helpers/fixtures.rb +21 -0
- data/lib/elabs_matchers/helpers/orm.rb +32 -0
- data/lib/elabs_matchers/helpers/session.rb +26 -0
- data/lib/elabs_matchers/matchers/capybara/common.rb +200 -0
- data/lib/elabs_matchers/matchers/rspec/common.rb +59 -0
- data/lib/elabs_matchers/matchers/rspec/orm.rb +29 -0
- data/lib/elabs_matchers/orm/post.rb +27 -0
- data/lib/elabs_matchers/version.rb +3 -0
- data/spec/elabs_matchers/cucumber/common_spec.rb +49 -0
- data/spec/elabs_matchers/helpers/capybara_spec.rb +32 -0
- data/spec/elabs_matchers/helpers/common_spec.rb +25 -0
- data/spec/elabs_matchers/helpers/fixtures_spec.rb +9 -0
- data/spec/elabs_matchers/helpers/orm_spec.rb +22 -0
- data/spec/elabs_matchers/matchers/capybara/common_spec.rb +202 -0
- data/spec/elabs_matchers/matchers/rspec/common_spec.rb +74 -0
- data/spec/elabs_matchers/matchers/rspec/orm_spec.rb +16 -0
- data/spec/fixtures/file.txt +1 -0
- data/spec/spec_helper.rb +11 -0
- metadata +192 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
module ElabsMatchers
|
2
|
+
module Helpers
|
3
|
+
module Fixtures
|
4
|
+
|
5
|
+
##
|
6
|
+
#
|
7
|
+
# Opens a file from the fixtures directory.
|
8
|
+
#
|
9
|
+
# @param [String] file name A file name, relative to the fixtures folder.
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
# fixture_file("file.txt")
|
13
|
+
#
|
14
|
+
|
15
|
+
def fixture_file(path)
|
16
|
+
root = if defined?(Rails) then Rails.root else "../../../spec/" end
|
17
|
+
File.open(File.expand_path("#{root}/fixtures/#{path}", File.dirname(__FILE__)))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ElabsMatchers
|
2
|
+
module Helpers
|
3
|
+
module Orm
|
4
|
+
##
|
5
|
+
#
|
6
|
+
# Finds the record from the database and return a new instance for that record.
|
7
|
+
#
|
8
|
+
# @param [Object] record An instance of an ORM record
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
# reload(post)
|
12
|
+
|
13
|
+
def reload(model)
|
14
|
+
model.class.find(model.id)
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
#
|
19
|
+
# Saves the record and fetches it from the database and return a new instance for that record.
|
20
|
+
#
|
21
|
+
# @param [Object] record An instance of an ORM record
|
22
|
+
#
|
23
|
+
# Example:
|
24
|
+
# save_and_reload(post)
|
25
|
+
|
26
|
+
def save_and_reload(model)
|
27
|
+
model.save!
|
28
|
+
reload(model)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ElabsMatchers
|
2
|
+
module Helpers
|
3
|
+
module Session
|
4
|
+
##
|
5
|
+
#
|
6
|
+
# Logs the user into the system. Requires that you login with an email and password
|
7
|
+
# and that your fields are named a certain way
|
8
|
+
# as well as there being a new_user_session path available.
|
9
|
+
#
|
10
|
+
# @param [Object] record The user record
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
# login_as(user)
|
14
|
+
|
15
|
+
attr_reader :current_user
|
16
|
+
|
17
|
+
def login_as(user)
|
18
|
+
visit(new_user_session_path)
|
19
|
+
fill_in('Email', :with => user.email)
|
20
|
+
fill_in('Password', :with => user.password)
|
21
|
+
click_button('Sign in')
|
22
|
+
@current_user = user
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
module ElabsMatchers
|
2
|
+
module Matchers
|
3
|
+
module Capybara
|
4
|
+
module Common
|
5
|
+
##
|
6
|
+
#
|
7
|
+
# Asserts if the select input tag contains the given options.
|
8
|
+
#
|
9
|
+
# @param [Array] options One or serveral strings seperated by comma
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
# find(:xpath, XPath::HTML.select("My input label")).should have_options(options)
|
13
|
+
|
14
|
+
RSpec::Matchers.define :have_options do |*options|
|
15
|
+
match do |select|
|
16
|
+
options.all? { |option| select.all("option").map(&:text).include?(option) }
|
17
|
+
end
|
18
|
+
|
19
|
+
failure_message_for_should do |select|
|
20
|
+
actual_options = select.all("option").map(&:text).inspect
|
21
|
+
"expected options to include '#{options.flatten.inspect}' but it had the options #{actual_options}."
|
22
|
+
end
|
23
|
+
failure_message_for_should_not { |select| "expected options not to include '#{options.flatten.inspect}' but it did." }
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
#
|
28
|
+
# Asserts if the supplied table row exists in the table
|
29
|
+
#
|
30
|
+
# @param [String] table name The tables's caption text.
|
31
|
+
# @param [Hash] column value A hash representing the column name and value in key-value form.
|
32
|
+
#
|
33
|
+
# Example:
|
34
|
+
# table.should have_table_row('Posts', "Title" => "First", :year => "2012")
|
35
|
+
|
36
|
+
RSpec::Matchers.define :have_table_row do |table_name, row|
|
37
|
+
match do |page|
|
38
|
+
table = page.find(:xpath, XPath::HTML.table(table_name))
|
39
|
+
row_index = nil
|
40
|
+
|
41
|
+
row.all? do |header, value|
|
42
|
+
col_index = table.all("thead th").index { |th| th.text.include?(header) }
|
43
|
+
col_index = if col_index then col_index + 1 else 0 end
|
44
|
+
|
45
|
+
current_row_index = table.all("tbody tr").index { |tr| tr.text.include?(value) }
|
46
|
+
correct_row = row_index.nil? || current_row_index == row_index
|
47
|
+
row_index = current_row_index
|
48
|
+
|
49
|
+
correct_row and table.has_xpath?(".//td[#{col_index}][contains(.,'#{value}')]")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
failure_message_for_should do |page|
|
54
|
+
table = page.find(:xpath, XPath::HTML.table(table_name))
|
55
|
+
ascii_table = table.all('tr').map do |tr|
|
56
|
+
'| ' + tr.all('td,th').map { |td| td.text.strip.ljust(21) }.join(' | ') + ' |'
|
57
|
+
end.join("\n")
|
58
|
+
"expected #{row.inspect} to be included in the table #{table_name}, but it wasn't:\n\n#{ascii_table}"
|
59
|
+
end
|
60
|
+
failure_message_for_should_not { |page| "expected there to be no table #{table_name} with row #{row.inspect}, but there was." }
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
#
|
65
|
+
# Asserts if the supplied show_for* attribute exists or not
|
66
|
+
#
|
67
|
+
# @param [String] label The name of the attribute.
|
68
|
+
# @param [String] value The value of the attribute.
|
69
|
+
#
|
70
|
+
# Example:
|
71
|
+
# page.should have_attribute("Status", "Pending")
|
72
|
+
#
|
73
|
+
# * https://github.com/plataformatec/show_for
|
74
|
+
|
75
|
+
RSpec::Matchers.define :have_attribute do |label, value|
|
76
|
+
match do |page|
|
77
|
+
xpath = XPath.generate { |x| x.descendant(:p)[x.attr(:class).contains('wrapper')][x.child(:strong).contains(label)][x.contains(value)] }
|
78
|
+
page.has_xpath?(xpath)
|
79
|
+
end
|
80
|
+
|
81
|
+
failure_message_for_should do |page|
|
82
|
+
attributes = page.all(:css, 'li.wrapper').map(&:text).to_sentence
|
83
|
+
"expected there to be an attribute #{label}: #{value}, but the only attributes were: #{attributes}."
|
84
|
+
end
|
85
|
+
failure_message_for_should_not { |page| "expected there to be no attribute #{label}: #{value}, but there was." }
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
#
|
90
|
+
# Asserts if the supplied image exists or not
|
91
|
+
#
|
92
|
+
# @param [String] alt The alt attribute content of the image
|
93
|
+
#
|
94
|
+
# Example:
|
95
|
+
# page.should have_image("Logo")
|
96
|
+
|
97
|
+
RSpec::Matchers.define :have_image do |alt|
|
98
|
+
match { |page| page.has_css?("img[alt=\"#{alt}\"]") }
|
99
|
+
|
100
|
+
failure_message_for_should do |page|
|
101
|
+
alts = page.all('img').map { |img| "'#{img[:alt]}'" }.to_sentence
|
102
|
+
"expected image alt to be '#{alt}' but it had the image alts: #{alts}."
|
103
|
+
end
|
104
|
+
failure_message_for_should_not { |page| "expected image not to be '#{alt}' but it was" }
|
105
|
+
end
|
106
|
+
|
107
|
+
##
|
108
|
+
#
|
109
|
+
# Asserts if the supplied header exists or not
|
110
|
+
#
|
111
|
+
# @param [String] text The content of the header
|
112
|
+
#
|
113
|
+
# Example:
|
114
|
+
# page.should have_header("Elabs")
|
115
|
+
|
116
|
+
RSpec::Matchers.define :have_header do |text|
|
117
|
+
match { |page| page.has_css?('h1,h2', :text => text) }
|
118
|
+
|
119
|
+
failure_message_for_should do |page|
|
120
|
+
headers = page.all('h1,h2').map { |h| "'#{h.text}'" }.to_sentence
|
121
|
+
"expected header to be '#{text}' but it had the headers #{headers}"
|
122
|
+
end
|
123
|
+
failure_message_for_should_not { |page| "expected header not to be '#{text}' but it was" }
|
124
|
+
end
|
125
|
+
|
126
|
+
##
|
127
|
+
#
|
128
|
+
# Asserts if the supplied flash notice exists or not
|
129
|
+
#
|
130
|
+
# @param [String] text The content of the flash notice
|
131
|
+
#
|
132
|
+
# Example:
|
133
|
+
# page.should have_flash_notice("Success")
|
134
|
+
|
135
|
+
RSpec::Matchers.define :have_flash_notice do |text|
|
136
|
+
match { |page| page.has_css?('#flash.notice', :text => text) }
|
137
|
+
failure_message_for_should { |page| "expected flash notice to be '#{text}' but was '#{page.find('#flash.notice').text}'" }
|
138
|
+
failure_message_for_should_not { |page| "expected flash notice not to be '#{text}' but it was" }
|
139
|
+
end
|
140
|
+
|
141
|
+
##
|
142
|
+
#
|
143
|
+
# Asserts if the supplied flash alert exists or not
|
144
|
+
#
|
145
|
+
# @param [String] text The content of the flash alert
|
146
|
+
#
|
147
|
+
# Example:
|
148
|
+
# page.should have_flash_alert("Error")
|
149
|
+
|
150
|
+
RSpec::Matchers.define :have_flash_alert do |text|
|
151
|
+
match { |page| page.has_css?('#flash.alert', :text => text) }
|
152
|
+
failure_message_for_should { |page| "expected flash alert to be '#{text}' but was '#{page.find('#flash.alert').text}'" }
|
153
|
+
failure_message_for_should_not { |page| "expected flash alert not to be '#{text}' but it was" }
|
154
|
+
end
|
155
|
+
|
156
|
+
##
|
157
|
+
#
|
158
|
+
# Asserts if the supplied flash alert exists or not
|
159
|
+
#
|
160
|
+
# @param [String] label The label content associated with the field.
|
161
|
+
# @param [String] message The error message expected.
|
162
|
+
#
|
163
|
+
# Example:
|
164
|
+
# page.should have_form_errors_on("Name", "Can't be blank")
|
165
|
+
|
166
|
+
RSpec::Matchers.define :have_form_errors_on do |field, message|
|
167
|
+
xpath = %Q{..//span[contains(@class,'error')]}
|
168
|
+
match { |page| page.has_field?(field) and page.find_field(field).has_xpath?(xpath, :text => message) }
|
169
|
+
|
170
|
+
failure_message_for_should do |page|
|
171
|
+
error = page.find_field(field).all(:xpath, xpath).first
|
172
|
+
if not error
|
173
|
+
"expected field '#{field}' to have an error, but it didn't"
|
174
|
+
elsif error.text != message
|
175
|
+
"expected error message on #{field} to be '#{message}' but was '#{error.text}'"
|
176
|
+
else
|
177
|
+
raise "This should not happen"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
failure_message_for_should_not { |page| "expected error message on '#{field}' not to be '#{text}' but it was" }
|
181
|
+
end
|
182
|
+
|
183
|
+
##
|
184
|
+
#
|
185
|
+
# Asserts if the supplied fields exists or not
|
186
|
+
#
|
187
|
+
# @param [Hash] field name, value A hash containing pairs of field name => value
|
188
|
+
#
|
189
|
+
# Example:
|
190
|
+
# page.should have_fields("Author" => "Adam", "Year" => "2011")
|
191
|
+
|
192
|
+
RSpec::Matchers.define :have_fields do |fields|
|
193
|
+
match { |page| fields.all? { |label, value| page.has_field?(label, :with => value.to_s) } }
|
194
|
+
failure_message_for_should { |page| "expected page to have the fields #{fields.inspect}, but it didn't." }
|
195
|
+
failure_message_for_should_not { |page| "expected page not to have the fields #{fields.inspect}, but it did." }
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module ElabsMatchers
|
2
|
+
module Matchers
|
3
|
+
module Rspec
|
4
|
+
module Common
|
5
|
+
##
|
6
|
+
#
|
7
|
+
# Asserts if the hash contains the supplied hash.
|
8
|
+
# Works with nested hashes and array of hashes.
|
9
|
+
#
|
10
|
+
# @param [Hash] options Key => value pairs seperated by comma
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
# { "foo" => ['quox', { 'bar' => 'baz'}]}.should contain_hash({ "foo" => [{ "bar" => "baz" }]})
|
14
|
+
# { "foo" => "bar", "baz" => "quox" }.should_not contain_hash({ "baz" => "bar" })
|
15
|
+
|
16
|
+
RSpec::Matchers.define :contain_hash do |expected|
|
17
|
+
match do |actual|
|
18
|
+
contains?(expected, actual)
|
19
|
+
end
|
20
|
+
|
21
|
+
def contains?(expected, actual)
|
22
|
+
return false unless actual.is_a?(expected.class)
|
23
|
+
|
24
|
+
if expected.is_a?(Array)
|
25
|
+
expected.all? do |expected_value|
|
26
|
+
actual.any? do |actual_value|
|
27
|
+
contains?(expected_value, actual_value)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
elsif expected.is_a?(Hash)
|
31
|
+
expected.all? do |key, value|
|
32
|
+
contains?(value, actual[key])
|
33
|
+
end
|
34
|
+
else
|
35
|
+
actual == expected
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
#
|
42
|
+
# Asserts if the array contains exactly the supplied elements.
|
43
|
+
# The order of the element do not have to match.
|
44
|
+
#
|
45
|
+
# @param argument list options comma seperated list of arguments
|
46
|
+
#
|
47
|
+
# Example:
|
48
|
+
# ["foo", "bar"].should only_include("bar", "foo")
|
49
|
+
# ["foo", "bar"].should_not only_include("foo")
|
50
|
+
|
51
|
+
RSpec::Matchers.define :only_include do |*collection|
|
52
|
+
match { |actual| actual.length == collection.length and collection.all? { |element| actual.include?(element) } }
|
53
|
+
failure_message_for_should { |actual| "Expected #{actual.inspect} to only include #{collection.inspect}." }
|
54
|
+
failure_message_for_should_not { |actual| "Expected #{actual.inspect} to not only include #{collection.inspect}, but it did." }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module ElabsMatchers
|
2
|
+
module Matchers
|
3
|
+
module Rspec
|
4
|
+
module Orm
|
5
|
+
##
|
6
|
+
#
|
7
|
+
# Asserts if an assigned value persistes in the database.
|
8
|
+
#
|
9
|
+
# @param [Symbol] attribute name The name of the attibute to check if it persisted or not
|
10
|
+
# @param [Object] value The value to persist to the attribute
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
# post.should persist(:title, "Blog post")
|
14
|
+
|
15
|
+
RSpec::Matchers.define :persist do |attribute, value|
|
16
|
+
match do |actual|
|
17
|
+
actual.send(:"#{attribute}=", value)
|
18
|
+
actual.save!
|
19
|
+
actual = actual.class.find(actual.id)
|
20
|
+
@final_value = actual.send(attribute)
|
21
|
+
@final_value == value
|
22
|
+
end
|
23
|
+
failure_message_for_should { |actual| "Expected #{attribute} to be persisted and retain its value of #{value.inspect} but the value was #{@final_value.inspect}" }
|
24
|
+
failure_message_for_should_not { |actual| "Expected #{attribute} not to be persisted and retain its value of #{value.inspect} but it did." }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ElabsMatchers
|
2
|
+
module Orm
|
3
|
+
class Post
|
4
|
+
attr_accessor :title
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def find(id)
|
8
|
+
new(:title => @@persisted_post.title)
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(attributes = {})
|
12
|
+
@@persisted_post = new(attributes)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(attributes = {})
|
17
|
+
self.title = attributes[:title]
|
18
|
+
end
|
19
|
+
|
20
|
+
def save!
|
21
|
+
end
|
22
|
+
|
23
|
+
def id
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ElabsMatchers::Cucumber::Common do
|
4
|
+
describe "LIST_SEPARATOR" do
|
5
|
+
it "matches ," do
|
6
|
+
", ".should =~ Cucumber::LIST_SEPARATOR
|
7
|
+
end
|
8
|
+
|
9
|
+
it "matches and" do
|
10
|
+
" and ".should =~ Cucumber::LIST_SEPARATOR
|
11
|
+
end
|
12
|
+
|
13
|
+
it "doesn't matches other things" do
|
14
|
+
"foo".should_not =~ Cucumber::LIST_SEPARATOR
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "LIST_REGEXP" do
|
19
|
+
it "matches just one item" do
|
20
|
+
%Q{"Bart"}.should =~ Cucumber::LIST_REGEXP
|
21
|
+
end
|
22
|
+
|
23
|
+
it "matches a comma seperated list" do
|
24
|
+
%Q{"Bart", "Lisa"}.should =~ Cucumber::LIST_REGEXP
|
25
|
+
end
|
26
|
+
|
27
|
+
it "matches a 'and' seperated list" do
|
28
|
+
%Q{"Bart" and "Lisa"}.should =~ Cucumber::LIST_REGEXP
|
29
|
+
end
|
30
|
+
|
31
|
+
it "matches a comma and 'and' seperated list" do
|
32
|
+
%Q{"Bart", "Lisa" and "Homer"}.should =~ Cucumber::LIST_REGEXP
|
33
|
+
end
|
34
|
+
|
35
|
+
it "matches a comma and 'and' seperated list with several words" do
|
36
|
+
%Q{"Bart Simpsons", "Lisa Simpsons" and "Homer Simpsons"}.should =~ Cucumber::LIST_REGEXP
|
37
|
+
end
|
38
|
+
|
39
|
+
it "doesn't matches other things" do
|
40
|
+
%Q{foo}.should_not =~ Cucumber::LIST_REGEXP
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#human_list_to_array" do
|
45
|
+
it "converts a LIST_REGEXP-list to an array" do
|
46
|
+
human_list_to_array(%Q{"Bart", "Lisa" and "Homer"}).should == %w[Bart Lisa Homer]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|