view-matchers 1.0.2 → 1.0.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a1365ce18908977a7000e3dd2d5d7657109a9a62
4
- data.tar.gz: 59e314145e7f518d556f43372071dd9f0d581bbe
3
+ metadata.gz: e6471f6f42d2df963bb178fd08d0387d9ecef966
4
+ data.tar.gz: 5723079ee2f3d9f7a750cbb7a814aba31d047970
5
5
  SHA512:
6
- metadata.gz: 70fa87e5dbec74d5b7dd006a7604e156b5a6c1007e9900e57510c6180a0799e1a4ebb4d918b42e584cc05c3fd52c9a51664868efa068bfed0392fedd405c62a7
7
- data.tar.gz: 04aa45493116339dd3c6802b2de1004e092858d9c1ca0522b097ac771b59ebf106a539884aa48424490946f19ca88edb554d32cdfc75be9b873414854e9cd154
6
+ metadata.gz: e5d26e144f082feeeef72f7f95795dd3afc00c36dc9dfa61a1c668151ab6d4842f229463bdeb62a331a73f778bac69f48e1bfc81850c7bc6ad593433f0d625b0
7
+ data.tar.gz: 9506c227ce33ed7724b966c90400013e5e71d34c18efc6b3f467306577e3b758dfefa5ba250666cd4e153e72156745daadff12993f06c566efda66f81a4ccff2
data/.gitignore ADDED
@@ -0,0 +1,34 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ # Gemfile.lock
30
+ # .ruby-version
31
+ # .ruby-gemset
32
+
33
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
+ .rvmrc
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.5
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ script: bundle exec rspec spec
5
+ addons:
6
+ code_climate:
7
+ repo_token: 2b2ff0bdbc6598c8503b0f23c52cc14c822e464147ec0b4dfdd90b33cb928552
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'nokogiri'
4
+ gem 'rspec-core', '~> 3.2'
5
+ gem 'rspec-expectations', '~> 3.2'
6
+
7
+ group :test do
8
+ gem 'codeclimate-test-reporter'
9
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,31 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ codeclimate-test-reporter (0.4.7)
5
+ simplecov (>= 0.7.1, < 1.0.0)
6
+ diff-lcs (1.2.5)
7
+ docile (1.1.5)
8
+ mini_portile (0.6.2)
9
+ multi_json (1.11.0)
10
+ nokogiri (1.6.6.2)
11
+ mini_portile (~> 0.6.0)
12
+ rspec-core (3.2.2)
13
+ rspec-support (~> 3.2.0)
14
+ rspec-expectations (3.2.0)
15
+ diff-lcs (>= 1.2.0, < 2.0)
16
+ rspec-support (~> 3.2.0)
17
+ rspec-support (3.2.2)
18
+ simplecov (0.9.2)
19
+ docile (~> 1.1.0)
20
+ multi_json (~> 1.0)
21
+ simplecov-html (~> 0.9.0)
22
+ simplecov-html (0.9.0)
23
+
24
+ PLATFORMS
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ codeclimate-test-reporter
29
+ nokogiri
30
+ rspec-core (~> 3.2)
31
+ rspec-expectations (~> 3.2)
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Tom König
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # view-matchers
2
+ Expressive RSpec matchers for ascii tables and form fields.
3
+
4
+ * **[match_table](#match_table)**: write ascii tables and match their existence
5
+ * **[match_form](#match_form)**: match form fields with an expressive dsl
6
+
7
+ [![Build Status](https://travis-ci.org/TomKnig/view-matchers.svg)](https://travis-ci.org/TomKnig/view-matchers)
8
+ [![Code Climate](https://codeclimate.com/github/TomKnig/view-matchers/badges/gpa.svg)](https://codeclimate.com/github/TomKnig/view-matchers)
9
+ [![Test Coverage](https://codeclimate.com/github/TomKnig/view-matchers/badges/coverage.svg)](https://codeclimate.com/github/TomKnig/view-matchers)
10
+
11
+ ## Installation
12
+
13
+ #### Gem
14
+
15
+ Include the gem in your Gemfile:
16
+
17
+ ```ruby
18
+ group :test do
19
+ gem 'view-matchers', '~> 1.0'
20
+ end
21
+ ```
22
+
23
+ #### Matcher inclusion
24
+
25
+ You can either include the matchers in a particular spec:
26
+
27
+ ```ruby
28
+ describe 'a particular view with tables' do
29
+ include ViewMatchers
30
+ # ...
31
+ end
32
+ ```
33
+
34
+ ... or include the matchers globally in a `spec_helper.rb` file:
35
+
36
+ ```ruby
37
+ RSpec.configure do |config|
38
+ config.include ViewMatchers
39
+ end
40
+ ```
41
+
42
+ ## Matchers
43
+
44
+ view-matchers exposes some useful matchers for view specs. They are individually documented below.
45
+
46
+ #### match_table
47
+
48
+ * You can match a table in a rendered view within a spec with `match_table`.
49
+ * Matches are partial. The actually rendered table can - but does not have to - be a superset of the expected table to evaluate the expectation to true.
50
+
51
+ ```ruby
52
+ # spec/views/table_spec.rb
53
+ it 'renders all products in a proper table' do
54
+ expect(rendered).to match_table %(
55
+ +----------+----------+----------+
56
+ | Number | Product | Price |
57
+ +----------+----------+----------+
58
+ | 1 | Computer | 42,00 € |
59
+ +----------+----------+----------+
60
+ | 2 | Phone | 21,00 € |
61
+ +----------+----------+----------+
62
+ )
63
+ end
64
+ ```
65
+
66
+ #### match_form
67
+
68
+ * You can match a table in a rendered view within a spec with `match_form`.
69
+ * Matches are partial. The actually rendered form can - but does not have to - be a superset of the expected form to evaluate the expectation to true.
70
+ * `match_form` takes a `Proc` as argument. Methodnames within the `Proc` are interpreted as HTML-Tag matchers. The first parameter of these methods matches the `name` attribute, which can be followed by arbitrary attribute names and values. The last parameter is an optional block, that can be provided to match nested tags.
71
+
72
+ ```ruby
73
+ # spec/views/sign_up_spec.rb
74
+ it 'renders a sign up form' do
75
+ expect(rendered).to match_form proc {
76
+ input 'user[email]', type: 'email'
77
+ input 'user[password]', type: 'password'
78
+ input 'user[password_confirmation]', type: 'password'
79
+ select 'user[language]' do
80
+ option nil, value: 'Objective-C'
81
+ option nil, value: 'Swift'
82
+ end
83
+ }
84
+ end
85
+ ```
86
+
87
+ ## Contribution
88
+
89
+ I'd love to see your ideas!
90
+ I do really appreciate pull requests and [Github issues](https://github.com/TomKnig/view-matchers/issues/new). :octocat:
91
+
92
+ ## Author
93
+
94
+ [Tom König](http://github.com/TomKnig) [@TomKnig](https://twitter.com/TomKnig)
95
+
96
+ ## Versioning
97
+
98
+ view-matchers follows Semantic Versioning 2.0 as defined at <http://semver.org>.
99
+
100
+ ## License
101
+
102
+ view-matchers is available under the MIT license. See the LICENSE file for more info.
@@ -0,0 +1,15 @@
1
+ require 'nokogiri'
2
+
3
+ require 'view_matchers/table_matcher'
4
+ require 'view_matchers/form_matcher'
5
+ require 'view_matchers/version'
6
+
7
+ module ViewMatchers
8
+ def match_form(block)
9
+ FormMatcher.new(block)
10
+ end
11
+
12
+ def match_table(ascii_table)
13
+ TableMatcher.new(ascii_table)
14
+ end
15
+ end
@@ -0,0 +1,50 @@
1
+ require 'view_matchers/form_matcher/form'
2
+
3
+ module ViewMatchers
4
+ class FormMatcher
5
+ def initialize(expected)
6
+ @expected = Form.new(expected)
7
+ end
8
+
9
+ def matches?(rendered)
10
+ expectation_exists_in_rendered? rendered
11
+ end
12
+
13
+ def failure_message
14
+ "the following expected tags did not exist:\n" <<
15
+ failure_messages
16
+ end
17
+
18
+ def failure_message_when_negated
19
+ "the following not expected tags actually did exist:\n" <<
20
+ failure_messages
21
+ end
22
+
23
+ private
24
+
25
+ def expectation_exists_in_rendered?(rendered)
26
+ Nokogiri::HTML(rendered).xpath('//form').each do |rendered_form|
27
+ return true if @expected.exists_in_rendered? rendered_form
28
+ update_failure_messages
29
+ end
30
+
31
+ false
32
+ end
33
+
34
+ def update_failure_messages
35
+ current_failures = @expected.failures
36
+ @failures = current_failures if current_failures.size < failures.size
37
+ end
38
+
39
+ def failure_messages
40
+ messages = @failures.keys.map do |selector|
41
+ @failures[selector].join("\n")
42
+ end
43
+ messages.join
44
+ end
45
+
46
+ def failures
47
+ @failures ||= @expected.failures
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,74 @@
1
+ module ViewMatchers
2
+ class Form
3
+ attr_reader :failures
4
+
5
+ def initialize(block)
6
+ @block = block
7
+ self
8
+ end
9
+
10
+ def exists_in_rendered?(actual_form)
11
+ @failures = {}
12
+ @current_scope = actual_form
13
+ @exists_in_rendered = true
14
+ instance_eval(&@block)
15
+ @exists_in_rendered
16
+ end
17
+
18
+ private
19
+
20
+ def method_missing(method, *args, &block)
21
+ @exists_in_rendered &= matches_selector? method, *args, &block
22
+ end
23
+
24
+ def matches_selector?(selector, name, hash = nil, &block)
25
+ matches = @current_scope.xpath xpath(selector, name, hash)
26
+ if matches.any?
27
+ return matches_nested_selectors?(matches, &block) if block_given?
28
+ return true
29
+ else
30
+ add_failure_message selector, name, hash
31
+ return false
32
+ end
33
+ end
34
+
35
+ def matches_nested_selectors?(matches, &block)
36
+ previous_scope = @current_scope
37
+ @current_scope = matches
38
+ retval = instance_eval(&block)
39
+ @current_scope = previous_scope
40
+ retval
41
+ end
42
+
43
+ def xpath(selector, name, hash = nil)
44
+ matcher = ''
45
+ matcher << explicit_matcher('name', name) if name
46
+ hash.keys.each { |key| matcher << fuzzy_matcher(key, hash[key]) } if hash
47
+ ".//#{selector}#{matcher}"
48
+ end
49
+
50
+ def explicit_matcher(key, value)
51
+ "[@#{key}=\"#{value}\"]"
52
+ end
53
+
54
+ def fuzzy_matcher(key, value)
55
+ "[contains(@#{key}, \"#{value}\")]"
56
+ end
57
+
58
+ def add_failure_message(selector, name, hash)
59
+ failures_for_selector(selector) << selector.to_s +
60
+ failure_message('named', name).to_s +
61
+ failure_message('attributes', hash).to_s
62
+ end
63
+
64
+ def failure_message(description, object)
65
+ " #{description}: #{object} " if object
66
+ end
67
+
68
+ def failures_for_selector(selector)
69
+ failures[selector] ||= []
70
+ end
71
+
72
+ undef_method :select
73
+ end
74
+ end
@@ -0,0 +1,33 @@
1
+ require 'view_matchers/table_matcher/ascii_table'
2
+ require 'view_matchers/table_matcher/html_table'
3
+
4
+ module ViewMatchers
5
+ class TableMatcher
6
+ def initialize(expected)
7
+ @expected = ASCIITable.new(expected)
8
+ end
9
+
10
+ def matches?(rendered)
11
+ expectation_exists_in_rendered?(rendered)
12
+ end
13
+
14
+ def failure_message
15
+ 'expected that the table contents would match'
16
+ end
17
+
18
+ def failure_message_when_negated
19
+ 'expected that the table contents would not match'
20
+ end
21
+
22
+ private
23
+
24
+ def expectation_exists_in_rendered?(rendered)
25
+ Nokogiri::HTML(rendered).xpath('//table').each do |rendered_table|
26
+ actual_table = HTMLTable.new(rendered_table)
27
+ return true if actual_table.contains? @expected
28
+ end
29
+
30
+ false
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ require 'view_matchers/table_matcher/table'
2
+
3
+ module ViewMatchers
4
+ class ASCIITable < Table
5
+ def rows
6
+ @rows ||= parse_rows
7
+ end
8
+
9
+ private
10
+
11
+ def parse_rows
12
+ @rows = @table.lines.map(&:strip)
13
+ @rows.select! { |row| row.start_with?('|') }
14
+ parse_cols
15
+ end
16
+
17
+ def parse_cols
18
+ @rows.map! do |row|
19
+ row.split('|').map(&:strip).reject(&:empty?)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ require 'view_matchers/table_matcher/table'
2
+
3
+ module ViewMatchers
4
+ class HTMLTable < Table
5
+ def rows
6
+ @rows ||= parse_rows
7
+ end
8
+
9
+ private
10
+
11
+ def parse_rows
12
+ @rows = @table.xpath('.//tr')
13
+ parse_cols
14
+ end
15
+
16
+ def parse_cols
17
+ @rows = @rows.collect do |row|
18
+ row.xpath('.//th | .//td').collect(&:content)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,45 @@
1
+ module ViewMatchers
2
+ class Table
3
+ def initialize(table)
4
+ @table = table
5
+ self
6
+ end
7
+
8
+ def contains?(table)
9
+ possible_origins_of(table).each do |origin|
10
+ matches = continuous_row_matches_from_index table, origin
11
+ return true if matches.all? && matches.uniq.length == 1
12
+ end
13
+ false
14
+ end
15
+
16
+ private
17
+
18
+ def possible_origins_of(table)
19
+ indices = rows.map.with_index do |_row, index|
20
+ index if row_contained_in_row? rows[index], table.rows.first
21
+ end
22
+ indices.reject(&:nil?)
23
+ end
24
+
25
+ def continuous_row_matches_from_index(table, origin)
26
+ table.rows.map.with_index do |expected_row, offset|
27
+ row_contained_in_row? rows[(origin + offset)], expected_row
28
+ end
29
+ end
30
+
31
+ def row_contained_in_row?(row, expected_row)
32
+ upper_bound = row.length - expected_row.length
33
+ (0..upper_bound).each do |origin|
34
+ return origin if row_matches_row_from_index? row, expected_row, origin
35
+ end
36
+ nil
37
+ end
38
+
39
+ def row_matches_row_from_index?(row, expected_row, origin)
40
+ upper_bound = origin + expected_row.length - 1
41
+ row = row[origin..upper_bound]
42
+ row.map(&:rstrip) == expected_row.map(&:rstrip)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ module ViewMatchers
2
+ VERSION = '1.0.3'
3
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+
3
+ module ViewMatchers
4
+ RSpec.describe ViewMatchers::TableMatcher, type: :view do
5
+ let(:rendered) do
6
+ %(
7
+ <html>
8
+ <body>
9
+ <form action="/clients" accept-charset="UTF-8" method="post">
10
+ <input name="utf8" type="hidden" value="✓">
11
+ <input name="authenticity_token" type="hidden" value="...">
12
+ <div class="input-group">
13
+ <input type="email" name="client[email]">
14
+ </div>
15
+ <input type="password" name="client[password]">
16
+ <input type="password" name="client[password_confirmation]">
17
+ <select name="client[supplier_id]">
18
+ <option value="1" selected>Eine kleine Firma</option>
19
+ <option value="2">Eine andere Firma</option>
20
+ </select>
21
+ <input type="submit" name="commit" class="btn btn-primary">
22
+ <option value="outside select"></option>
23
+ </form>
24
+ <option value="outside form"></option>
25
+ <body>
26
+ <html>
27
+ )
28
+ end
29
+
30
+ describe 'match_form' do
31
+ it 'matches the exact same form' do
32
+ expect(rendered).to match_form proc {
33
+ input 'utf8', type: 'hidden', value: '✓'
34
+ input 'authenticity_token', type: 'hidden', value: '...'
35
+ input 'client[password]', type: 'password'
36
+ input 'client[password_confirmation]', type: 'password'
37
+ select 'client[supplier_id]' do
38
+ option nil, value: '1'
39
+ option nil, value: '2'
40
+ end
41
+ }
42
+ end
43
+
44
+ it 'matches nested form elements' do
45
+ expect(rendered).to match_form proc {
46
+ input 'client[email]', type: 'email'
47
+ }
48
+ end
49
+
50
+ it 'matches attributes fuzzily' do
51
+ expect(rendered).to match_form proc {
52
+ input 'commit', class: 'btn'
53
+ }
54
+ end
55
+
56
+ it 'matches selected options within a select' do
57
+ expect(rendered).to match_form proc {
58
+ select 'client[supplier_id]' do
59
+ option nil, value: '2'
60
+ end
61
+ }
62
+ end
63
+
64
+ it 'does not match elements outside a form' do
65
+ expect(rendered).not_to match_form proc {
66
+ option nil, value: 'outside form'
67
+ }
68
+ end
69
+
70
+ it 'does not match options outside the select' do
71
+ expect(rendered).not_to match_form proc {
72
+ select 'client[supplier_id]' do
73
+ option nil, value: 'outside select'
74
+ end
75
+ }
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,205 @@
1
+ require 'spec_helper'
2
+
3
+ module ViewMatchers
4
+ RSpec.describe ViewMatchers::TableMatcher, type: :view do
5
+ let(:rendered) do
6
+ %(
7
+ <html>
8
+ <body>
9
+ <table>
10
+ <tbody>
11
+ <tr>
12
+ <td>irrelevant table</td>
13
+ </tr>
14
+ </tbody>
15
+ </table>
16
+ <table>
17
+ <thead>
18
+ <tr>
19
+ <th>Quantity</th>
20
+ <th>Product</th>
21
+ <th>Price</th>
22
+ <th>Total</th>
23
+ </tr>
24
+ </thead>
25
+ <tbody>
26
+ <tr>
27
+ <td>1</td>
28
+ <td>Computer</td>
29
+ <td>42,00 €</td>
30
+ <td>42,00 €</td>
31
+ </tr>
32
+ <tr>
33
+ <td>2</td>
34
+ <td>Phone</td>
35
+ <td>21,00 €</td>
36
+ <td>42,00 €</td>
37
+ </tr>
38
+ </tbody>
39
+ </table>
40
+ <body>
41
+ <html>
42
+ )
43
+ end
44
+
45
+ describe 'match_table' do
46
+ it 'does not match a completely different table' do
47
+ expect(rendered).not_to match_table %(
48
+ +----------+----------+
49
+ | 3 | 5 |
50
+ +----------+----------+
51
+ | 4 | 6 |
52
+ +----------+----------+
53
+ )
54
+ end
55
+
56
+ it 'does not match a missing cell' do
57
+ expect(rendered).not_to match_table %(
58
+ +----------+
59
+ | 3 |
60
+ +----------+
61
+ )
62
+ end
63
+
64
+ it 'does not match slighly different tables' do
65
+ expect(rendered).not_to match_table %(
66
+ +----------+----------+----------+
67
+ | 1 | Computer | 42,00 € |
68
+ +----------+----------+----------+
69
+ | 2 | Phone | 22,00 € |
70
+ +----------+----------+----------+
71
+ )
72
+ end
73
+
74
+ it 'does not match slighly different tables' do
75
+ expect(rendered).not_to match_table %(
76
+ +----------+----------+----------+
77
+ | 2 | Computer | 42,00 € |
78
+ +----------+----------+----------+
79
+ | 1 | Phone | 21,00 € |
80
+ +----------+----------+----------+
81
+ )
82
+ end
83
+
84
+ it 'does not match table with missing inner column' do
85
+ expect(rendered).not_to match_table %(
86
+ +----------+----------+
87
+ | 1 | 42,00 € |
88
+ +----------+----------+
89
+ | 2 | 21,00 € |
90
+ +----------+----------+
91
+ )
92
+ end
93
+
94
+ it 'does not confuse column indices when columns are equal' do
95
+ expect(rendered).not_to match_table %(
96
+ +----------+----------+
97
+ | 42,00 € | 42,00 € |
98
+ +----------+----------+
99
+ | Phone | 21,00 € |
100
+ +----------+----------+
101
+ )
102
+ end
103
+
104
+ it 'does not confuse column indices when columns are equal' do
105
+ expect(rendered).to match_table %(
106
+ +----------+
107
+ | 42,00 € |
108
+ +----------+
109
+ | 21,00 € |
110
+ +----------+
111
+ )
112
+ end
113
+
114
+ it 'does not match table with missing inner row' do
115
+ expect(rendered).not_to match_table %(
116
+ +----------+----------+----------+
117
+ | Quantity | Product | Price |
118
+ +----------+----------+----------+
119
+ | 2 | Phone | 21,00 € |
120
+ +----------+----------+----------+
121
+ )
122
+ end
123
+
124
+ it 'does not match table with shifted rows' do
125
+ expect(rendered).not_to match_table %(
126
+ +----------+----------+
127
+ | Computer | 42,00 € |
128
+ +----------+----------+
129
+ | 2 | Phone |
130
+ +----------+----------+
131
+ )
132
+ end
133
+
134
+ it 'matches the exact same table' do
135
+ expect(rendered).to match_table %(
136
+ +----------+----------+----------+
137
+ | Quantity | Product | Price |
138
+ +----------+----------+----------+
139
+ | 1 | Computer | 42,00 € |
140
+ +----------+----------+----------+
141
+ | 2 | Phone | 21,00 € |
142
+ +----------+----------+----------+
143
+ )
144
+ end
145
+
146
+ it 'matches vertically partially existing table' do
147
+ expect(rendered).to match_table %(
148
+ +----------+----------+----------+
149
+ | 1 | Computer | 42,00 € |
150
+ +----------+----------+----------+
151
+ | 2 | Phone | 21,00 € |
152
+ +----------+----------+----------+
153
+ )
154
+ end
155
+
156
+ it 'matches an existing cell' do
157
+ expect(rendered).to match_table %(
158
+ +----------+
159
+ | Computer |
160
+ +----------+
161
+ )
162
+ end
163
+
164
+ it 'matches partially existing table' do
165
+ expect(rendered).to match_table %(
166
+ +----------+----------+
167
+ | 1 | Computer |
168
+ +----------+----------+
169
+ | 2 | Phone |
170
+ +----------+----------+
171
+ )
172
+ end
173
+
174
+ it 'matches horizontally equal columns correctly' do
175
+ expect(rendered).to match_table %(
176
+ +----------+----------+
177
+ | 42,00 € | 42,00 € |
178
+ +----------+----------+
179
+ | 21,00 € | 42,00 € |
180
+ +----------+----------+
181
+ )
182
+ end
183
+
184
+ it 'matches horizontally, partially existing table' do
185
+ expect(rendered).to match_table %(
186
+ +----------+----------+
187
+ | Computer | 42,00 € |
188
+ +----------+----------+
189
+ | Phone | 21,00 € |
190
+ +----------+----------+
191
+ )
192
+ end
193
+
194
+ it 'matches vertically, partially existing table' do
195
+ expect(rendered).to match_table %(
196
+ +----------+----------+----------+
197
+ | Quantity | Product | Price |
198
+ +----------+----------+----------+
199
+ | 1 | Computer | 42,00 € |
200
+ +----------+----------+----------+
201
+ )
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,8 @@
1
+ require 'codeclimate-test-reporter'
2
+ CodeClimate::TestReporter.start
3
+
4
+ require 'view_matchers'
5
+
6
+ RSpec.configure do |config|
7
+ config.include ViewMatchers
8
+ end
@@ -0,0 +1,16 @@
1
+ $:.push File.join(File.dirname(__FILE__), 'lib')
2
+ require 'view_matchers/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'view-matchers'
6
+ s.version = ViewMatchers::VERSION
7
+ s.date = Time.now.strftime('%Y-%m-%d')
8
+ s.summary = 'RSpec matchers for ascii tables and form fields.'
9
+ s.description = 'Expressive RSpec matchers for ascii tables and form fields.'
10
+ s.authors = ['Tom König']
11
+ s.email = 'hi@tomknig.de'
12
+ s.files = `git ls-files`.split($/)
13
+ s.require_paths = ['lib']
14
+ s.homepage = 'https://github.com/TomKnig/view-matchers'
15
+ s.license = 'MIT'
16
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: view-matchers
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom König
@@ -15,7 +15,26 @@ email: hi@tomknig.de
15
15
  executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
18
- files: []
18
+ files:
19
+ - ".gitignore"
20
+ - ".ruby-version"
21
+ - ".travis.yml"
22
+ - Gemfile
23
+ - Gemfile.lock
24
+ - LICENSE
25
+ - README.md
26
+ - lib/view_matchers.rb
27
+ - lib/view_matchers/form_matcher.rb
28
+ - lib/view_matchers/form_matcher/form.rb
29
+ - lib/view_matchers/table_matcher.rb
30
+ - lib/view_matchers/table_matcher/ascii_table.rb
31
+ - lib/view_matchers/table_matcher/html_table.rb
32
+ - lib/view_matchers/table_matcher/table.rb
33
+ - lib/view_matchers/version.rb
34
+ - spec/matchers/form_matcher_spec.rb
35
+ - spec/matchers/table_matcher_spec.rb
36
+ - spec/spec_helper.rb
37
+ - view-matchers.gemspec
19
38
  homepage: https://github.com/TomKnig/view-matchers
20
39
  licenses:
21
40
  - MIT