pouch 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/pouch/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pouch
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
data/lib/pouch.rb CHANGED
@@ -1,5 +1,81 @@
1
1
  require "pouch/version"
2
2
 
3
3
  module Pouch
4
- # Your code goes here...
4
+
5
+ class ContextualReplacementError < StandardError; end
6
+
7
+ def self.included base
8
+ base.extend self
9
+ end
10
+
11
+ def initialize browser, start = false, opts = {}
12
+ if start.is_a?(Hash) && opts.empty?
13
+ opts = start
14
+ start = false
15
+ end
16
+
17
+ @browser = browser
18
+ @context = standardize opts[:context] if opts[:context]
19
+ visit if self.respond_to?(:visit) && start
20
+ contextualize_methods
21
+ end
22
+
23
+ def browser
24
+ @browser
25
+ end
26
+
27
+ def context
28
+ @context
29
+ end
30
+
31
+ def page_url= str
32
+ define_method :visit do
33
+ self.browser.goto str
34
+ end
35
+ end
36
+
37
+ def element tag, name, identifier, *args, &block
38
+ define_method name do
39
+ return browser.element_for tag, identifier unless block_given?
40
+ block.call browser.send('element_for', tag, identifier), *args
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def contextualize_methods
47
+ return unless context
48
+ context.each_with_object([]) do |ctxt, array|
49
+ next unless array.flatten.empty?
50
+ array << match_and_replace(ctxt)
51
+ end
52
+ end
53
+
54
+ def match_and_replace context
55
+ get_match(context).map{ |mthd| self.method mthd }.each{ |mthd| replace_method mthd, context }
56
+ end
57
+
58
+ def get_match context
59
+ methods.select{ |mthd| mthd.to_s.start_with? "#{context}_" }.each_with_object([]) do |mthd, array|
60
+ unless respond_to? mthd.to_s.gsub("#{context}_", "")
61
+ raise ContextualReplacementError, "#{self.class} defined no standard method for replacement '#{mthd}'"
62
+ end
63
+ array << mthd
64
+ end
65
+ end
66
+
67
+ def replace_method method, context
68
+ (class << self; self; end).class_eval{ define_method method.name.to_s.gsub("#{context}_",""), method }
69
+ end
70
+
71
+ def standardize context
72
+ context.map!{ |c| standardize c } if context.kind_of? Array
73
+
74
+ if [Array, String, Symbol].include? context.class
75
+ [context].flatten.map(&:to_s)
76
+ else
77
+ raise "Cannot define Pouch context as #{context.class}"
78
+ end
79
+ end
80
+
5
81
  end
data/pouch.gemspec CHANGED
@@ -18,6 +18,9 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_runtime_dependency "watir-webdriver", "~> 0.6.11"
22
+
21
23
  spec.add_development_dependency "bundler", "~> 1.7"
22
24
  spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec", "~> 3.0.0"
23
26
  end
