fracture 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in fracture.gemspec
4
+ gemspec
@@ -0,0 +1,186 @@
1
+ # Fracture
2
+ Unified view testing for your view or controller specs.
3
+
4
+ Fracture allows you to define text or selector once at the top of a spec file. It also allows grouping of multiple text or selectors snippets using one label.
5
+
6
+ Defining what you are looking for in one place prevents issues when a name (or selector) you are searching for is changed on a view which would only result in one failing spec, the other spec checking for the non exisitence would not fail so you would not find this 'always' passing spec.
7
+
8
+
9
+ ### Example
10
+
11
+ A simple example why would you use the fracture gem, assume you have the following tests (without Fracture)
12
+
13
+ context "admin"
14
+ ```ruby
15
+ response.body.should have_text("Edit")
16
+ ```
17
+ ...
18
+
19
+ (Somewhere further down in your spec file)
20
+
21
+ ...
22
+
23
+ context "user"
24
+ ```ruby
25
+ response.body.should_not have_text("Edit")
26
+ ```
27
+ If the word 'Edit' was changed in your view to 'Modify' the first test would fail although the second test would not fail. In a small spec this may be obvious to see although in a large file it might not be found. This would leave you with a never failing spec and if the logic controlling the display of this text broke and allowed for it to display when you are a user this would never be detected.
28
+
29
+ ####With Fracture:
30
+ You define the text "Edit" once at the top of your spec and now it can be used multiple times within the spec. If you change the text in the view, you only need to change the Fracture.define_text(:show_edit_button, "Modify") and all test using that definition will change.
31
+ ```ruby
32
+ Fracture.define_text(:show_edit_button, "Edit")
33
+ ```
34
+ context "admin"
35
+ ```ruby
36
+ response.body.should have_fracture(:show_edit_button)
37
+ ```
38
+ context "user"
39
+ ```ruby
40
+ response.body.should_not have_fracture(:show_edit_button)
41
+ ```
42
+
43
+ ## Installation:
44
+ Gemfile
45
+ ```
46
+ gem "fracture"
47
+ ```
48
+
49
+ ## Usage:
50
+ spec_helper.rb
51
+ ```ruby
52
+ config.after :all do
53
+ Fracture.clear
54
+ end
55
+ ```
56
+ This is to clear the set Fractures between each spec file
57
+
58
+
59
+ #### In your spec
60
+ If you want to test views from the controller spec you will need to add *render_views*, fracture will also work within view specs.
61
+
62
+ ```ruby
63
+ require 'spec_helper'
64
+
65
+ describe ContactsController do
66
+ render_views
67
+
68
+ Fracture.define_text(:add, "New")
69
+
70
+ context "as admin" do
71
+ describe "as an admin" do
72
+ it "index" do
73
+ login_as :admin # psuedo code for example
74
+ get :index
75
+ response.body.should have_fracture(:add)
76
+ end
77
+ end
78
+ end
79
+
80
+ context "as user" do
81
+ describe "as an user" do
82
+ it "index" do
83
+ login_as :user # psuedo code for example
84
+ get :index
85
+ response.body.should have_fracture(:add)
86
+ end
87
+ end
88
+ end
89
+ end
90
+ ```
91
+
92
+ ## Definitions
93
+ ### Text
94
+ Single
95
+ ```ruby
96
+ Fracture.define_text(:edits, "Edit")
97
+ ```
98
+ Multiple
99
+ ```ruby
100
+ Fracture.define_text(:edits, "Edit", "Edit All")
101
+ ```
102
+ ### Selector
103
+ ```ruby
104
+ Fracture.define_selector(:label_1, "#an_id", ".a_class", ".another_class")
105
+ ```
106
+
107
+ Currently there is no way to build text and selectors into one definition (future feature). Another future feature will be to support 'within'.
108
+
109
+ ## Matchers
110
+ Example Definitions
111
+ ```ruby
112
+ Fracture.define_text(:label_1, "Fred")
113
+ Fracture.define_text(:label_2, "Barney", "Betty")
114
+ Fracture.define_text(:label_3, "Wilma")
115
+ ```
116
+
117
+ Page should contain "Barney" and "Betty". Ignores any other definitions
118
+ ```ruby
119
+ response.body.should have_fracture(:label_2)
120
+ ```
121
+
122
+ Page should contain "Barney", "Betty", "Fred" and "Wilma"
123
+ ```ruby
124
+ response.body.should have_fracture(:label_1, :label_2, :label_3)
125
+ ```
126
+ or
127
+ ```ruby
128
+ response.body.should have_all_fractures
129
+ ```
130
+
131
+ Page should contain "Barney" and "Betty" and not "Fred" or "Wilma"
132
+ ```ruby
133
+ response.body.should have_only_fractures(:label_2)
134
+ ```
135
+
136
+ Page should contain "Barney", "Betty", "Fred" and not "Wilma"
137
+ ```ruby
138
+ response.body.should have_all_fractures_except(:label_3)
139
+ ```
140
+
141
+ ### Forms
142
+ Check to see if there is a form
143
+ ```ruby
144
+ response.body.should have_a_form
145
+ ```
146
+ Check to see if its a new form or editing (checks method is POST or PUT)
147
+ ```ruby
148
+ response.body.should have_a_form.that_is_new
149
+ response.body.should have_a_form.that_is_edit
150
+ ```
151
+ Check to path form posts to
152
+ ```ruby
153
+ response.body.should have_a_form.that_is_new.with_path_of("/tickets")
154
+ response.body.should have_a_form.with_path_of(tickets_path)
155
+ ```
156
+
157
+
158
+ ## All Methods:
159
+
160
+ * have_fracture(*labels)
161
+ * have_all_fractures
162
+ * have_all_fractures_except(*labels)
163
+ * have_only_fractures(*labels)
164
+ * have_a_form
165
+ - that_is_new
166
+ - that_is_edit
167
+ - with_path_of(path)
168
+
169
+ # TODO
170
+
171
+ * Support text and selector in one fracture
172
+
173
+ ## Contributing
174
+
175
+ 1. Fork it
176
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
177
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
178
+ 4. Push to the branch (`git push origin my-new-feature`)
179
+ 5. Create new Pull Request
180
+
181
+
182
+
183
+
184
+
185
+
186
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "fracture/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "fracture"
7
+ s.version = FractureVersion::VERSION
8
+ s.authors = ["Nigel Rausch"]
9
+ s.email = ["nigelr@brisbanerails.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Unified View testing within Views or Controllers for RSpec}
12
+ s.description = %q{Fracture allows you to define and group view text or selectors in one place (at the top of a spec) and then refer to them with labels. This prevents issues when checking for existence and non existence of text/selectors if the views value changes only one spec will fail, using fracture you will update both instances}
13
+
14
+ s.rubyforge_project = "fracture"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency "nokogiri"
22
+ s.add_runtime_dependency "rspec"
23
+
24
+ s.add_development_dependency "rake"
25
+ end
@@ -0,0 +1,4 @@
1
+ require "fracture/version"
2
+ require "fracture/fracture"
3
+ require "rspec"
4
+ require "fracture/matchers/matcher.rb"
@@ -0,0 +1,112 @@
1
+ class Fracture
2
+ attr_accessor :label, :items, :is_text
3
+
4
+ def initialize label, items, is_text
5
+ self.label = label
6
+ self.items = Array(items)
7
+ self.is_text = is_text
8
+ end
9
+
10
+ def self.define_text label, *items
11
+ @all ||= {}
12
+ raise "#{label} has already been defined" if @all[label.to_s]
13
+ @all[label.to_s] = self.new(label, items.flatten, true)
14
+ end
15
+
16
+ def self.define_selector label, *items
17
+ @all ||= {}
18
+ raise "#{label} has already been defined" if @all[label.to_s]
19
+ @all[label.to_s] = self.new(label, items.flatten, false)
20
+ end
21
+
22
+ def text?
23
+ !!is_text
24
+ end
25
+
26
+ def self.find label
27
+ #if labels.is_a? Array
28
+ # ret = []
29
+ # labels.map do |label|
30
+ # p label
31
+ # ret = all[label.to_s]
32
+ # raise "Fracture with Label of '#{label}' was not found" unless ret
33
+ # end
34
+ # p ret
35
+ #else
36
+ raise "No Fractures have been defined" if all.empty?
37
+ ret = all[label.to_s]
38
+ raise "Fracture with Label of '#{label}' was not found" unless ret
39
+ #end
40
+ ret
41
+ end
42
+
43
+ def self.all
44
+ @all || {}
45
+ end
46
+
47
+ def self.clear
48
+ @all = {}
49
+ end
50
+
51
+ def self.list_to_s items
52
+ items.map { |item| item.to_s }
53
+ end
54
+
55
+ def self.have_only_test page, is_not, only_fractures
56
+ test_fractures page, is_not, only_fractures, all_keys_less(only_fractures)
57
+ end
58
+
59
+ def self.have_all_except_test page, is_not, except_fractures
60
+ test_fractures page, is_not, all_keys_less(except_fractures), except_fractures
61
+ end
62
+
63
+ def self.all_keys_less fractures
64
+ all.keys - list_to_s(Array(fractures).flatten)
65
+ end
66
+
67
+ def do_check page, label
68
+ #page = page.response.body if page.is_a? CompaniesController
69
+ page = Nokogiri::HTML.parse(page)
70
+ if text?
71
+ page.text.include?(label)
72
+ else
73
+ page.at label
74
+ end
75
+ end
76
+
77
+ def self.test_fractures(page, is_not, fracture_labels, reverse_fracture_labels=[])
78
+ failures = {}
79
+ failures[:should] = []
80
+ failures[:should_not] = []
81
+ Array(fracture_labels).flatten.each do |fracture_label|
82
+ fracture = Fracture.find(fracture_label)
83
+ fracture.items.each do |label|
84
+ if is_not
85
+ if fracture.do_check(page, label)
86
+ failures[:should_not] << {fracture_label: fracture_label, label: label}
87
+ end
88
+ else
89
+ unless fracture.do_check(page, label)
90
+ failures[:should] << {fracture_label: fracture_label, label: label}
91
+ end
92
+ end
93
+ end
94
+ end
95
+ Array(reverse_fracture_labels).flatten.each do |fracture_label|
96
+ fracture = Fracture.find(fracture_label)
97
+ fracture.items.each do |label|
98
+ unless is_not
99
+ if fracture.do_check(page, label)
100
+ failures[:should_not] << {fracture_label: fracture_label, label: label}
101
+ end
102
+ else
103
+ unless fracture.do_check(page, label)
104
+ failures[:should] << {fracture_label: fracture_label, label: label}
105
+ end
106
+ end
107
+ end
108
+ end
109
+ failures.merge!(passed: (failures[:should].empty? && failures[:should_not].empty?))
110
+ failures
111
+ end
112
+ end
@@ -0,0 +1,113 @@
1
+ RSpec::Matchers.define :have_fracture do |*fracture_labels|
2
+ match do |page|
3
+ @results = Fracture.test_fractures page, false, fracture_labels, nil
4
+ @results[:passed]
5
+ end
6
+
7
+ match_for_should_not do |page|
8
+ @results = Fracture.test_fractures page, true, fracture_labels, nil
9
+ @results[:passed]
10
+ end
11
+
12
+ failure_message_for_should { |actual| common_error(actual, @results) }
13
+ failure_message_for_should_not { |actual| common_error(actual, @results) }
14
+ end
15
+
16
+ RSpec::Matchers.define :have_all_fractures do
17
+ match do |page|
18
+ @results = Fracture.test_fractures page, false, Fracture.all.keys, nil
19
+ @results[:passed]
20
+ end
21
+
22
+ match_for_should_not do |page|
23
+ @results = Fracture.test_fractures page, true, Fracture.all.keys, nil
24
+ @results[:passed]
25
+ end
26
+
27
+ failure_message_for_should { |actual| common_error(actual, @results) }
28
+ failure_message_for_should_not { |actual| common_error(actual, @results) }
29
+ end
30
+
31
+ RSpec::Matchers.define :have_all_fractures_except do |*fracture_labels|
32
+ match do |page|
33
+ @results = Fracture.have_all_except_test(page, false, fracture_labels)
34
+ @results[:passed]
35
+ end
36
+
37
+ match_for_should_not do |page|
38
+ @results = Fracture.have_all_except_test(page, true, fracture_labels)
39
+ @results[:passed]
40
+ end
41
+
42
+ failure_message_for_should { |actual| common_error(actual, @results) }
43
+ failure_message_for_should_not { |actual| common_error(actual, @results) }
44
+ end
45
+
46
+ RSpec::Matchers.define :have_only_fractures do |*fracture_labels|
47
+ match do |page|
48
+ @results = Fracture.have_only_test(page, false, fracture_labels)
49
+ @results[:passed]
50
+ end
51
+
52
+ match_for_should_not do |page|
53
+ @results = Fracture.have_only_test(page, true, fracture_labels)
54
+ @results[:passed]
55
+ end
56
+
57
+ failure_message_for_should { |actual| common_error(actual, @results) }
58
+ failure_message_for_should_not { |actual| common_error(actual, @results) }
59
+ end
60
+
61
+ def common_error(actual, results)
62
+ errors = ""
63
+ unless results[:should].empty?
64
+ errors += "expected to find '#{results[:should].map { |i| i[:label] }.join(", ")}'"
65
+ end
66
+ unless results[:should_not].empty?
67
+ errors += "expected not to find '#{results[:should_not].map { |i| i[:label] }.join(", ")}'"
68
+ end
69
+ errors += "\non page of\n #{actual}"
70
+ end
71
+
72
+ RSpec::Matchers.define :have_a_form do
73
+ match do |page|
74
+ page = Nokogiri::HTML.parse(page)
75
+ @edit_found = page.at("input[type='hidden'][name='_method'][value='put']")
76
+ @has_form = page.at("form[method='post']")
77
+ #TODO refactor this
78
+ #@found_action = page.at("form[action]").try(:attributes).try(:fetch, "action", nil).try(:value)
79
+ @found_action = page.at("form[action]") &&
80
+ page.at("form[action]").attributes &&
81
+ page.at("form[action]").attributes.fetch("action", nil) &&
82
+ page.at("form[action]").attributes.fetch("action", nil).value
83
+ @has_form && !(@new_form && @edit_found) && (!@edit_form || @edit_found) && (!@expected_path || (@found_action == @expected_path))
84
+ end
85
+
86
+ match_for_should_not do |page|
87
+ raise "Cannot use should_not chained with .is_for, .that_is_edit or .with_path_of " if @new_form || @edit_form || @expected_path
88
+ page = Nokogiri::HTML.parse(page)
89
+ !page.at("form[method='post']")
90
+ end
91
+
92
+ #chain(:for_action) { |action #new:edit| @new_form = true }
93
+ chain(:that_is_new) { @new_form = true }
94
+ chain(:that_is_edit) { @edit_form = true }
95
+ #chain(:with_path) { |path| @expected_path = path }
96
+ chain(:with_path_of) { |path| @expected_path = path }
97
+ failure_message_for_should do
98
+ ret = case
99
+ when !@has_form
100
+ "expected to find a form on the page\n"
101
+ when @new_form && @edit_found
102
+ 'Form is an edit'
103
+ when @edit_form && !@edit_found
104
+ 'Form is not an edit'
105
+ when @expected_path
106
+ "Expected to find forms action of '/#{@expected_path}' but found '/#@found_action'"
107
+ else
108
+ raise "Unexpected have_form state."
109
+ end
110
+ ret
111
+ end
112
+ failure_message_for_should_not { "expected not to find a form on the page" }
113
+ end
@@ -0,0 +1,3 @@
1
+ module FractureVersion
2
+ VERSION = "0.9.0"
3
+ end
@@ -0,0 +1,75 @@
1
+ require "rspec"
2
+ require "fracture/fracture"
3
+ require 'nokogiri'
4
+
5
+
6
+ describe Fracture do
7
+
8
+ before { Fracture.clear }
9
+
10
+ context "without data" do
11
+ it("should be empty before use") { Fracture.all.should == {} }
12
+ it "should not fail when no data set" do
13
+ expect {Fracture.find(:nothing) }.to raise_error(RuntimeError, /No Fractures have been defined/)
14
+ end
15
+ end
16
+
17
+ context "with data" do
18
+ before do
19
+ @first = Fracture.define_text(:a, "a")
20
+ Fracture.define_text(:bc, "b", "c")
21
+ Fracture.define_selector(:x, "x")
22
+ Fracture.define_selector(:yz, "y", "z")
23
+ end
24
+
25
+ describe "#clear" do
26
+ before { Fracture.clear }
27
+ it("should clear all") { Fracture.all.should == {} }
28
+ end
29
+
30
+ describe ".text?" do
31
+ it("should be text search") { Fracture.find(:a).text?.should be_true }
32
+ it("should not be text search") { Fracture.find(:x).text?.should be_false }
33
+ end
34
+
35
+ context "reuse" do
36
+ context "of same text label" do
37
+ it("should raise error if a label is reused") { expect { Fracture.define_text(:bc, "reused") }.to raise_error(RuntimeError, /bc has already been defined/) }
38
+ end
39
+ context "of same selector label" do
40
+ it("should raise error if a label is reused") { expect { Fracture.define_selector(:x, "reused") }.to raise_error(RuntimeError, /x has already been defined/) }
41
+ end
42
+ end
43
+
44
+ context "reuse of same text or selector" do
45
+ it "should display warning when same text is defined"
46
+ it "should display warning when same label is defined"
47
+ end
48
+
49
+ describe "#find" do
50
+ context "existing" do
51
+ it("should find label using symbol") { Fracture.find(:a).items == ["a"] }
52
+ it("should find label using string") { Fracture.find("a").items == ["a"] }
53
+ end
54
+ context "should raise error if label does not exist" do
55
+ it("single") { expect { Fracture.find(:ab) }.to raise_error(RuntimeError, /Fracture with Label of 'ab' was not found/) }
56
+ end
57
+ end
58
+
59
+ describe "#all" do
60
+ context "should return all Fractures" do
61
+ subject {Fracture.all }
62
+ its(:length) {should == 4}
63
+ its(:keys) {should =~ ["a", "bc", "x", "yz"]}
64
+ end
65
+ end
66
+
67
+ #TODO move from matcher_spec
68
+ describe "test_fracture"
69
+
70
+ describe ".do_check" do
71
+ it("should find it") { @first.do_check("z a b", "a").should be_true }
72
+ it("should not find it") { @first.do_check("z b", "a").should be_false }
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,350 @@
1
+ require 'rspec'
2
+ require 'nokogiri'
3
+ require "fracture/fracture"
4
+ require "fracture/matchers/matcher"
5
+
6
+ describe Fracture do
7
+ context "form" do
8
+ context "when no form exists" do
9
+ before { @page = "<p>not a form</p>" }
10
+ it("should not have a form") { @page.should_not have_a_form }
11
+ it("should have a form") { expect { @page.should have_a_form }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected to find a form on the page/) }
12
+ end
13
+ context "when form exists" do
14
+ before { @page = "<form method='post' action='/companies'>" }
15
+ it("should have a form") { @page.should have_a_form }
16
+ it("should not have a form") { expect { @page.should_not have_a_form }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected not to find a form on the page/) }
17
+ context "that_is_new" do
18
+ it("should be a new form") { @page.should have_a_form.that_is_new }
19
+ it("should not be an edit") { expect { @page.should have_a_form.that_is_edit }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /Form is not an edit/) }
20
+ end
21
+ context "that_is_edit" do
22
+ before { @page += "<input type='hidden' name='_method' value='put'>" }
23
+ it "should not be a new form" do
24
+ expect { @page.should have_a_form.that_is_new }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /Form is an edit/)
25
+ end
26
+ it("should be an edit form") { @page.should have_a_form.that_is_edit }
27
+ it("should have a form") { @page.should have_a_form }
28
+ end
29
+ context "with_path_of" do
30
+ it "should match path" do
31
+ @page.should have_a_form.with_path_of("/companies")
32
+ end
33
+ it "should not match path" do
34
+ expect { @page.should have_a_form.with_path_of("/fred") }.to raise_error(RSpec::Expectations::ExpectationNotMetError, "Expected to find forms action of '//fred' but found '//companies'")
35
+ end
36
+ end
37
+ end
38
+ context "not support should_not when chained" do
39
+ it "should raise error if that_is_edit" do
40
+ expect { @page.should_not have_a_form.that_is_edit }.to raise_error(RuntimeError, "Cannot use should_not chained with .is_for, .that_is_edit or .with_path_of ")
41
+ end
42
+ it "should raise error if that_is_new" do
43
+ expect { @page.should_not have_a_form.that_is_new }.to raise_error(RuntimeError, "Cannot use should_not chained with .is_for, .that_is_edit or .with_path_of ")
44
+ end
45
+ it "should raise error if with_path_of" do
46
+ expect { @page.should_not have_a_form.with_path_of("/abc") }.to raise_error(RuntimeError, "Cannot use should_not chained with .is_for, .that_is_edit or .with_path_of ")
47
+ end
48
+ end
49
+ end
50
+
51
+ context "Fracture" do
52
+ it "non existent fracture label" do
53
+ expect { @page.should have_fracture(:dont_exist) }.to raise_error(RuntimeError, "Fracture with Label of 'dont_exist' was not found")
54
+ end
55
+
56
+ before do
57
+ Fracture.clear
58
+ @page = <<sample
59
+ <h1>Opening</h1>
60
+ <table>
61
+ <tr>
62
+ <th>abc</th>
63
+ <th>def</th>
64
+ </tr>
65
+ <tr>
66
+ <td class='left'>123</td>
67
+ <td id='second'>456</td>
68
+ </tr>
69
+ </table>
70
+ <p class='big'>Title 1</p>
71
+ The Main Body
72
+ sample
73
+
74
+ Fracture.define_text(:text_1, "Title 1")
75
+ Fracture.define_text(:text_2, "Main", "Opening")
76
+ end
77
+
78
+ let(:nsel_1) { Fracture.define_selector(:nsel_1, "table > td") }
79
+ let(:ntext_1) { Fracture.define_text(:ntext_1, "sex") }
80
+ let(:b11) { Fracture.define_text(:b11, "please") }
81
+ let(:bb1) { Fracture.define_text(:bb1, "Main", "sex") }
82
+ let(:bb2) { Fracture.define_text(:bb2, "Sex", "Main") }
83
+ let(:bb3) { Fracture.define_text(:bb3, "Sex", "please") }
84
+
85
+ context "when selector" do
86
+ describe "Fracture" do
87
+ before do
88
+ Fracture.define_selector(:sel_1, "tr>td:contains('123')")
89
+ Fracture.define_selector(:sel_2, "tr>th:contains('abc')", "tr>td:contains('456')")
90
+ end
91
+
92
+ it "should find sel_1" do
93
+ Fracture.test_fractures(@page, false, :sel_1).should == {passed: true, should: [], should_not: []}
94
+ end
95
+ it 'should find sel_2' do
96
+ Fracture.test_fractures(@page, false, :sel_2).should == {passed: true, should: [], should_not: []}
97
+ end
98
+ it "should not have sel_1 present" do
99
+ Fracture.test_fractures(@page, true, :sel_1).should == {passed: false,
100
+ should: [],
101
+ should_not: [{fracture_label: :sel_1, label: "tr>td:contains('123')"}]}
102
+ end
103
+ it "cant find nsel_1 on page" do
104
+ nsel_1
105
+ Fracture.test_fractures(@page, false, :nsel_1).should == {passed: false,
106
+ should: [{fracture_label: :nsel_1, :label => "table > td"}],
107
+ should_not: []}
108
+ end
109
+ it "should not find nsel_1 on page" do
110
+ nsel_1
111
+ Fracture.test_fractures(@page, true, :nsel_1).should == {passed: true,
112
+ should: [],
113
+ should_not: []}
114
+ end
115
+ end
116
+
117
+ context "have_fracture" do
118
+ it "should find fracture of :class_1" do
119
+ Fracture.define_selector(:class_1, "td.left")
120
+ @page.should have_fracture :class_1
121
+ end
122
+ it "should find fracture of :id_1" do
123
+ Fracture.define_selector(:id_1, "td#second")
124
+ @page.should have_fracture :id_1
125
+ end
126
+ it "should not find missing fracture" do
127
+ Fracture.define_selector(:id_2, "th#second")
128
+ @page.should_not have_fracture :id_2
129
+ end
130
+ it "should fail to find a fracture" do
131
+ Fracture.define_selector(:id_3, "th#second")
132
+ expect { @page.should have_fracture(:id_3) }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected to find 'th#second'/)
133
+ end
134
+ end
135
+ end
136
+
137
+ context "when text" do
138
+ describe "Fracture" do
139
+ context "when passing only one fracture list" do
140
+ context "should" do
141
+ context "when 1 fracture" do
142
+ it "1 found" do
143
+ Fracture.test_fractures(@page, false, :text_1).should == {passed: true, should: [], should_not: []}
144
+ end
145
+ it "2 found" do
146
+ Fracture.test_fractures(@page, false, :text_2).should == {passed: true, should: [], should_not: []}
147
+ end
148
+ it "1 not found" do
149
+ ntext_1
150
+ Fracture.test_fractures(@page, false, :ntext_1).should == {passed: false,
151
+ should: [{fracture_label: :ntext_1, label: "sex"}],
152
+ should_not: []}
153
+ end
154
+ it "2 not found" do
155
+ bb3
156
+ Fracture.test_fractures(@page, false, :bb3).should == {passed: false,
157
+ should: [{fracture_label: :bb3, label: "Sex"}, {fracture_label: :bb3, label: "please"}],
158
+ should_not: []}
159
+ end
160
+ it "1 not found and 1 found" do
161
+ bb1
162
+ Fracture.test_fractures(@page, false, :bb1).should == {passed: false,
163
+ should: [{fracture_label: :bb1, label: "sex"}],
164
+ should_not: []}
165
+ end
166
+ end
167
+ context "when list of 2 fractures" do
168
+ it "3 found" do
169
+ Fracture.test_fractures(@page, false, [:text_1, :text_2]).should == {passed: true, should: [], should_not: []}
170
+ end
171
+ it "2 not found" do
172
+ ntext_1
173
+ b11
174
+ Fracture.test_fractures(@page, false, [:ntext_1, :b11]).should == {passed: false,
175
+ should: [{:fracture_label => :ntext_1, :label => "sex"}, {:fracture_label => :b11, :label => "please"}],
176
+ should_not: []}
177
+ end
178
+ end
179
+ end
180
+ context "should_not" do
181
+ context "when 1 fracture" do
182
+ it "1 found (not)" do
183
+ Fracture.test_fractures(@page, true, :text_1).should == {passed: false,
184
+ should_not: [{fracture_label: :text_1, label: "Title 1"}],
185
+ should: []}
186
+ end
187
+ it "not found" do
188
+ ntext_1
189
+ Fracture.test_fractures(@page, true, :ntext_1).should == {passed: true, should: [], should_not: []}
190
+ end
191
+ it "not found multi" do
192
+ bb3
193
+ Fracture.test_fractures(@page, true, :bb3).should == {passed: true, should: [], should_not: []}
194
+ end
195
+ end
196
+ context "when list of 2 fractures" do
197
+ it "3 found" do
198
+ Fracture.test_fractures(@page, true, [:text_1, :text_2]).should == {passed: false,
199
+ should_not: [{:fracture_label => :text_1, :label => "Title 1"},
200
+ {:fracture_label => :text_2, :label => "Main"},
201
+ {:fracture_label => :text_2, :label => "Opening"}],
202
+ should: []}
203
+ end
204
+ it "2 not found" do
205
+ ntext_1
206
+ b11
207
+ Fracture.test_fractures(@page, true, [:ntext_1, :b11]).should == {passed: true, should: [], should_not: []}
208
+ end
209
+ end
210
+ end
211
+ end
212
+ context "when passing 2 fracture lists (should find and should not find)" do
213
+ context "should" do
214
+ it "exist 1 found and not exist 1 not found" do
215
+ ntext_1
216
+ Fracture.test_fractures(@page, false, [:text_1], [:ntext_1]).should == {passed: true, should: [], should_not: []}
217
+ end
218
+
219
+ it "should not find text_2" do
220
+ Fracture.test_fractures(@page, false, [:text_1], [:text_2]).should == {passed: false, should: [],
221
+ should_not: [{:fracture_label => :text_2, :label => "Main"}, {:fracture_label => :text_2, :label => "Opening"}]}
222
+ end
223
+ it "should not find text_1" do
224
+ ntext_1
225
+ Fracture.test_fractures(@page, false, [:ntext_1], [:text_1]).should == {passed: false, should:
226
+ [{:fracture_label => :ntext_1, :label => "sex"}], should_not: [{fracture_label: :text_1, label: "Title 1"}]}
227
+ end
228
+ end
229
+ context "when should_not" do
230
+ it "should not find ntext_1 and should find text_1 " do
231
+ ntext_1
232
+ Fracture.test_fractures(@page, true, [:ntext_1], [:text_1]).should == {passed: true, should: [], should_not: []}
233
+ end
234
+
235
+ it "exist 1 found and not exist 1 not found" do
236
+ ntext_1
237
+ Fracture.test_fractures(@page, true, [:text_1], [:ntext_1]).should == {passed: false,
238
+ should: [{:fracture_label => :ntext_1, :label => "sex"}],
239
+ should_not: [{fracture_label: :text_1, label: "Title 1"}]}
240
+ end
241
+ it "text_1 should_not appear on the page and text_2 should" do
242
+ Fracture.test_fractures(@page, true, [:text_1], [:text_2]).should == {passed: false,
243
+ should_not: [{fracture_label: :text_1, label: "Title 1"}],
244
+ should: []}
245
+ end
246
+ end
247
+ end
248
+ context "have_fracture" do
249
+ context "should" do
250
+ it "match single" do
251
+ @page.should have_fracture(:text_1)
252
+ end
253
+ it "should match multiple" do
254
+ @page.should have_fracture(:text_2)
255
+ end
256
+ it "should not match multiple when 2nd fracture item does not match" do
257
+ bb1
258
+ expect { @page.should have_fracture(:bb1) }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected to find 'sex'/)
259
+ end
260
+ it "should match with multiple arguments" do
261
+ @page.should have_fracture(:text_2, :text_1)
262
+ end
263
+ it "should not match with multiple argument when last item does not match" do
264
+ ntext_1
265
+ expect { @page.should have_fracture(:text_2, :text_1, :ntext_1) }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected to find 'sex'/)
266
+ end
267
+ it "should fail with missing element" do
268
+ ntext_1
269
+ expect { @page.should have_fracture(:ntext_1) }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected to find 'sex'/)
270
+ end
271
+ end
272
+ context "should not" do
273
+ it "fails not match single" do
274
+ expect { @page.should_not have_fracture(:text_1) }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected not to find 'Title 1'/)
275
+ end
276
+ it "should not match multiple when 2nd fracture item does exist" do
277
+ bb2
278
+ expect { @page.should_not have_fracture(:bb2) }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected not to find 'Main'/)
279
+ end
280
+ it "should fail when last fracture has items that exist on pag" do
281
+ bb2
282
+ bb3
283
+ expect { @page.should_not have_fracture(:bb3, :bb2) }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected not to find 'Main'/)
284
+ end
285
+ it "should fail when first fracture has items that exist on pag" do
286
+ bb2
287
+ bb3
288
+ expect { @page.should_not have_fracture([:bb2, :bb3]) }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected not to find 'Main'/)
289
+ end
290
+ it "should pass when no items exist" do
291
+ bb3
292
+ @page.should_not have_fracture(:bb3)
293
+ end
294
+ end
295
+ end
296
+ end
297
+ end
298
+
299
+ describe "have_all_fractures" do
300
+ it "all" do
301
+ @page.should have_all_fractures
302
+ end
303
+ it "not have :ntext_1" do
304
+ ntext_1
305
+ expect { @page.should have_all_fractures }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected to find 'sex'/)
306
+ end
307
+ it "not have any fractures" do
308
+ Fracture.clear
309
+ bb3
310
+ @page.should_not have_all_fractures
311
+ end
312
+ end
313
+
314
+ describe "have_all_fractures_except" do
315
+ it "should have all except ntext_1" do
316
+ ntext_1
317
+ @page.should have_all_fractures_except :ntext_1
318
+ end
319
+ it "fails when find text_2 on page" do
320
+ expect { @page.should have_all_fractures_except :text_2 }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected not to find 'Main, Opening'/)
321
+ end
322
+
323
+ it "fails when should_not finds text_1 on the page" do
324
+ expect { @page.should_not have_all_fractures_except :text_2 }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected not to find 'Title 1'/)
325
+ end
326
+
327
+ it "none" do
328
+ Fracture.clear
329
+ Fracture.define_text(:text_1, "Title 1")
330
+ @page.should_not have_all_fractures_except :text_1
331
+ end
332
+ end
333
+ describe "have_only_fractures" do
334
+ it "should have only text_1 and text_2" do
335
+ @page.should have_only_fractures :text_1, :text_2
336
+ end
337
+ it "should have only text_1 and text_2 and ignore ntext_1" do
338
+ ntext_1
339
+ @page.should have_only_fractures :text_1, :text_2
340
+ end
341
+ it "should raise error when one exists" do
342
+ expect { @page.should have_only_fractures :text_2 }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected not to find 'Title 1'/)
343
+ end
344
+ it "should raise error when expected item to exist" do
345
+ ntext_1
346
+ expect { @page.should have_only_fractures :text_1, :text_2, :ntext_1 }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected to find 'sex'/)
347
+ end
348
+ end
349
+ end
350
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fracture
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nigel Rausch
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
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: rspec
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: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
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
+ description: Fracture allows you to define and group view text or selectors in one
63
+ place (at the top of a spec) and then refer to them with labels. This prevents issues
64
+ when checking for existence and non existence of text/selectors if the views value
65
+ changes only one spec will fail, using fracture you will update both instances
66
+ email:
67
+ - nigelr@brisbanerails.com
68
+ executables: []
69
+ extensions: []
70
+ extra_rdoc_files: []
71
+ files:
72
+ - .gitignore
73
+ - Gemfile
74
+ - README.md
75
+ - Rakefile
76
+ - fracture.gemspec
77
+ - lib/fracture.rb
78
+ - lib/fracture/fracture.rb
79
+ - lib/fracture/matchers/matcher.rb
80
+ - lib/fracture/version.rb
81
+ - spec/fracture_spec.rb
82
+ - spec/matcher_spec.rb
83
+ homepage: ''
84
+ licenses: []
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project: fracture
103
+ rubygems_version: 1.8.24
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Unified View testing within Views or Controllers for RSpec
107
+ test_files:
108
+ - spec/fracture_spec.rb
109
+ - spec/matcher_spec.rb