wayfarer 0.4.7 → 0.4.8

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.
Files changed (183) hide show
  1. checksums.yaml +4 -4
  2. data/.env +17 -0
  3. data/.github/workflows/lint.yaml +8 -6
  4. data/.github/workflows/release.yaml +4 -3
  5. data/.github/workflows/tests.yaml +5 -14
  6. data/.gitignore +2 -2
  7. data/.rubocop.yml +31 -0
  8. data/.vale.ini +6 -3
  9. data/Dockerfile +3 -2
  10. data/Gemfile +21 -0
  11. data/Gemfile.lock +233 -128
  12. data/Rakefile +7 -0
  13. data/docker-compose.yml +13 -14
  14. data/docs/guides/callbacks.md +3 -1
  15. data/docs/guides/configuration.md +10 -35
  16. data/docs/guides/development.md +67 -0
  17. data/docs/guides/handlers.md +7 -7
  18. data/docs/guides/jobs.md +54 -11
  19. data/docs/guides/networking/custom_adapters.md +31 -10
  20. data/docs/guides/pages.md +24 -22
  21. data/docs/guides/routing.md +116 -34
  22. data/docs/guides/tasks.md +30 -10
  23. data/docs/guides/tutorial.md +23 -17
  24. data/docs/guides/user_agents.md +11 -9
  25. data/lib/wayfarer/base.rb +9 -8
  26. data/lib/wayfarer/batch_completion.rb +18 -14
  27. data/lib/wayfarer/callbacks.rb +14 -14
  28. data/lib/wayfarer/cli/route_printer.rb +78 -96
  29. data/lib/wayfarer/cli.rb +12 -30
  30. data/lib/wayfarer/gc.rb +6 -1
  31. data/lib/wayfarer/kv.rb +28 -0
  32. data/lib/wayfarer/middleware/chain.rb +7 -1
  33. data/lib/wayfarer/middleware/content_type.rb +20 -15
  34. data/lib/wayfarer/middleware/dedup.rb +9 -3
  35. data/lib/wayfarer/middleware/dispatch.rb +7 -2
  36. data/lib/wayfarer/middleware/normalize.rb +4 -12
  37. data/lib/wayfarer/middleware/router.rb +1 -1
  38. data/lib/wayfarer/middleware/uri_parser.rb +4 -3
  39. data/lib/wayfarer/networking/context.rb +12 -1
  40. data/lib/wayfarer/networking/ferrum.rb +1 -4
  41. data/lib/wayfarer/networking/follow.rb +2 -1
  42. data/lib/wayfarer/networking/pool.rb +12 -7
  43. data/lib/wayfarer/networking/selenium.rb +15 -7
  44. data/lib/wayfarer/page.rb +0 -2
  45. data/lib/wayfarer/parsing/xml.rb +1 -1
  46. data/lib/wayfarer/parsing.rb +2 -5
  47. data/lib/wayfarer/redis/barrier.rb +15 -2
  48. data/lib/wayfarer/redis/counter.rb +1 -2
  49. data/lib/wayfarer/routing/dsl.rb +166 -31
  50. data/lib/wayfarer/routing/hash_stack.rb +33 -0
  51. data/lib/wayfarer/routing/matchers/custom.rb +8 -5
  52. data/lib/wayfarer/routing/matchers/{suffix.rb → empty_params.rb} +2 -6
  53. data/lib/wayfarer/routing/matchers/host.rb +15 -9
  54. data/lib/wayfarer/routing/matchers/path.rb +11 -33
  55. data/lib/wayfarer/routing/matchers/query.rb +41 -17
  56. data/lib/wayfarer/routing/matchers/result.rb +12 -0
  57. data/lib/wayfarer/routing/matchers/scheme.rb +13 -5
  58. data/lib/wayfarer/routing/matchers/url.rb +13 -5
  59. data/lib/wayfarer/routing/path_consumer.rb +130 -0
  60. data/lib/wayfarer/routing/path_finder.rb +151 -23
  61. data/lib/wayfarer/routing/result.rb +1 -1
  62. data/lib/wayfarer/routing/root_route.rb +14 -2
  63. data/lib/wayfarer/routing/route.rb +71 -14
  64. data/lib/wayfarer/routing/serializable.rb +28 -0
  65. data/lib/wayfarer/routing/sub_route.rb +53 -0
  66. data/lib/wayfarer/routing/target_route.rb +17 -1
  67. data/lib/wayfarer/stringify.rb +1 -2
  68. data/lib/wayfarer/task.rb +3 -5
  69. data/lib/wayfarer/uri/normalization.rb +120 -0
  70. data/lib/wayfarer.rb +50 -10
  71. data/mise.toml +2 -0
  72. data/mkdocs.yml +8 -17
  73. data/rake/lint.rake +0 -96
  74. data/rake/release.rake +5 -11
  75. data/rake/tests.rake +8 -4
  76. data/requirements.txt +1 -1
  77. data/spec/factories/job.rb +8 -0
  78. data/spec/factories/middleware.rb +2 -2
  79. data/spec/factories/path_finder.rb +11 -0
  80. data/spec/factories/redis.rb +19 -0
  81. data/spec/factories/task.rb +39 -1
  82. data/spec/spec_helpers.rb +50 -57
  83. data/spec/support/active_job_helpers.rb +8 -0
  84. data/spec/support/integration_helpers.rb +21 -0
  85. data/spec/support/redis_helpers.rb +9 -0
  86. data/spec/support/test_app.rb +64 -43
  87. data/spec/{base_spec.rb → wayfarer/base_spec.rb} +32 -36
  88. data/spec/wayfarer/batch_completion_spec.rb +142 -0
  89. data/spec/wayfarer/cli/job_spec.rb +88 -0
  90. data/spec/wayfarer/cli/routing_spec.rb +322 -0
  91. data/spec/{cli → wayfarer/cli}/version_spec.rb +1 -1
  92. data/spec/wayfarer/gc_spec.rb +29 -0
  93. data/spec/{handler_spec.rb → wayfarer/handler_spec.rb} +1 -3
  94. data/spec/{integration → wayfarer/integration}/callbacks_spec.rb +9 -6
  95. data/spec/wayfarer/integration/content_type_spec.rb +37 -0
  96. data/spec/wayfarer/integration/custom_routing_spec.rb +51 -0
  97. data/spec/{integration → wayfarer/integration}/gc_spec.rb +9 -13
  98. data/spec/{integration → wayfarer/integration}/handler_spec.rb +9 -10
  99. data/spec/{integration → wayfarer/integration}/page_spec.rb +8 -6
  100. data/spec/{integration → wayfarer/integration}/params_spec.rb +4 -4
  101. data/spec/{integration → wayfarer/integration}/parsing_spec.rb +7 -33
  102. data/spec/wayfarer/integration/retry_spec.rb +112 -0
  103. data/spec/{integration → wayfarer/integration}/stage_spec.rb +5 -5
  104. data/spec/{middleware → wayfarer/middleware}/batch_completion_spec.rb +4 -5
  105. data/spec/{middleware → wayfarer/middleware}/chain_spec.rb +20 -15
  106. data/spec/{middleware → wayfarer/middleware}/content_type_spec.rb +18 -21
  107. data/spec/{middleware → wayfarer/middleware}/controller_spec.rb +22 -20
  108. data/spec/wayfarer/middleware/dedup_spec.rb +66 -0
  109. data/spec/wayfarer/middleware/normalize_spec.rb +32 -0
  110. data/spec/{middleware → wayfarer/middleware}/router_spec.rb +18 -20
  111. data/spec/{middleware → wayfarer/middleware}/stage_spec.rb +11 -10
  112. data/spec/wayfarer/middleware/uri_parser_spec.rb +63 -0
  113. data/spec/{middleware → wayfarer/middleware}/user_agent_spec.rb +34 -32
  114. data/spec/wayfarer/networking/capybara_spec.rb +13 -0
  115. data/spec/{networking → wayfarer/networking}/context_spec.rb +46 -38
  116. data/spec/wayfarer/networking/ferrum_spec.rb +13 -0
  117. data/spec/{networking → wayfarer/networking}/follow_spec.rb +9 -4
  118. data/spec/wayfarer/networking/http_spec.rb +12 -0
  119. data/spec/{networking → wayfarer/networking}/pool_spec.rb +11 -9
  120. data/spec/wayfarer/networking/selenium_spec.rb +12 -0
  121. data/spec/{networking → wayfarer/networking}/strategy.rb +33 -54
  122. data/spec/{page_spec.rb → wayfarer/page_spec.rb} +3 -3
  123. data/spec/{parsing → wayfarer/parsing}/json_spec.rb +1 -1
  124. data/spec/{parsing/xml_spec.rb → wayfarer/parsing/xml_parse_spec.rb} +4 -3
  125. data/spec/{redis → wayfarer/redis}/barrier_spec.rb +5 -4
  126. data/spec/wayfarer/redis/counter_spec.rb +34 -0
  127. data/spec/{redis → wayfarer/redis}/pool_spec.rb +3 -2
  128. data/spec/{routing → wayfarer/routing}/dsl_spec.rb +12 -22
  129. data/spec/wayfarer/routing/hash_stack_spec.rb +63 -0
  130. data/spec/wayfarer/routing/integration_spec.rb +101 -0
  131. data/spec/wayfarer/routing/matchers/custom_spec.rb +39 -0
  132. data/spec/wayfarer/routing/matchers/host_spec.rb +56 -0
  133. data/spec/wayfarer/routing/matchers/matcher.rb +17 -0
  134. data/spec/wayfarer/routing/matchers/path_spec.rb +43 -0
  135. data/spec/wayfarer/routing/matchers/query_spec.rb +123 -0
  136. data/spec/wayfarer/routing/matchers/scheme_spec.rb +45 -0
  137. data/spec/wayfarer/routing/matchers/url_spec.rb +33 -0
  138. data/spec/wayfarer/routing/path_consumer_spec.rb +123 -0
  139. data/spec/wayfarer/routing/path_finder_spec.rb +409 -0
  140. data/spec/wayfarer/routing/root_route_spec.rb +51 -0
  141. data/spec/wayfarer/routing/route_spec.rb +74 -0
  142. data/spec/wayfarer/routing/sub_route_spec.rb +103 -0
  143. data/spec/wayfarer/uri/normalization_spec.rb +98 -0
  144. data/spec/wayfarer_spec.rb +2 -2
  145. data/wayfarer.gemspec +17 -28
  146. metadata +768 -246
  147. data/.rbenv-gemsets +0 -1
  148. data/.ruby-version +0 -1
  149. data/RELEASING.md +0 -17
  150. data/docs/cookbook/user_agent.md +0 -7
  151. data/docs/design.md +0 -36
  152. data/docs/guides/jobs/error_handling.md +0 -40
  153. data/docs/reference/configuration.md +0 -36
  154. data/spec/batch_completion_spec.rb +0 -104
  155. data/spec/cli/job_spec.rb +0 -74
  156. data/spec/cli/routing_spec.rb +0 -101
  157. data/spec/fixtures/dummy_job.rb +0 -9
  158. data/spec/gc_spec.rb +0 -17
  159. data/spec/integration/content_type_spec.rb +0 -145
  160. data/spec/integration/routing_spec.rb +0 -18
  161. data/spec/middleware/dedup_spec.rb +0 -71
  162. data/spec/middleware/dispatch_spec.rb +0 -59
  163. data/spec/middleware/normalize_spec.rb +0 -60
  164. data/spec/middleware/uri_parser_spec.rb +0 -53
  165. data/spec/networking/capybara_spec.rb +0 -12
  166. data/spec/networking/ferrum_spec.rb +0 -12
  167. data/spec/networking/http_spec.rb +0 -12
  168. data/spec/networking/selenium_spec.rb +0 -12
  169. data/spec/redis/counter_spec.rb +0 -44
  170. data/spec/routing/integration_spec.rb +0 -110
  171. data/spec/routing/matchers/custom_spec.rb +0 -31
  172. data/spec/routing/matchers/host_spec.rb +0 -49
  173. data/spec/routing/matchers/path_spec.rb +0 -43
  174. data/spec/routing/matchers/query_spec.rb +0 -137
  175. data/spec/routing/matchers/scheme_spec.rb +0 -25
  176. data/spec/routing/matchers/suffix_spec.rb +0 -41
  177. data/spec/routing/matchers/uri_spec.rb +0 -27
  178. data/spec/routing/path_finder_spec.rb +0 -33
  179. data/spec/routing/root_route_spec.rb +0 -29
  180. data/spec/routing/route_spec.rb +0 -43
  181. data/docs/{reference → guides}/cli.md +0 -0
  182. data/spec/{stringify_spec.rb → wayfarer/stringify_spec.rb} +2 -2
  183. /data/spec/{task_spec.rb → wayfarer/task_spec.rb} +0 -0
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
-
5
- describe Wayfarer::Middleware::Dispatch do
6
- let(:task) { build(:task) }
7
- let(:action) { :action }
8
- subject(:chain) { described_class.new }
9
-
10
- before do
11
- task[:controller] = spy
12
- task[:action] = action
13
-
14
- allow(task[:controller]).to receive(:run_callbacks).and_yield
15
- end
16
-
17
- describe "#call" do
18
- it "runs callbacks" do
19
- expect(task[:controller]).to receive(:run_callbacks).with(action)
20
- subject.call(task)
21
- end
22
-
23
- context "when action is a Symbol" do
24
- it "calls the method" do
25
- expect(task[:controller]).to receive(action)
26
- subject.call(task)
27
- end
28
- end
29
-
30
- context "with handler" do
31
- let(:action) { Class.new.include(Wayfarer::Handler) }
32
-
33
- it "instantiates and calls" do
34
- expect_any_instance_of(action).to receive(:call).with(task)
35
- subject.call(task)
36
- end
37
- end
38
-
39
- context "without action" do
40
- let(:action) { nil }
41
-
42
- it "instantiates and calls" do
43
- expect { subject.call(task) }.to raise_error(ArgumentError)
44
- end
45
- end
46
-
47
- context "without other action" do
48
- let(:action) { Class.new }
49
-
50
- it "instantiates and calls" do
51
- expect { subject.call(task) }.to raise_error(ArgumentError)
52
- end
53
- end
54
-
55
- it "yields" do
56
- expect { |spy| subject.call(task, &spy) }.to yield_control
57
- end
58
- end
59
- end
@@ -1,60 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
-
5
- describe Wayfarer::Middleware::Normalize do
6
- let(:task) { build(:task) }
7
- let(:uri) { Addressable::URI.parse(url) }
8
- subject { described_class.new }
9
-
10
- describe "::normalize" do
11
- subject { described_class.normalize(uri).to_s }
12
-
13
- context "without HTTP(S) URL" do
14
- let(:url) { "localhost:3000" }
15
-
16
- it { is_expected.to eq(url) }
17
- end
18
-
19
- context "with HTTP URL" do
20
- let(:url) { "http://example.com" }
21
-
22
- it { is_expected.to eq("http://example.com/") }
23
- end
24
- end
25
-
26
- describe "#call" do
27
- let(:url) { task.url }
28
- before { task[:uri] = uri }
29
-
30
- context "when already assigned" do
31
- before { task[:normalized_url] = Object.new }
32
-
33
- specify do
34
- expect { |spy| subject.call(task, &spy) }.to yield_control
35
- end
36
-
37
- it "doesn't normalize URL" do
38
- expect { subject.call(task) }.not_to(change { task[:normalized_url] })
39
- end
40
- end
41
-
42
- context "with invalid URL" do
43
- before do
44
- # I can't come up with a URL that normalize_url raises on but
45
- # Addressable::URI doesn't, hence the stub
46
- allow(described_class).to receive(:normalize).with(uri).and_return(nil)
47
- end
48
-
49
- specify do
50
- expect { |spy| subject.call(task, &spy) }.not_to yield_control
51
- end
52
-
53
- specify do
54
- expect(Wayfarer::Logging.logger).to receive(:add).with(Logger::INFO, "Failed to normalize HTTP(S) URL")
55
-
56
- subject.call(task)
57
- end
58
- end
59
- end
60
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
-
5
- describe Wayfarer::Middleware::UriParser, "#call" do
6
- let(:task) { build(:task) }
7
- subject { described_class.new }
8
-
9
- it "parses URLs" do
10
- expect { subject.call(task) }.to change { task[:uri] }.to(Addressable::URI.parse(task.url))
11
- end
12
-
13
- it "normalizes URLs" do
14
- task = build(:task, url: "http://example.com")
15
-
16
- expect { subject.call(task) }.to change { task[:uri].to_s }.to("http://example.com/")
17
- end
18
-
19
- specify do
20
- expect { |spy| subject.call(task, &spy) }.to yield_control
21
- end
22
-
23
- context "with invalid URL" do
24
- let(:task) { build(:task, url: "ht%0atp://localhost/") }
25
-
26
- specify do
27
- expect { |spy| subject.call(task, &spy) }.not_to yield_control
28
- end
29
-
30
- specify do
31
- expect(Wayfarer::Logging.logger)
32
- .to receive(:add).with(Logger::INFO, "Not processing invalid URL (Invalid scheme format: 'ht%0atp')")
33
-
34
- subject.call(task)
35
- end
36
- end
37
-
38
- describe described_class::API do
39
- subject(:controller) do
40
- Struct.new(:task).include(described_class).new(task)
41
- end
42
-
43
- describe "#uri" do
44
- let(:uri) { Addressable::URI.parse(task.url) }
45
-
46
- before { task[:uri] = uri }
47
-
48
- it "returns the agent" do
49
- expect(controller.uri).to be(uri)
50
- end
51
- end
52
- end
53
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
- require_relative "strategy"
5
-
6
- describe Wayfarer::Networking::Capybara, ferrum: true do
7
- include_examples "Network strategy", strategy: described_class,
8
- browser: true,
9
- request_headers: false,
10
- response_headers: true,
11
- status_code: true
12
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
- require_relative "strategy"
5
-
6
- describe Wayfarer::Networking::Ferrum, ferrum: true do
7
- include_examples "Network strategy", strategy: described_class,
8
- browser: true,
9
- request_headers: true,
10
- response_headers: true,
11
- status_code: true
12
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
- require_relative "strategy"
5
-
6
- describe Wayfarer::Networking::HTTP do
7
- include_examples "Network strategy", strategy: described_class,
8
- browser: false,
9
- request_headers: true,
10
- response_headers: true,
11
- status_code: true
12
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
- require_relative "strategy"
5
-
6
- describe Wayfarer::Networking::Selenium, selenium: true do
7
- include_examples "Network strategy", strategy: described_class,
8
- browser: true,
9
- request_headers: false,
10
- response_headers: false,
11
- status_code: false
12
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
-
5
- describe Wayfarer::Redis::Counter, redis: true do
6
- let(:callback) { -> {} }
7
- let(:task) { build(:task, :redis_pool) }
8
- subject(:counter) { Wayfarer::Redis::Counter.new(task, &callback) }
9
-
10
- describe "#redis_key" do
11
- it "returns the expected Redis key" do
12
- expect(counter.redis_key).to eq("wayfarer-counter-batch")
13
- end
14
- end
15
-
16
- describe "#increment" do
17
- it "increments" do
18
- expect { counter.increment }.to change { counter.value }.by(1)
19
- end
20
- end
21
-
22
- describe "#decrement" do
23
- it "decrements" do
24
- expect { counter.decrement }.to change { counter.value }.by(-1)
25
- end
26
-
27
- context "when reaching zero" do
28
- let(:callback) { -> { @callback_called = true } }
29
-
30
- before { counter.increment }
31
-
32
- it "runs callback" do
33
- expect { counter.decrement }.to change { @callback_called }.to(true).from(nil)
34
- end
35
- end
36
- end
37
-
38
- describe "#reset!" do
39
- it "resets" do
40
- 3.times { counter.increment }
41
- expect { counter.reset! }.to change { counter.value }.to(0)
42
- end
43
- end
44
- end
@@ -1,110 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
-
5
- describe Wayfarer::Routing::DSL do
6
- let(:route) { Wayfarer::Routing::RootRoute.new }
7
-
8
- it "matches URLs" do
9
- route.path "/"
10
-
11
- result = route.invoke(Addressable::URI.parse("https://example.com/"))
12
- expect(result).to be_a(Wayfarer::Routing::Result::Match)
13
-
14
- result = route.invoke(Addressable::URI.parse("https://example.com/foo"))
15
- expect(result).to be_a(Wayfarer::Routing::Result::Mismatch)
16
- end
17
-
18
- it "matches URLs" do
19
- route.host "example.com", path: "/foo"
20
-
21
- result = route.invoke(Addressable::URI.parse("https://example.com/foo"))
22
- expect(result).to be_a(Wayfarer::Routing::Result::Match)
23
- end
24
-
25
- it "matches URLs" do
26
- route.host "example.com", path: "/foo" do
27
- query page: 1..10
28
- end
29
-
30
- result = route.invoke(Addressable::URI.parse("https://example.com/foo?page=4"))
31
- expect(result).to be_a(Wayfarer::Routing::Result::Match)
32
-
33
- result = route.invoke(Addressable::URI.parse("https://example.com/foo?page=11"))
34
- expect(result).to be_a(Wayfarer::Routing::Result::Mismatch)
35
-
36
- result = route.invoke(Addressable::URI.parse("https://example.com/foo"))
37
- expect(result).to be_a(Wayfarer::Routing::Result::Mismatch)
38
-
39
- result = route.invoke(Addressable::URI.parse("https://example.com?page=2"))
40
- expect(result).to be_a(Wayfarer::Routing::Result::Mismatch)
41
- end
42
-
43
- it "matches URLs" do
44
- route.host "example.com", path: "/foo" do
45
- query page: 1..10
46
- end
47
-
48
- result = route.invoke(Addressable::URI.parse("https://example.com/foo?page=4"))
49
- expect(result).to be_a(Wayfarer::Routing::Result::Match)
50
-
51
- result = route.invoke(Addressable::URI.parse("https://example.com/foo?page=11"))
52
- expect(result).to be_a(Wayfarer::Routing::Result::Mismatch)
53
-
54
- result = route.invoke(Addressable::URI.parse("https://example.com/foo"))
55
- expect(result).to be_a(Wayfarer::Routing::Result::Mismatch)
56
-
57
- result = route.invoke(Addressable::URI.parse("https://example.com?page=2"))
58
- expect(result).to be_a(Wayfarer::Routing::Result::Mismatch)
59
- end
60
-
61
- it "matches URLs" do
62
- route.host "example.com" do
63
- path "/contact"
64
- path "/users/:id"
65
- end
66
-
67
- result = route.invoke(Addressable::URI.parse("https://example.com/contact"))
68
- expect(result).to be_a(Wayfarer::Routing::Result::Match)
69
-
70
- result = route.invoke(Addressable::URI.parse("https://example.com/contact/foo"))
71
- expect(result).to be_a(Wayfarer::Routing::Result::Mismatch)
72
-
73
- result = route.invoke(Addressable::URI.parse("https://example.com/users/123"))
74
- expect(result).to be_a(Wayfarer::Routing::Result::Match)
75
-
76
- result = route.invoke(Addressable::URI.parse("https://example.com/users/123/images"))
77
- expect(result).to be_a(Wayfarer::Routing::Result::Mismatch)
78
-
79
- result = route.invoke(Addressable::URI.parse("https://example.com/users"))
80
- expect(result).to be_a(Wayfarer::Routing::Result::Mismatch)
81
- end
82
-
83
- it "matches URLs" do
84
- route.host "example.com" do
85
- path "/contact"
86
- path "/users/:user_id" do
87
- path "/images/:id"
88
- path "/friends"
89
- end
90
- end
91
-
92
- result = route.invoke(Addressable::URI.parse("https://example.com/contact"))
93
- expect(result).to be_a(Wayfarer::Routing::Result::Match)
94
-
95
- result = route.invoke(Addressable::URI.parse("https://example.com/users/123"))
96
- expect(result).to be_a(Wayfarer::Routing::Result::Mismatch)
97
-
98
- result = route.invoke(Addressable::URI.parse("https://example.com/users/123/images/23"))
99
- expect(result).to be_a(Wayfarer::Routing::Result::Match)
100
-
101
- result = route.invoke(Addressable::URI.parse("https://example.com/users/123/images/23/foo"))
102
- expect(result).to be_a(Wayfarer::Routing::Result::Mismatch)
103
-
104
- result = route.invoke(Addressable::URI.parse("https://example.com/users/123/friends"))
105
- expect(result).to be_a(Wayfarer::Routing::Result::Match)
106
-
107
- result = route.invoke(Addressable::URI.parse("https://example.com/users/123/foobar"))
108
- expect(result).to be_a(Wayfarer::Routing::Result::Mismatch)
109
- end
110
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
-
5
- describe Wayfarer::Routing::Matchers::Custom do
6
- let(:url) { Addressable::URI.parse("http://example.com") }
7
-
8
- describe "#match" do
9
- context "with a block" do
10
- context "when block is truthy" do
11
- subject(:matcher) do
12
- Wayfarer::Routing::Matchers::Custom.new ->(_) { true }
13
- end
14
-
15
- it "returns true" do
16
- expect(matcher).to match(url)
17
- end
18
- end
19
-
20
- context "when block is falsy" do
21
- subject(:matcher) do
22
- Wayfarer::Routing::Matchers::Custom.new ->(_) { false }
23
- end
24
-
25
- it "returns true" do
26
- expect(matcher).not_to match(url)
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
-
5
- describe Wayfarer::Routing::Matchers::Host do
6
- subject(:matcher) { Wayfarer::Routing::Matchers::Host.new(str_or_regexp) }
7
-
8
- describe "#matches?" do
9
- describe "String matching" do
10
- let(:str_or_regexp) { "example.com" }
11
-
12
- context "with matching URL" do
13
- let(:url) { Addressable::URI.parse("http://example.com/foo/bar") }
14
-
15
- it "returns true" do
16
- expect(matcher).to match(url)
17
- end
18
- end
19
-
20
- context "with mismatching URL" do
21
- let(:url) { Addressable::URI.parse("http://google.com/bar/qux") }
22
-
23
- it "returns false" do
24
- expect(matcher).not_to match(url)
25
- end
26
- end
27
- end
28
-
29
- describe "RegExp matching" do
30
- let(:str_or_regexp) { /example.com/ }
31
-
32
- context "with matching URL" do
33
- let(:url) { Addressable::URI.parse("http://sub.example.com") }
34
-
35
- it "returns true" do
36
- expect(matcher).to match(url)
37
- end
38
- end
39
-
40
- context "with mismatching URL" do
41
- let(:url) { Addressable::URI.parse("http://example.sub.com") }
42
-
43
- it "returns false" do
44
- expect(matcher).not_to match(url)
45
- end
46
- end
47
- end
48
- end
49
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
-
5
- describe Wayfarer::Routing::Matchers::Path, mri: true do
6
- let(:route) { Wayfarer::Routing::RootRoute.new }
7
- subject(:matcher) { Wayfarer::Routing::Matchers::Path.new(path, route) }
8
-
9
- describe "#match?" do
10
- context "with matching URL" do
11
- let(:path) { "/{alpha}/{beta}" }
12
-
13
- it "returns true" do
14
- expect(matcher).to match(Addressable::URI.parse("http://example.com/foo/bar"))
15
- end
16
- end
17
-
18
- context "with mismatching URL" do
19
- let(:path) { "/{alpha}/{beta}" }
20
-
21
- it "returns false" do
22
- expect(matcher).not_to match(Addressable::URI.parse("http://example.com/foo"))
23
- end
24
- end
25
-
26
- context "with mismatching URL" do
27
- let(:path) { "/" }
28
-
29
- it "returns false" do
30
- expect(matcher).not_to match(Addressable::URI.parse("http://example.com/foo"))
31
- end
32
- end
33
- end
34
-
35
- describe "#params" do
36
- let(:path) { "/{alpha}/{beta}" }
37
-
38
- it "returns the correct parameters" do
39
- url = Addressable::URI.parse("http://example.com/foo/bar")
40
- expect(matcher.params(url)).to eq("alpha" => "foo", "beta" => "bar")
41
- end
42
- end
43
- end
@@ -1,137 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
-
5
- describe Wayfarer::Routing::Matchers::Query do
6
- subject(:matcher) { Wayfarer::Routing::Matchers::Query.new(constraints) }
7
-
8
- describe "String constraints" do
9
- let(:constraints) { Hash[arg: "foo"] }
10
-
11
- context "with matching query field value" do
12
- let(:url) { Addressable::URI.parse("http://example.com?arg=foo") }
13
-
14
- it "returns true" do
15
- expect(matcher).to match(url)
16
- end
17
- end
18
-
19
- context "with mismatching query field value" do
20
- let(:url) { Addressable::URI.parse("http://example.com?arg=bar") }
21
-
22
- it "returns false" do
23
- expect(matcher).not_to match(url)
24
- end
25
- end
26
- end
27
-
28
- describe "Integer constraints" do
29
- let(:constraints) { Hash[arg: 0] }
30
-
31
- context "with matching query field value" do
32
- let(:url) { Addressable::URI.parse("http://example.com?arg=0") }
33
-
34
- it "returns true" do
35
- expect(matcher).to match(url)
36
- end
37
- end
38
-
39
- context "with mismatching query field value" do
40
- let(:url) { Addressable::URI.parse("http://example.com?arg=1") }
41
-
42
- it "returns false" do
43
- expect(matcher).not_to match(url)
44
- end
45
- end
46
-
47
- context "with non-numeric query field value" do
48
- let(:url) { Addressable::URI.parse("http://example.com?arg=foo") }
49
-
50
- it "returns false" do
51
- expect(matcher).not_to match(url)
52
- end
53
- end
54
- end
55
-
56
- describe "Regexp constraints" do
57
- let(:constraints) { Hash[arg: /foo/] }
58
-
59
- context "with matching query field value" do
60
- let(:url) { Addressable::URI.parse("http://example.com?arg=foo") }
61
-
62
- it "returns true" do
63
- expect(matcher).to match(url)
64
- end
65
- end
66
-
67
- context "with mismatching query field value" do
68
- let(:url) { Addressable::URI.parse("http://example.com?arg=bar") }
69
-
70
- it "returns false" do
71
- expect(matcher).not_to match(url)
72
- end
73
- end
74
- end
75
-
76
- describe "Range constraints" do
77
- let(:constraints) { Hash[arg: 1..10] }
78
-
79
- context "with matching query field value" do
80
- let(:url) { Addressable::URI.parse("http://example.com?arg=5") }
81
-
82
- it "returns true" do
83
- expect(matcher).to match(url)
84
- end
85
- end
86
-
87
- context "with mismatching query field value" do
88
- let(:url) { Addressable::URI.parse("http://example.com?arg=11") }
89
-
90
- it "returns false" do
91
- expect(matcher).not_to match(url)
92
- end
93
- end
94
-
95
- context "with non-numeric query field value" do
96
- let(:url) { Addressable::URI.parse("http://example.com?arg=foo") }
97
-
98
- it "returns false" do
99
- expect(matcher).not_to match(url)
100
- end
101
- end
102
- end
103
-
104
- describe "Compound constraints" do
105
- let(:constraints) do
106
- Hash[foo: 1..5, bar: /baz/, qux: "zot", toto: 2]
107
- end
108
-
109
- context "with matching query field values" do
110
- let(:url) { Addressable::URI.parse("http://example.com?foo=4&bar=bazqux&qux=zot&toto=2") }
111
-
112
- it "returns true" do
113
- expect(matcher).to match(url)
114
- end
115
- end
116
-
117
- context "with mismatching query field values" do
118
- let(:url) { Addressable::URI.parse("http://example.com?foo=bar&bar=qux&qux=6toto=0") }
119
-
120
- it "returns false" do
121
- expect(matcher).not_to match(url)
122
- end
123
- end
124
- end
125
-
126
- describe "#params" do
127
- let(:constraints) do
128
- Hash[foo: 1..5, bar: /baz/, qux: "zot", toto: 2]
129
- end
130
-
131
- it "returns the correct parameters" do
132
- url = Addressable::URI.parse("http://example.com?foo=4&bar=bazqux&qux=zot&toto=2")
133
- expect(matcher.params(url)).to \
134
- eq("foo" => "4", "bar" => "bazqux", "qux" => "zot", "toto" => "2")
135
- end
136
- end
137
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helpers"
4
-
5
- describe Wayfarer::Routing::Matchers::Scheme do
6
- describe "#match" do
7
- subject(:matcher) { Wayfarer::Routing::Matchers::Scheme.new(:http) }
8
-
9
- context "with matching URL" do
10
- let(:url) { Addressable::URI.parse("http://example.com") }
11
-
12
- it "returns true" do
13
- expect(matcher).to match(url)
14
- end
15
- end
16
-
17
- context "with mismatching URL" do
18
- let(:url) { Addressable::URI.parse("https://example.com") }
19
-
20
- it "returns true" do
21
- expect(matcher).not_to match(url)
22
- end
23
- end
24
- end
25
- end