page_magic 1.2.7 → 2.0.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.
- checksums.yaml +5 -5
- data/.rubocop.yml +23 -4
- data/.simplecov +5 -3
- data/.zsh_config +6 -0
- data/Dockerfile +11 -0
- data/Gemfile +13 -13
- data/Gemfile.lock +135 -144
- data/Makefile +17 -0
- data/README.md +48 -4
- data/Rakefile +12 -2
- data/VERSION +1 -1
- data/circle.yml +4 -2
- data/lib/active_support/core_ext/object/to_query.rb +84 -0
- data/lib/page_magic.rb +22 -20
- data/lib/page_magic/class_methods.rb +5 -2
- data/lib/page_magic/comparator.rb +37 -0
- data/lib/page_magic/comparator/fuzzy.rb +23 -0
- data/lib/page_magic/comparator/literal.rb +22 -0
- data/lib/page_magic/comparator/null.rb +26 -0
- data/lib/page_magic/comparator/parameter_map.rb +52 -0
- data/lib/page_magic/driver.rb +3 -0
- data/lib/page_magic/drivers.rb +6 -5
- data/lib/page_magic/drivers/poltergeist.rb +2 -0
- data/lib/page_magic/drivers/rack_test.rb +3 -1
- data/lib/page_magic/drivers/selenium.rb +4 -2
- data/lib/page_magic/element.rb +35 -15
- data/lib/page_magic/element/locators.rb +8 -5
- data/lib/page_magic/element/not_found.rb +38 -0
- data/lib/page_magic/element/query.rb +21 -20
- data/lib/page_magic/element/query/multiple_results.rb +21 -0
- data/lib/page_magic/element/query/prefetched_result.rb +26 -0
- data/lib/page_magic/element/query/single_result.rb +20 -0
- data/lib/page_magic/element/selector.rb +41 -16
- data/lib/page_magic/element/selector/methods.rb +18 -0
- data/lib/page_magic/element/selector/model.rb +21 -0
- data/lib/page_magic/element_context.rb +7 -21
- data/lib/page_magic/element_definition_builder.rb +20 -24
- data/lib/page_magic/elements.rb +65 -68
- data/lib/page_magic/elements/config.rb +103 -0
- data/lib/page_magic/elements/inheritance_hooks.rb +15 -0
- data/lib/page_magic/elements/types.rb +25 -0
- data/lib/page_magic/exceptions.rb +6 -1
- data/lib/page_magic/instance_methods.rb +8 -3
- data/lib/page_magic/mapping.rb +79 -0
- data/lib/page_magic/session.rb +15 -35
- data/lib/page_magic/session_methods.rb +3 -1
- data/lib/page_magic/transitions.rb +49 -0
- data/lib/page_magic/utils/string.rb +18 -0
- data/lib/page_magic/utils/url.rb +20 -0
- data/lib/page_magic/wait_methods.rb +3 -0
- data/lib/page_magic/watcher.rb +12 -17
- data/lib/page_magic/watchers.rb +31 -15
- data/page_magic.gemspec +17 -13
- data/spec/lib/active_support/core_ext/object/to_query_test.rb +78 -0
- data/spec/page_magic/class_methods_spec.rb +66 -37
- data/spec/page_magic/comparator/fuzzy_spec.rb +44 -0
- data/spec/page_magic/comparator/literal_spec.rb +41 -0
- data/spec/page_magic/comparator/null_spec.rb +35 -0
- data/spec/page_magic/comparator/parameter_map_spec.rb +75 -0
- data/spec/page_magic/driver_spec.rb +26 -28
- data/spec/page_magic/drivers/poltergeist_spec.rb +6 -7
- data/spec/page_magic/drivers/rack_test_spec.rb +6 -9
- data/spec/page_magic/drivers/selenium_spec.rb +11 -12
- data/spec/page_magic/drivers_spec.rb +38 -29
- data/spec/page_magic/element/locators_spec.rb +28 -25
- data/spec/page_magic/element/not_found_spec.rb +24 -0
- data/spec/page_magic/element/query/multiple_results_spec.rb +14 -0
- data/spec/page_magic/element/query/single_result_spec.rb +21 -0
- data/spec/page_magic/element/query_spec.rb +26 -45
- data/spec/page_magic/element/selector_spec.rb +120 -110
- data/spec/page_magic/element_context_spec.rb +47 -87
- data/spec/page_magic/element_definition_builder_spec.rb +14 -71
- data/spec/page_magic/element_spec.rb +256 -0
- data/spec/page_magic/elements/config_spec.rb +200 -0
- data/spec/page_magic/elements_spec.rb +90 -127
- data/spec/page_magic/instance_methods_spec.rb +65 -63
- data/spec/page_magic/mapping_spec.rb +181 -0
- data/spec/page_magic/session_methods_spec.rb +29 -25
- data/spec/page_magic/session_spec.rb +109 -199
- data/spec/page_magic/transitions_spec.rb +43 -0
- data/spec/page_magic/utils/string_spec.rb +29 -0
- data/spec/page_magic/utils/url_spec.rb +9 -0
- data/spec/page_magic/wait_methods_spec.rb +16 -22
- data/spec/page_magic/watcher_spec.rb +22 -0
- data/spec/page_magic/watchers_spec.rb +58 -62
- data/spec/page_magic_spec.rb +31 -30
- data/spec/spec_helper.rb +9 -2
- data/spec/support/shared_contexts.rb +3 -1
- data/spec/support/shared_examples.rb +17 -17
- metadata +101 -48
- data/lib/page_magic/element/query_builder.rb +0 -48
- data/lib/page_magic/element/selector_methods.rb +0 -13
- data/lib/page_magic/matcher.rb +0 -121
- data/spec/element_spec.rb +0 -249
- data/spec/page_magic/element/query_builder_spec.rb +0 -108
- data/spec/page_magic/matcher_spec.rb +0 -336
- data/spec/support/shared_contexts/files_context.rb +0 -7
- data/spec/support/shared_contexts/nested_elements_html_context.rb +0 -16
- data/spec/support/shared_contexts/rack_application_context.rb +0 -9
- data/spec/support/shared_contexts/webapp_fixture_context.rb +0 -39
- data/spec/watcher_spec.rb +0 -61
data/Makefile
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
.PHONY: help
|
|
2
|
+
DOCKER_IMAGE = lvl-up/page-magic
|
|
3
|
+
MOUNT_DIR = /page_magic
|
|
4
|
+
|
|
5
|
+
help:
|
|
6
|
+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
|
7
|
+
|
|
8
|
+
docker: ## build project docker image
|
|
9
|
+
docker build -t $(DOCKER_IMAGE) .
|
|
10
|
+
|
|
11
|
+
test: ## Run tests
|
|
12
|
+
docker run -v $(PWD):$(MOUNT_DIR) -w $(MOUNT_DIR) -t $(DOCKER_IMAGE) bundle exec rspec
|
|
13
|
+
|
|
14
|
+
build: docker ## build gem
|
|
15
|
+
rake build
|
|
16
|
+
|
|
17
|
+
all: docker test build ## run all targets before building gem
|
data/README.md
CHANGED
|
@@ -20,6 +20,25 @@ Well PageMagic might just be the answer!
|
|
|
20
20
|
|
|
21
21
|
Give it a try and let us know what you think! There will undoubtedly be things that can be improved and issues that
|
|
22
22
|
we are not aware of so your feedback/pull requests are greatly appreciated!
|
|
23
|
+
|
|
24
|
+
##Under the hood
|
|
25
|
+
Under the hood PageMagic uses the totally brilliant [Capybara](https://github.com/teamcapybara/capybara) to benefit from its amazing cross browser support.
|
|
26
|
+
|
|
27
|
+
PageMagic builds on top of Capybara to build resuable models for webpages and website structure.
|
|
28
|
+
|
|
29
|
+
##What about the other PageObject frameworks out there?
|
|
30
|
+
PageMagic isn't the first [PageObject](https://martinfowler.com/bliki/PageObject.html) framework to be written, indeed there are others out there that are totaly awesome e.g:
|
|
31
|
+
- [PageObject](https://github.com/cheezy/page-object)
|
|
32
|
+
- [SitePrism](https://github.com/natritmeyer/site_prism)
|
|
33
|
+
|
|
34
|
+
Whilst these APIs are great, PageMagic goes much further in the power it provides for:
|
|
35
|
+
- [modelling pages](defining-pages) and page components
|
|
36
|
+
- defining the [wait logic](#hooks) and [watchers](#watchers) that are required to build robust page objects that work reliably with javascript rich webpages.
|
|
37
|
+
- Supporting [page transitions](#page-mapping)
|
|
38
|
+
|
|
39
|
+
Check it out :)
|
|
40
|
+
|
|
41
|
+
|
|
23
42
|
# Contents
|
|
24
43
|
|
|
25
44
|
- [Installation](#installation)
|
|
@@ -40,7 +59,7 @@ we are not aware of so your feedback/pull requests are greatly appreciated!
|
|
|
40
59
|
- [Page mapping](#page-mapping)
|
|
41
60
|
- [Mapping against query string parameters](#mapping-against-query-string-parameters)
|
|
42
61
|
- [Mapping against fragment identifiers](#mapping-against-fragment-identifiers)
|
|
43
|
-
- [Loading pages from source](#loading-pages-from-source)
|
|
62
|
+
- [Loading pages/elements from source](#loading-pages/elements-from-source)
|
|
44
63
|
- [Watchers](#watchers)
|
|
45
64
|
- [Method watchers](#method-watchers)
|
|
46
65
|
- [Simple watchers](#simple-watchers)
|
|
@@ -157,6 +176,19 @@ After visiting a page you are will get a `Session` object. Elements can be acces
|
|
|
157
176
|
```ruby
|
|
158
177
|
page.search_field.set 'page_magic'
|
|
159
178
|
```
|
|
179
|
+
PageMagic sits on top of [Capybara](https://github.com/teamcapybara/capybara) and ultimately returns capybara elements elements for you interact with. Interacting with the element types above is done by calling the following methods:
|
|
180
|
+
|
|
181
|
+
element | method
|
|
182
|
+
--- | ---
|
|
183
|
+
text_field | set(String)
|
|
184
|
+
checkbox | set(Boolean)
|
|
185
|
+
radio | choose(String)
|
|
186
|
+
link | click
|
|
187
|
+
text_area | set(String)
|
|
188
|
+
select_list | select(String)
|
|
189
|
+
|
|
190
|
+
Typically you will not need to know much about Capybara itself but there will be times when you want to interact with elements at a lower level.In this case please see Capybara's [API](http://www.rubydoc.info/github/jnicklas/capybara/Capybara/Node/Element) For more information.
|
|
191
|
+
|
|
160
192
|
|
|
161
193
|
### Sub Elements
|
|
162
194
|
If your pages are complex you can use PageMagic to compose pages, their elements and subelements to as many levels as
|
|
@@ -349,16 +381,27 @@ against URL fragments.
|
|
|
349
381
|
browser.define_page_mappings PageMagic.mapping(fragment: string_or_regex) => ResultsPage
|
|
350
382
|
```
|
|
351
383
|
|
|
352
|
-
# Loading pages from source
|
|
384
|
+
# Loading pages/elements from source
|
|
353
385
|
PageMagic supports loading page objects using html source. This technique can be useful for getting quick feedback that
|
|
354
|
-
your templates correctly render based on your view objects. I.e you can test your templates in isolation.
|
|
386
|
+
your templates correctly render based on your view objects. I.e you can test your templates and partials/fragments in isolation.
|
|
355
387
|
```ruby
|
|
356
388
|
class MyPage
|
|
357
389
|
include PageMagic
|
|
390
|
+
element(:link, id: 'link_id')
|
|
358
391
|
#element definitions
|
|
359
392
|
end
|
|
360
393
|
|
|
361
394
|
page_instance = Page.load(html_string)
|
|
395
|
+
page_instance.link.text # returns the link text
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
class CustomElement < PageMagic::Element
|
|
399
|
+
element(:link, id: 'link_id')
|
|
400
|
+
#element definitions
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
page_element = CustomElement.load(html_string)
|
|
404
|
+
page_element.link.text # returns the link text
|
|
362
405
|
```
|
|
363
406
|
|
|
364
407
|
# Watchers
|
|
@@ -421,7 +464,8 @@ You can register any Capybara compliant driver as follows
|
|
|
421
464
|
Webkit = PageMagic::Driver.new(:webkit) do |app, options, browser_alias_chosen|
|
|
422
465
|
# Write the code necessary to initialise the driver you have chosen
|
|
423
466
|
require 'capybara/webkit'
|
|
424
|
-
Capybara::Webkit::Driver.new(app,
|
|
467
|
+
Capybara::Webkit::Driver.new(app,
|
|
468
|
+
)
|
|
425
469
|
end
|
|
426
470
|
|
|
427
471
|
#2. Register driver
|
data/Rakefile
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
Bundler.require :test, :development
|
|
2
4
|
|
|
3
5
|
RuboCop::RakeTask.new
|
|
@@ -12,11 +14,19 @@ Jeweler::Tasks.new do |gem|
|
|
|
12
14
|
gem.license = 'ruby'
|
|
13
15
|
gem.summary = 'Framework for modeling and interacting with webpages'
|
|
14
16
|
gem.description = 'Framework for modeling and interacting with webpages which wraps capybara'
|
|
15
|
-
gem.email = 'info@
|
|
17
|
+
gem.email = 'info@lvl-up.uk'
|
|
16
18
|
gem.authors = ['Leon Davis']
|
|
17
19
|
gem.required_ruby_version = '>= 2.1'
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
Jeweler::RubygemsDotOrgTasks.new
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
require 'rake/testtask'
|
|
25
|
+
Rake::TestTask.new do |t|
|
|
26
|
+
t.libs << 'spec'
|
|
27
|
+
t.pattern = 'spec/**/*_test.rb'
|
|
28
|
+
t.warning = true
|
|
29
|
+
t.verbose = true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
task default: [:spec, :test, 'rubocop:auto_correct']
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
2.0.0
|
data/circle.yml
CHANGED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'cgi'
|
|
2
|
+
|
|
3
|
+
class Object
|
|
4
|
+
# Alias of <tt>to_s</tt>.
|
|
5
|
+
def to_param
|
|
6
|
+
to_s
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Converts an object into a string suitable for use as a URL query string,
|
|
10
|
+
# using the given <tt>key</tt> as the param name.
|
|
11
|
+
def to_query(key)
|
|
12
|
+
"#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class NilClass
|
|
17
|
+
# Returns +self+.
|
|
18
|
+
def to_param
|
|
19
|
+
self
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class TrueClass
|
|
24
|
+
# Returns +self+.
|
|
25
|
+
def to_param
|
|
26
|
+
self
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class FalseClass
|
|
31
|
+
# Returns +self+.
|
|
32
|
+
def to_param
|
|
33
|
+
self
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class Array
|
|
38
|
+
# Calls <tt>to_param</tt> on all its elements and joins the result with
|
|
39
|
+
# slashes. This is used by <tt>url_for</tt> in Action Pack.
|
|
40
|
+
def to_param
|
|
41
|
+
collect(&:to_param).join '/'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Converts an array into a string suitable for use as a URL query string,
|
|
45
|
+
# using the given +key+ as the param name.
|
|
46
|
+
#
|
|
47
|
+
# ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
|
|
48
|
+
def to_query(key)
|
|
49
|
+
prefix = "#{key}[]"
|
|
50
|
+
|
|
51
|
+
if empty?
|
|
52
|
+
nil.to_query(prefix)
|
|
53
|
+
else
|
|
54
|
+
collect { |value| value.to_query(prefix) }.join '&'
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class Hash
|
|
60
|
+
# Returns a string representation of the receiver suitable for use as a URL
|
|
61
|
+
# query string:
|
|
62
|
+
# @example
|
|
63
|
+
# {name: 'David', nationality: 'Danish'}.to_query
|
|
64
|
+
# # => "name=David&nationality=Danish"
|
|
65
|
+
#
|
|
66
|
+
# An optional namespace can be passed to enclose key names:
|
|
67
|
+
# @example
|
|
68
|
+
# {name: 'David', nationality: 'Danish'}.to_query('user')
|
|
69
|
+
# # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
|
|
70
|
+
#
|
|
71
|
+
# The string pairs "key=value" that conform the query string
|
|
72
|
+
# are sorted lexicographically in ascending order.
|
|
73
|
+
#
|
|
74
|
+
# This method is also aliased as +to_param+.
|
|
75
|
+
def to_query(namespace = nil)
|
|
76
|
+
collect do |key, value|
|
|
77
|
+
unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
|
|
78
|
+
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
|
|
79
|
+
end
|
|
80
|
+
end.compact.sort! * '&'
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
alias to_param to_query
|
|
84
|
+
end
|
data/lib/page_magic.rb
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'capybara'
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
require_relative 'page_magic/exceptions'
|
|
5
|
+
require_relative 'page_magic/wait_methods'
|
|
6
|
+
require_relative 'page_magic/watchers'
|
|
7
|
+
require_relative 'page_magic/session'
|
|
8
|
+
require_relative 'page_magic/session_methods'
|
|
9
|
+
require_relative 'page_magic/elements'
|
|
10
|
+
require_relative 'page_magic/element_context'
|
|
11
|
+
require_relative 'page_magic/element'
|
|
12
|
+
require_relative 'page_magic/class_methods'
|
|
13
|
+
require_relative 'page_magic/instance_methods'
|
|
14
|
+
require_relative 'page_magic/drivers'
|
|
14
15
|
|
|
15
16
|
# module PageMagic - PageMagic is an api for modelling pages in a website.
|
|
16
17
|
module PageMagic
|
|
@@ -18,9 +19,9 @@ module PageMagic
|
|
|
18
19
|
|
|
19
20
|
# @!method matcher
|
|
20
21
|
# define match critera for loading a page object class
|
|
21
|
-
# @see
|
|
22
|
-
# @return [
|
|
23
|
-
def_delegator
|
|
22
|
+
# @see Mapping#initialize
|
|
23
|
+
# @return [Mapping]
|
|
24
|
+
def_delegator Mapping, :new, :matcher
|
|
24
25
|
|
|
25
26
|
class << self
|
|
26
27
|
# @return [Drivers] registered drivers
|
|
@@ -31,7 +32,8 @@ module PageMagic
|
|
|
31
32
|
def included(clazz)
|
|
32
33
|
clazz.class_eval do
|
|
33
34
|
include(InstanceMethods)
|
|
34
|
-
extend
|
|
35
|
+
extend ClassMethods
|
|
36
|
+
extend Elements
|
|
35
37
|
end
|
|
36
38
|
end
|
|
37
39
|
|
|
@@ -40,7 +42,7 @@ module PageMagic
|
|
|
40
42
|
# PageMagic.mapping '/', parameters: {project: 'page_magic'}, fragment: 'display'
|
|
41
43
|
# @see Matchers#initialize
|
|
42
44
|
def mapping(path = nil, parameters: nil, fragment: nil)
|
|
43
|
-
|
|
45
|
+
Mapping.new(path, parameters: parameters, fragment: fragment)
|
|
44
46
|
end
|
|
45
47
|
|
|
46
48
|
# Visit this page based on the class level registered url
|
|
@@ -48,10 +50,10 @@ module PageMagic
|
|
|
48
50
|
# @param [Symbol] browser name of browser
|
|
49
51
|
# @param [String] url url to start the session on
|
|
50
52
|
# @param [Hash] options browser driver specific options
|
|
51
|
-
# @return [Session] configured
|
|
52
|
-
def session(application: nil, browser: :rack_test,
|
|
53
|
+
# @return [Session] configured session
|
|
54
|
+
def session(url: nil, application: nil, browser: :rack_test, options: {})
|
|
53
55
|
driver = drivers.find(browser)
|
|
54
|
-
raise
|
|
56
|
+
raise UnsupportedBrowserException unless driver
|
|
55
57
|
|
|
56
58
|
Capybara.register_driver browser do |app|
|
|
57
59
|
driver.build(app, browser: browser, options: options)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module PageMagic
|
|
2
4
|
# module ClassMethods - contains class level methods for PageObjects
|
|
3
5
|
module ClassMethods
|
|
@@ -15,6 +17,7 @@ module PageMagic
|
|
|
15
17
|
# if one has not been set on the page object class it will return a default block that does nothing
|
|
16
18
|
def on_load(&block)
|
|
17
19
|
return @on_load || DEFAULT_ON_LOAD unless block
|
|
20
|
+
|
|
18
21
|
@on_load = block
|
|
19
22
|
end
|
|
20
23
|
|
|
@@ -27,14 +30,14 @@ module PageMagic
|
|
|
27
30
|
|
|
28
31
|
# Visit this page based on the class level registered url
|
|
29
32
|
# @param [Object] application rack application (optional)
|
|
30
|
-
# @param [Symbol] browser name of browser
|
|
33
|
+
# @param [Symbol] browser name of browser driver to use
|
|
31
34
|
# @param [Hash] options browser driver specific options
|
|
32
35
|
# @return [Session] active session configured to be using an instance of the page object modeled by this class
|
|
33
36
|
def visit(application: nil, browser: :rack_test, options: {})
|
|
34
37
|
session_options = { browser: browser, options: options, url: url }
|
|
35
38
|
session_options[:application] = application if application
|
|
36
39
|
|
|
37
|
-
PageMagic.session(session_options).tap do |session|
|
|
40
|
+
PageMagic.session(**session_options).tap do |session|
|
|
38
41
|
session.visit(self, url: url)
|
|
39
42
|
end
|
|
40
43
|
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'comparator/fuzzy'
|
|
4
|
+
require_relative 'comparator/literal'
|
|
5
|
+
require_relative 'comparator/parameter_map'
|
|
6
|
+
require_relative 'comparator/null'
|
|
7
|
+
|
|
8
|
+
module PageMagic
|
|
9
|
+
# class Comparator - used for comparing components used for mapping pages
|
|
10
|
+
class Comparator
|
|
11
|
+
class << self
|
|
12
|
+
def for(comparator)
|
|
13
|
+
klass = { Regexp => Fuzzy, Hash => ParameterMap, NilClass => Null }.fetch(comparator.class, Literal)
|
|
14
|
+
klass.new(comparator)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
attr_reader :comparator, :fuzzy
|
|
19
|
+
|
|
20
|
+
def initialize(comparator, fuzzy)
|
|
21
|
+
@comparator = comparator
|
|
22
|
+
@fuzzy = fuzzy
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def fuzzy?
|
|
26
|
+
fuzzy
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_s
|
|
30
|
+
comparator.to_s
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def ==(other)
|
|
34
|
+
comparator == other.comparator
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PageMagic
|
|
4
|
+
class Comparator
|
|
5
|
+
# class Fuzzy - used for modeling and comparing components that are 'fuzzy' i.e. respond to `=~` e.g. a Regexp
|
|
6
|
+
class Fuzzy < Comparator
|
|
7
|
+
def initialize(comparator)
|
|
8
|
+
super(comparator, true)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def match?(value)
|
|
12
|
+
comparator =~ value ? true : false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def <=>(other)
|
|
16
|
+
return -1 if other.is_a?(Null)
|
|
17
|
+
return 1 unless other.fuzzy?
|
|
18
|
+
|
|
19
|
+
0
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PageMagic
|
|
4
|
+
class Comparator
|
|
5
|
+
# class Literal - used for modeling and comparing thing directly. E.g. strings
|
|
6
|
+
class Literal < Comparator
|
|
7
|
+
def initialize(comparator)
|
|
8
|
+
super(comparator, false)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def match?(value)
|
|
12
|
+
comparator == value
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def <=>(other)
|
|
16
|
+
return 1 if other.fuzzy? || other.is_a?(Null)
|
|
17
|
+
|
|
18
|
+
0
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PageMagic
|
|
4
|
+
class Comparator
|
|
5
|
+
# models mapping used to relate pages to uris
|
|
6
|
+
class Null < Comparator
|
|
7
|
+
def initialize(_comparator = nil)
|
|
8
|
+
super(nil, false)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def match?(_value)
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def <=>(other)
|
|
16
|
+
return 0 if other.is_a?(Null)
|
|
17
|
+
|
|
18
|
+
1
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def present?
|
|
22
|
+
false
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|