@@ -0,0 +1,168 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pouch do
4
+
5
+ describe ".included" do
6
+ class Page; end
7
+
8
+ it "extends Pouch onto the base class" do
9
+ expect(Page).to receive(:extend).with(Pouch)
10
+ Page.send(:include, Pouch)
11
+ end
12
+ end
13
+
14
+ describe "#initialize" do
15
+ class Page2; include Pouch; end
16
+
17
+ it "creates @browser variable" do
18
+ obj = Page2.new 'webdriver'
19
+ expect(obj.instance_variable_get :@browser).to eq 'webdriver'
20
+ end
21
+
22
+ context "when instance does not respond to #visit" do
23
+ it "doesn't navigate to page_url if start=true" do
24
+ driver = double 'webdriver'
25
+ expect(driver).to_not receive(:goto).with('url')
26
+ Page2.new driver, true, context: 'test'
27
+ end
28
+
29
+ it "doesn't navigate to page_url if start=false" do
30
+ driver = double 'webdriver'
31
+ expect(driver).to_not receive(:goto).with('url')
32
+ Page2.new driver, false
33
+ end
34
+ end
35
+
36
+ context "when instance responds to #visit" do
37
+ it "doesn't navigate to page_url if start=false" do
38
+ Page2.send :page_url=, 'url'
39
+ driver = double 'webdriver'
40
+ expect(driver).to_not receive(:goto)
41
+ Page2.new driver, false
42
+ end
43
+
44
+ it "navigates to page_url if start=true" do
45
+ driver = double 'webdriver'
46
+ expect(driver).to receive(:goto).with('url')
47
+ Page2.new driver, true, context: 'test'
48
+ end
49
+ end
50
+
51
+ context "with context" do
52
+ obj = ->(context){ Page2.new 'webdriver', context: context }
53
+
54
+ it "defines @context with String argument" do
55
+ expect(obj.call('my_context').instance_variable_get :@context).to eq ['my_context']
56
+ end
57
+
58
+ it "defines @context with Array argument" do
59
+ expect(obj.call(['my_context']).instance_variable_get :@context).to eq ['my_context']
60
+ end
61
+
62
+ it "defines @context with Symbol argument" do
63
+ expect(obj.call(:my_context).instance_variable_get :@context).to eq ['my_context']
64
+ end
65
+
66
+ it "defines @context with two Strings" do
67
+ expect(obj.call(['one', 'two']).instance_variable_get :@context).to eq ['one', 'two']
68
+ end
69
+
70
+ it "defines @context with two Arrays" do
71
+ expect(obj.call([['one'], ['two']]).instance_variable_get :@context).to eq ['one', 'two']
72
+ end
73
+
74
+ it "defines @context with two Symbols" do
75
+ expect(obj.call([:one, :two]).instance_variable_get :@context).to eq ['one', 'two']
76
+ end
77
+
78
+ it "defines @context with one String and one Array" do
79
+ expect(obj.call(['one', [:two]]).instance_variable_get :@context).to eq ['one', 'two']
80
+ end
81
+
82
+ it "defines @context with combination of Array, String, and Symbol" do
83
+ given = [:one, 'two', [:three, [:four, 'five'], :six], 'seven', ['eight', [['nine', [:ten]]]]]
84
+ expected = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']
85
+ expect(obj.call(given).instance_variable_get :@context).to eq expected
86
+ end
87
+
88
+ it "raises StandardError with Hash argument" do
89
+ expect{ obj.call({}) }.to raise_error(StandardError, /Hash/)
90
+ end
91
+
92
+ it "raises StandardError if one argument is a Number" do
93
+ expect{ obj.call(['one', 2]) }.to raise_error(StandardError, /Fixnum/)
94
+ end
95
+ end
96
+ end
97
+
98
+ class Page3
99
+ include Pouch
100
+ element(:a, :generic, id: 'generic')
101
+ element(:a, :blocked, id: 'blocked'){ |link| link.href }
102
+ element(:a, :different_generic, id: 'generic-diff')
103
+ element(:a, :different_blocked, id: 'blocked-diff'){ |link| link.href }
104
+ element(:a, :what_replacement, id: 'no-match')
105
+ end
106
+
107
+ describe "#browser" do
108
+ it "returns the browser instance" do
109
+ obj = Page3.new 'webdriver'
110
+ expect(obj.browser).to eq 'webdriver'
111
+ end
112
+ end
113
+
114
+ describe "#context" do
115
+ it "returns the page object context" do
116
+ obj = Page3.new 'webdriver', context: ['one', :two, ['three']]
117
+ expect(obj.context).to eq ['one', 'two', 'three']
118
+ end
119
+ end
120
+
121
+ describe "#element" do
122
+ let(:browser){ double 'webdriver' }
123
+ let(:element){ double 'html_link' }
124
+ let(:page){ Page3.new browser }
125
+ let(:diff){ Page3.new browser, context: 'different' }
126
+ let(:what){ Page3.new browser, context: 'what' }
127
+
128
+ it "returns the link element by default" do
129
+ expect(browser).to receive(:element_for).with(:a, id:'generic').and_return(element)
130
+ expect(page.generic).to eq element
131
+ end
132
+
133
+ it "returns an element that can be clicked" do
134
+ expect(browser).to receive(:element_for).with(:a, id:'generic').and_return(element)
135
+ expect(element).to receive(:click)
136
+ page.generic.click
137
+ end
138
+
139
+ it "returns the result of the definition block" do
140
+ expect(browser).to receive(:element_for).with(:a, id:'blocked').and_return(element)
141
+ expect(element).to receive(:href).and_return("www.test.com")
142
+ expect(page.blocked).to eq "www.test.com"
143
+ end
144
+
145
+ context "with context" do
146
+ it "uses the replacement method" do
147
+ expect(browser).to receive(:element_for).with(:a, id:'generic-diff').and_return(element)
148
+ expect(diff.generic).to eq element
149
+ end
150
+
151
+ it "uses the replacement method with definition block" do
152
+ expect(browser).to receive(:element_for).with(:a, id:'blocked-diff').and_return(element)
153
+ expect(element).to receive(:href).and_return("www.diff.com")
154
+ expect(diff.blocked).to eq "www.diff.com"
155
+ end
156
+
157
+ it "uses the standard method when context matches no replacement" do
158
+ expect(browser).to receive(:element_for).with(:a, id:'generic').and_return(element)
159
+ expect(Page3.new(browser, context: 'test').generic).to eq element
160
+ end
161
+
162
+ it "throws an error with replacement but no standard method" do
163
+ expect{ what.replacement }.to raise_error Pouch::ContextualReplacementError, /Page3 defined no standard method for replacement/
164
+ end
165
+ end
166
+ end
167
+
168
+ end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift(File.expand_path '../../lib', __FILE__)
2
+
3
+ require 'pouch'
4
+ require 'rspec'
5
+
6
+ RSpec.configure do |config|
7
+ config.order = 'default'
8
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pouch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-11-21 00:00:00.000000000 Z
12
+ date: 2014-11-26 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: watir-webdriver
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.6.11
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.6.11
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: bundler
16
32
  requirement: !ruby/object:Gem::Requirement
@@ -43,6 +59,22 @@ dependencies:
43
59
  - - ~>
44
60
  - !ruby/object:Gem::Version
45
61
  version: '10.0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 3.0.0
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: 3.0.0
46
78
  description: A flexible page object DSL for responsive UI testing via automated browsers
47
79
  and devices
48
80
  email:
@@ -59,6 +91,8 @@ files:
59
91
  - lib/pouch.rb
60
92
  - lib/pouch/version.rb
61
93
  - pouch.gemspec
94
+ - spec/pouch_spec.rb
95
+ - spec/spec_helper.rb
62
96
  homepage: https://github.com/jdenen/pouch
63
97
  licenses:
64
98
  - MIT
@@ -84,5 +118,7 @@ rubygems_version: 1.8.23.2
84
118
  signing_key:
85
119
  specification_version: 3
86
120
  summary: A flexible page object DSL for responsive UI testing
87
- test_files: []
121
+ test_files:
122
+ - spec/pouch_spec.rb
123
+ - spec/spec_helper.rb
88
124
  has_rdoc: