wayfarer-jruby 0.0.1

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 (224) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.rbenv-gemsets +1 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +21 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +5 -0
  8. data/.yardopts +3 -0
  9. data/Gemfile +11 -0
  10. data/LICENSE +19 -0
  11. data/README.md +19 -0
  12. data/Rakefile +114 -0
  13. data/benchmark/frontiers.rb +143 -0
  14. data/bin/wayfarer +116 -0
  15. data/docs/.gitignore +2 -0
  16. data/docs/_config.yml +15 -0
  17. data/docs/_includes/base.html +7 -0
  18. data/docs/_includes/head.html +10 -0
  19. data/docs/_includes/navigation.html +172 -0
  20. data/docs/_layouts/default.html +42 -0
  21. data/docs/_sass/base.scss +439 -0
  22. data/docs/_sass/variables.scss +24 -0
  23. data/docs/_sass/vendor/bourbon/_bourbon-deprecate.scss +19 -0
  24. data/docs/_sass/vendor/bourbon/_bourbon-deprecated-upcoming.scss +425 -0
  25. data/docs/_sass/vendor/bourbon/_bourbon.scss +90 -0
  26. data/docs/_sass/vendor/bourbon/addons/_border-color.scss +29 -0
  27. data/docs/_sass/vendor/bourbon/addons/_border-radius.scss +48 -0
  28. data/docs/_sass/vendor/bourbon/addons/_border-style.scss +28 -0
  29. data/docs/_sass/vendor/bourbon/addons/_border-width.scss +28 -0
  30. data/docs/_sass/vendor/bourbon/addons/_buttons.scss +69 -0
  31. data/docs/_sass/vendor/bourbon/addons/_clearfix.scss +25 -0
  32. data/docs/_sass/vendor/bourbon/addons/_ellipsis.scss +30 -0
  33. data/docs/_sass/vendor/bourbon/addons/_font-stacks.scss +31 -0
  34. data/docs/_sass/vendor/bourbon/addons/_hide-text.scss +27 -0
  35. data/docs/_sass/vendor/bourbon/addons/_margin.scss +29 -0
  36. data/docs/_sass/vendor/bourbon/addons/_padding.scss +29 -0
  37. data/docs/_sass/vendor/bourbon/addons/_position.scss +51 -0
  38. data/docs/_sass/vendor/bourbon/addons/_prefixer.scss +66 -0
  39. data/docs/_sass/vendor/bourbon/addons/_retina-image.scss +27 -0
  40. data/docs/_sass/vendor/bourbon/addons/_size.scss +56 -0
  41. data/docs/_sass/vendor/bourbon/addons/_text-inputs.scss +118 -0
  42. data/docs/_sass/vendor/bourbon/addons/_timing-functions.scss +34 -0
  43. data/docs/_sass/vendor/bourbon/addons/_triangle.scss +63 -0
  44. data/docs/_sass/vendor/bourbon/addons/_word-wrap.scss +29 -0
  45. data/docs/_sass/vendor/bourbon/css3/_animation.scss +61 -0
  46. data/docs/_sass/vendor/bourbon/css3/_appearance.scss +5 -0
  47. data/docs/_sass/vendor/bourbon/css3/_backface-visibility.scss +5 -0
  48. data/docs/_sass/vendor/bourbon/css3/_background-image.scss +44 -0
  49. data/docs/_sass/vendor/bourbon/css3/_background.scss +57 -0
  50. data/docs/_sass/vendor/bourbon/css3/_border-image.scss +61 -0
  51. data/docs/_sass/vendor/bourbon/css3/_calc.scss +6 -0
  52. data/docs/_sass/vendor/bourbon/css3/_columns.scss +67 -0
  53. data/docs/_sass/vendor/bourbon/css3/_filter.scss +6 -0
  54. data/docs/_sass/vendor/bourbon/css3/_flex-box.scss +327 -0
  55. data/docs/_sass/vendor/bourbon/css3/_font-face.scss +29 -0
  56. data/docs/_sass/vendor/bourbon/css3/_font-feature-settings.scss +6 -0
  57. data/docs/_sass/vendor/bourbon/css3/_hidpi-media-query.scss +12 -0
  58. data/docs/_sass/vendor/bourbon/css3/_hyphens.scss +6 -0
  59. data/docs/_sass/vendor/bourbon/css3/_image-rendering.scss +15 -0
  60. data/docs/_sass/vendor/bourbon/css3/_keyframes.scss +38 -0
  61. data/docs/_sass/vendor/bourbon/css3/_linear-gradient.scss +40 -0
  62. data/docs/_sass/vendor/bourbon/css3/_perspective.scss +12 -0
  63. data/docs/_sass/vendor/bourbon/css3/_placeholder.scss +10 -0
  64. data/docs/_sass/vendor/bourbon/css3/_radial-gradient.scss +40 -0
  65. data/docs/_sass/vendor/bourbon/css3/_selection.scss +44 -0
  66. data/docs/_sass/vendor/bourbon/css3/_text-decoration.scss +27 -0
  67. data/docs/_sass/vendor/bourbon/css3/_transform.scss +21 -0
  68. data/docs/_sass/vendor/bourbon/css3/_transition.scss +81 -0
  69. data/docs/_sass/vendor/bourbon/css3/_user-select.scss +5 -0
  70. data/docs/_sass/vendor/bourbon/functions/_assign-inputs.scss +16 -0
  71. data/docs/_sass/vendor/bourbon/functions/_contains-falsy.scss +25 -0
  72. data/docs/_sass/vendor/bourbon/functions/_contains.scss +31 -0
  73. data/docs/_sass/vendor/bourbon/functions/_is-length.scss +16 -0
  74. data/docs/_sass/vendor/bourbon/functions/_is-light.scss +26 -0
  75. data/docs/_sass/vendor/bourbon/functions/_is-number.scss +16 -0
  76. data/docs/_sass/vendor/bourbon/functions/_is-size.scss +23 -0
  77. data/docs/_sass/vendor/bourbon/functions/_modular-scale.scss +74 -0
  78. data/docs/_sass/vendor/bourbon/functions/_px-to-em.scss +24 -0
  79. data/docs/_sass/vendor/bourbon/functions/_px-to-rem.scss +26 -0
  80. data/docs/_sass/vendor/bourbon/functions/_shade.scss +24 -0
  81. data/docs/_sass/vendor/bourbon/functions/_strip-units.scss +22 -0
  82. data/docs/_sass/vendor/bourbon/functions/_tint.scss +24 -0
  83. data/docs/_sass/vendor/bourbon/functions/_transition-property-name.scss +37 -0
  84. data/docs/_sass/vendor/bourbon/functions/_unpack.scss +32 -0
  85. data/docs/_sass/vendor/bourbon/helpers/_convert-units.scss +26 -0
  86. data/docs/_sass/vendor/bourbon/helpers/_directional-values.scss +108 -0
  87. data/docs/_sass/vendor/bourbon/helpers/_font-source-declaration.scss +53 -0
  88. data/docs/_sass/vendor/bourbon/helpers/_gradient-positions-parser.scss +24 -0
  89. data/docs/_sass/vendor/bourbon/helpers/_linear-angle-parser.scss +35 -0
  90. data/docs/_sass/vendor/bourbon/helpers/_linear-gradient-parser.scss +51 -0
  91. data/docs/_sass/vendor/bourbon/helpers/_linear-positions-parser.scss +77 -0
  92. data/docs/_sass/vendor/bourbon/helpers/_linear-side-corner-parser.scss +41 -0
  93. data/docs/_sass/vendor/bourbon/helpers/_radial-arg-parser.scss +74 -0
  94. data/docs/_sass/vendor/bourbon/helpers/_radial-gradient-parser.scss +55 -0
  95. data/docs/_sass/vendor/bourbon/helpers/_radial-positions-parser.scss +28 -0
  96. data/docs/_sass/vendor/bourbon/helpers/_render-gradients.scss +31 -0
  97. data/docs/_sass/vendor/bourbon/helpers/_shape-size-stripper.scss +15 -0
  98. data/docs/_sass/vendor/bourbon/helpers/_str-to-num.scss +55 -0
  99. data/docs/_sass/vendor/bourbon/settings/_asset-pipeline.scss +7 -0
  100. data/docs/_sass/vendor/bourbon/settings/_deprecation-warnings.scss +8 -0
  101. data/docs/_sass/vendor/bourbon/settings/_prefixer.scss +9 -0
  102. data/docs/_sass/vendor/bourbon/settings/_px-to-em.scss +1 -0
  103. data/docs/_sass/vendor/neat/_neat-helpers.scss +11 -0
  104. data/docs/_sass/vendor/neat/_neat.scss +23 -0
  105. data/docs/_sass/vendor/neat/functions/_new-breakpoint.scss +49 -0
  106. data/docs/_sass/vendor/neat/functions/_private.scss +114 -0
  107. data/docs/_sass/vendor/neat/grid/_box-sizing.scss +15 -0
  108. data/docs/_sass/vendor/neat/grid/_direction-context.scss +33 -0
  109. data/docs/_sass/vendor/neat/grid/_display-context.scss +28 -0
  110. data/docs/_sass/vendor/neat/grid/_fill-parent.scss +22 -0
  111. data/docs/_sass/vendor/neat/grid/_media.scss +92 -0
  112. data/docs/_sass/vendor/neat/grid/_omega.scss +87 -0
  113. data/docs/_sass/vendor/neat/grid/_outer-container.scss +34 -0
  114. data/docs/_sass/vendor/neat/grid/_pad.scss +25 -0
  115. data/docs/_sass/vendor/neat/grid/_private.scss +35 -0
  116. data/docs/_sass/vendor/neat/grid/_row.scss +52 -0
  117. data/docs/_sass/vendor/neat/grid/_shift.scss +50 -0
  118. data/docs/_sass/vendor/neat/grid/_span-columns.scss +94 -0
  119. data/docs/_sass/vendor/neat/grid/_to-deprecate.scss +97 -0
  120. data/docs/_sass/vendor/neat/grid/_visual-grid.scss +42 -0
  121. data/docs/_sass/vendor/neat/mixins/_clearfix.scss +25 -0
  122. data/docs/_sass/vendor/neat/settings/_disable-warnings.scss +13 -0
  123. data/docs/_sass/vendor/neat/settings/_grid.scss +51 -0
  124. data/docs/_sass/vendor/neat/settings/_visual-grid.scss +27 -0
  125. data/docs/_sass/vendor/normalize-3.0.2.scss +427 -0
  126. data/docs/_sass/vendor/pygments.scss +356 -0
  127. data/docs/automating_browsers/capybara.md +70 -0
  128. data/docs/css/screen.scss +7 -0
  129. data/docs/guides/callbacks.md +45 -0
  130. data/docs/guides/cli.md +52 -0
  131. data/docs/guides/configuration.md +184 -0
  132. data/docs/guides/error_handling.md +46 -0
  133. data/docs/guides/frontiers.md +93 -0
  134. data/docs/guides/halting.md +23 -0
  135. data/docs/guides/job_queues.md +26 -0
  136. data/docs/guides/locals.md +36 -0
  137. data/docs/guides/logging.md +22 -0
  138. data/docs/guides/page_objects.md +67 -0
  139. data/docs/guides/peeking.md +46 -0
  140. data/docs/guides/selenium_capybara.md +100 -0
  141. data/docs/guides/tutorial.md +452 -0
  142. data/docs/index.md +82 -0
  143. data/docs/js/navigation.js +11 -0
  144. data/docs/misc/contributing.md +20 -0
  145. data/docs/misc/testing.md +11 -0
  146. data/docs/recipes/authentication.md +23 -0
  147. data/docs/recipes/csv.md +29 -0
  148. data/docs/recipes/javascript.md +20 -0
  149. data/docs/recipes/multiple_uris.md +18 -0
  150. data/docs/recipes/screenshots.md +20 -0
  151. data/docs/routing/host_rules.md +24 -0
  152. data/docs/routing/path_rules.md +33 -0
  153. data/docs/routing/query_rules.md +69 -0
  154. data/docs/routing/routes.md +96 -0
  155. data/docs/routing/uri_rules.md +18 -0
  156. data/examples/collect_github_issues.rb +65 -0
  157. data/examples/find_foobar_on_wikipedia.rb +23 -0
  158. data/lib/wayfarer.rb +65 -0
  159. data/lib/wayfarer/configuration.rb +86 -0
  160. data/lib/wayfarer/crawl.rb +79 -0
  161. data/lib/wayfarer/crawl_observer.rb +103 -0
  162. data/lib/wayfarer/dispatcher.rb +104 -0
  163. data/lib/wayfarer/finders.rb +61 -0
  164. data/lib/wayfarer/frontiers/frontier.rb +79 -0
  165. data/lib/wayfarer/frontiers/memory_bloomfilter.rb +32 -0
  166. data/lib/wayfarer/frontiers/memory_frontier.rb +76 -0
  167. data/lib/wayfarer/frontiers/memory_trie_frontier.rb +39 -0
  168. data/lib/wayfarer/frontiers/normalize_uris.rb +48 -0
  169. data/lib/wayfarer/frontiers/redis_bloomfilter.rb +34 -0
  170. data/lib/wayfarer/frontiers/redis_frontier.rb +83 -0
  171. data/lib/wayfarer/http_adapters/adapter_pool.rb +62 -0
  172. data/lib/wayfarer/http_adapters/net_http_adapter.rb +77 -0
  173. data/lib/wayfarer/http_adapters/selenium_adapter.rb +80 -0
  174. data/lib/wayfarer/job.rb +192 -0
  175. data/lib/wayfarer/locals.rb +40 -0
  176. data/lib/wayfarer/page.rb +94 -0
  177. data/lib/wayfarer/parsers/json_parser.rb +20 -0
  178. data/lib/wayfarer/parsers/xml_parser.rb +27 -0
  179. data/lib/wayfarer/processor.rb +103 -0
  180. data/lib/wayfarer/routing/host_rule.rb +19 -0
  181. data/lib/wayfarer/routing/path_rule.rb +54 -0
  182. data/lib/wayfarer/routing/query_rule.rb +59 -0
  183. data/lib/wayfarer/routing/router.rb +71 -0
  184. data/lib/wayfarer/routing/rule.rb +102 -0
  185. data/lib/wayfarer/routing/uri_rule.rb +21 -0
  186. data/spec/configuration_spec.rb +26 -0
  187. data/spec/crawl_spec.rb +48 -0
  188. data/spec/finders_spec.rb +49 -0
  189. data/spec/frontiers/memory_bloomfilter_spec.rb +6 -0
  190. data/spec/frontiers/memory_frontier_spec.rb +6 -0
  191. data/spec/frontiers/memory_trie_frontier_spec.rb +6 -0
  192. data/spec/frontiers/normalize_uris_spec.rb +59 -0
  193. data/spec/frontiers/redis_bloomfilter_spec.rb +6 -0
  194. data/spec/frontiers/redis_frontier_spec.rb +6 -0
  195. data/spec/http_adapters/adapter_pool_spec.rb +33 -0
  196. data/spec/http_adapters/net_http_adapter_spec.rb +83 -0
  197. data/spec/http_adapters/selenium_adapter_spec.rb +53 -0
  198. data/spec/integration/callbacks_spec.rb +42 -0
  199. data/spec/integration/locals_spec.rb +106 -0
  200. data/spec/job_spec.rb +86 -0
  201. data/spec/page_spec.rb +38 -0
  202. data/spec/parsers/json_parser_spec.rb +30 -0
  203. data/spec/parsers/xml_parser_spec.rb +24 -0
  204. data/spec/processor_spec.rb +31 -0
  205. data/spec/routing/host_rule_spec.rb +48 -0
  206. data/spec/routing/path_rule_spec.rb +66 -0
  207. data/spec/routing/query_rule_spec.rb +124 -0
  208. data/spec/routing/router_spec.rb +67 -0
  209. data/spec/routing/rule_spec.rb +218 -0
  210. data/spec/routing/uri_rule_spec.rb +24 -0
  211. data/spec/shared/frontier.rb +96 -0
  212. data/spec/spec_helpers.rb +62 -0
  213. data/spec/wayfarer_spec.rb +24 -0
  214. data/support/static/finders.html +38 -0
  215. data/support/static/graph/details/a.html +10 -0
  216. data/support/static/graph/details/b.html +10 -0
  217. data/support/static/graph/index.html +20 -0
  218. data/support/static/json/dummy.json +13 -0
  219. data/support/static/links/links.html +28 -0
  220. data/support/static/xml/dummy.xml +120 -0
  221. data/support/test_app.rb +45 -0
  222. data/wayfarer-jruby.gemspec +49 -0
  223. data/wayfarer.gemspec +53 -0
  224. metadata +616 -0
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helpers"
3
+
4
+ describe Wayfarer::Routing::URIRule do
5
+ subject(:rule) { URIRule.new("http://example.com/foo/bar") }
6
+
7
+ describe "#matches?" do
8
+ context "with matching URI" do
9
+ let(:uri) { URI("http://example.com/foo/bar") }
10
+
11
+ it "returns true" do
12
+ expect(rule.matches?(uri)).to be true
13
+ end
14
+ end
15
+
16
+ context "with mismatching URI" do
17
+ let(:uri) { URI("http://example.com/foo/qux") }
18
+
19
+ it "returns true" do
20
+ expect(rule.matches?(uri)).to be false
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+ require "securerandom"
3
+
4
+ RSpec.shared_examples "Frontier" do |klass|
5
+ subject(:frontier) { klass.new(Configuration.new) }
6
+
7
+ after { frontier.free }
8
+
9
+ describe "#stage" do
10
+ let(:uri) { "http://example.com/foo#bar" }
11
+
12
+ it "stages a URI" do
13
+ frontier.stage("http://example.com")
14
+ expect(frontier.staged?("http://example.com")).to be true
15
+ end
16
+
17
+ it "stages multiple URIs" do
18
+ frontier.stage("http://example.com", "http://google.com")
19
+ expect(frontier.staged?("http://example.com")).to be true
20
+ expect(frontier.staged?("http://google.com")).to be true
21
+ end
22
+ end
23
+
24
+ describe "#cache" do
25
+ it "caches a URI" do
26
+ frontier.cache("http://example.com")
27
+ expect(frontier.cached?("http://example.com")).to be true
28
+ end
29
+
30
+ it "caches multiple URIs" do
31
+ frontier.cache("http://example.com", "http://google.com")
32
+ expect(frontier.cached?("http://example.com")).to be true
33
+ expect(frontier.cached?("http://google.com")).to be true
34
+ end
35
+ end
36
+
37
+ describe "#cycle" do
38
+ let(:uri) { "http://example.com" }
39
+
40
+ it "does not stage the same URI twice" do
41
+ 2.times { frontier.stage(uri) }
42
+
43
+ expect { frontier.cycle }.to change { frontier.current_uris.count }.by(1)
44
+ end
45
+
46
+ it "caches URIs" do
47
+ frontier.stage(uri)
48
+
49
+ 2.times { frontier.cycle }
50
+
51
+ expect(frontier.cached?(uri)).to be true
52
+ end
53
+
54
+ context "with staged URIs" do
55
+ before { frontier.stage(uri) }
56
+
57
+ it "swaps current and staged URIs" do
58
+ frontier.cycle
59
+ expect(frontier.current_uris).to eq [URI(uri)]
60
+ expect(frontier.staged_uris).to eq []
61
+ end
62
+
63
+ it "returns true" do
64
+ expect(frontier.cycle).to be true
65
+ end
66
+ end
67
+
68
+ context "without staged URIs" do
69
+ it "returns false" do
70
+ expect(frontier.cycle).to be false
71
+ end
72
+ end
73
+
74
+ it "does not set cached URIs as current" do
75
+ frontier.cache(uri)
76
+ frontier.stage(uri)
77
+ frontier.cycle
78
+
79
+ expect(frontier.current_uris).to be_empty
80
+ end
81
+
82
+ context "when circulation is allowed" do
83
+ subject(:frontier) do
84
+ klass.new(Configuration.new(allow_circulation: true))
85
+ end
86
+
87
+ it "sets cached URIs as current" do
88
+ 3.times do
89
+ frontier.stage(uri)
90
+ frontier.cycle
91
+ expect(frontier.current_uris).to eq [URI(uri)]
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+ require_relative "../lib/wayfarer"
3
+
4
+ require("bundler") && Bundler.require
5
+
6
+ include Wayfarer
7
+ include Wayfarer::HTTPAdapters
8
+ include Wayfarer::Routing
9
+ include Wayfarer::Frontiers
10
+
11
+ if RUBY_PLATFORM == "java"
12
+ Wayfarer::Frontiers::MemoryBloomfilter = \
13
+ Wayfarer::Frontiers::MemoryTrieFrontier = \
14
+ Wayfarer::Frontiers::RedisBloomfilter = nil
15
+ end
16
+
17
+ Dir["./spec/shared/**/*.rb"].sort.each { |file| require file }
18
+
19
+ module SpecHelpers
20
+ def jruby?
21
+ RUBY_PLATFORM == "java"
22
+ end
23
+
24
+ def test_app(path)
25
+ URI("http://localhost:9876#{path}")
26
+ end
27
+
28
+ def fetch_page(uri)
29
+ NetHTTPAdapter.instance.fetch(URI(uri))
30
+ end
31
+
32
+ def html_fragment(html)
33
+ Nokogiri::HTML.fragment(html)
34
+ end
35
+
36
+ def node_set(html)
37
+ html_fragment(html).css("*")
38
+ end
39
+ end
40
+
41
+ RSpec.configure do |config|
42
+ config.include(SpecHelpers)
43
+
44
+ config.before do
45
+ Wayfarer.config.reset!
46
+ Wayfarer.config.selenium_argv = [:phantomjs]
47
+ end
48
+
49
+ config.before(integration: true) do
50
+ Wayfarer.logger.level = :fatal
51
+ end
52
+
53
+ config.after(integration: true) do
54
+ Wayfarer.logger.level = :debug
55
+ end
56
+
57
+ config.before(mri_only: true) do
58
+ skip("Not supported on JRuby") and fail if RUBY_PLATFORM == "java"
59
+ end
60
+
61
+ config.alias_example_to :they
62
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helpers"
3
+
4
+ describe Wayfarer do
5
+ describe "::VERSION" do
6
+ it("is present") { expect(defined? Wayfarer::VERSION).not_to be nil }
7
+ end
8
+
9
+ describe "::logger, ::logger=" do
10
+ it "returns and alters the logger" do
11
+ expect(Wayfarer.logger).to be_a Logger
12
+ end
13
+ end
14
+
15
+ describe "::config" do
16
+ it "alters keys and values" do
17
+ Wayfarer.config.foo = :bar
18
+ expect(Wayfarer.config.foo).to be :bar
19
+
20
+ Wayfarer.config { |config| config.baz = :qux }
21
+ expect(Wayfarer.config.baz).to be :qux
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,38 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>Things</title>
5
+
6
+ <!-- Stylesheet -->
7
+ <link rel="stylesheet" href="/a.css" id="stylesheet-a">
8
+ <link rel="stylesheet" href="b.css" id="stylesheet-b">
9
+ <link rel="stylesheet" href="http://google.com/c.css" id="stylesheet-c">
10
+
11
+ <!-- Duplicate stylesheets -->
12
+ <link rel="stylesheet" href="/a.css">
13
+ <link rel="stylesheet" href="b.css">
14
+ <link rel="stylesheet" href="http://google.com/c.css">
15
+ </head>
16
+
17
+ <body>
18
+ <ul>
19
+ <li><a href="/foo">Foo</a></li>
20
+ <li><a href="/bar">Bar</a></li>
21
+ <li><a href="/baz">Baz</a></li>
22
+
23
+ <li><a href="foo">Foo</a></li>
24
+ <li><a href="bar">Bar</a></li>
25
+ <li><a href="baz">Baz</a></li>
26
+
27
+ <!-- Duplicates -->
28
+ <li><a href="foo">Foo</a></li>
29
+ <li><a href="bar">Bar</a></li>
30
+ <li><a href="baz">Baz</a></li>
31
+
32
+ <!-- Absolute links -->
33
+ <li><a href="http://google.com">Foobar</a></li>
34
+ <li><a href="http://yahoo.com">Yahoo</a></li>
35
+ <li><a href="http://aol.com">AOL</a></li>
36
+ </ul>
37
+ </body>
38
+ </html>
@@ -0,0 +1,10 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>Detail A</title>
5
+ </head>
6
+
7
+ <body>
8
+ <a href="b.html">Detail B</a>
9
+ </body>
10
+ </html>
@@ -0,0 +1,10 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>Detail B</title>
5
+ </head>
6
+
7
+ <body>
8
+ <a href="a.html">Detail A</a>
9
+ </body>
10
+ </html>
@@ -0,0 +1,20 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>Index</title>
5
+ </head>
6
+
7
+ <body>
8
+ <a href="details/a.html">Detail A</a>
9
+ <a href="details/b.html">Detail B</a>
10
+
11
+ <!-- Erroneous links -->
12
+ <a href="/status_code/400">400</a>
13
+ <a href="/status_code/403">403</a>
14
+ <a href="/status_code/404">404</a>
15
+ <a href="http://bro.ken">Broken</a>
16
+
17
+ <!-- Redirect loop -->
18
+ <a href="/redirect_loop">Redirect loop</a>
19
+ </body>
20
+ </html>
@@ -0,0 +1,13 @@
1
+ {
2
+ "id": 1,
3
+ "name": "Foo",
4
+ "price": 123,
5
+ "tags": [
6
+ "Bar",
7
+ "Eek"
8
+ ],
9
+ "stock": {
10
+ "warehouse": 300,
11
+ "retail": 20
12
+ }
13
+ }
@@ -0,0 +1,28 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>Things</title>
5
+ </head>
6
+
7
+ <body>
8
+ <ul>
9
+ <li><a href="/foo">Foo</a></li>
10
+ <li><a href="/bar">Bar</a></li>
11
+ <li><a href="/baz">Baz</a></li>
12
+
13
+ <li><a href="foo">Foo</a></li>
14
+ <li><a href="bar">Bar</a></li>
15
+ <li><a href="baz">Baz</a></li>
16
+
17
+ <!-- Duplicates -->
18
+ <li><a href="foo">Foo</a></li>
19
+ <li><a href="bar">Bar</a></li>
20
+ <li><a href="baz">Baz</a></li>
21
+
22
+ <!-- Absolute links -->
23
+ <li><a href="http://google.com">Foobar</a></li>
24
+ <li><a href="http://yahoo.com">Yahoo</a></li>
25
+ <li><a href="http://aol.com">AOL</a></li>
26
+ </ul>
27
+ </body>
28
+ </html>
@@ -0,0 +1,120 @@
1
+ <?xml version="1.0"?>
2
+ <catalog>
3
+ <book id="bk101">
4
+ <author>Gambardella, Matthew</author>
5
+ <title>XML Developer's Guide</title>
6
+ <genre>Computer</genre>
7
+ <price>44.95</price>
8
+ <publish_date>2000-10-01</publish_date>
9
+ <description>An in-depth look at creating applications
10
+ with XML.</description>
11
+ </book>
12
+ <book id="bk102">
13
+ <author>Ralls, Kim</author>
14
+ <title>Midnight Rain</title>
15
+ <genre>Fantasy</genre>
16
+ <price>5.95</price>
17
+ <publish_date>2000-12-16</publish_date>
18
+ <description>A former architect battles corporate zombies,
19
+ an evil sorceress, and her own childhood to become queen
20
+ of the world.</description>
21
+ </book>
22
+ <book id="bk103">
23
+ <author>Corets, Eva</author>
24
+ <title>Maeve Ascendant</title>
25
+ <genre>Fantasy</genre>
26
+ <price>5.95</price>
27
+ <publish_date>2000-11-17</publish_date>
28
+ <description>After the collapse of a nanotechnology
29
+ society in England, the young survivors lay the
30
+ foundation for a new society.</description>
31
+ </book>
32
+ <book id="bk104">
33
+ <author>Corets, Eva</author>
34
+ <title>Oberon's Legacy</title>
35
+ <genre>Fantasy</genre>
36
+ <price>5.95</price>
37
+ <publish_date>2001-03-10</publish_date>
38
+ <description>In post-apocalypse England, the mysterious
39
+ agent known only as Oberon helps to create a new life
40
+ for the inhabitants of London. Sequel to Maeve
41
+ Ascendant.</description>
42
+ </book>
43
+ <book id="bk105">
44
+ <author>Corets, Eva</author>
45
+ <title>The Sundered Grail</title>
46
+ <genre>Fantasy</genre>
47
+ <price>5.95</price>
48
+ <publish_date>2001-09-10</publish_date>
49
+ <description>The two daughters of Maeve, half-sisters,
50
+ battle one another for control of England. Sequel to
51
+ Oberon's Legacy.</description>
52
+ </book>
53
+ <book id="bk106">
54
+ <author>Randall, Cynthia</author>
55
+ <title>Lover Birds</title>
56
+ <genre>Romance</genre>
57
+ <price>4.95</price>
58
+ <publish_date>2000-09-02</publish_date>
59
+ <description>When Carla meets Paul at an ornithology
60
+ conference, tempers fly as feathers get ruffled.</description>
61
+ </book>
62
+ <book id="bk107">
63
+ <author>Thurman, Paula</author>
64
+ <title>Splish Splash</title>
65
+ <genre>Romance</genre>
66
+ <price>4.95</price>
67
+ <publish_date>2000-11-02</publish_date>
68
+ <description>A deep sea diver finds true love twenty
69
+ thousand leagues beneath the sea.</description>
70
+ </book>
71
+ <book id="bk108">
72
+ <author>Knorr, Stefan</author>
73
+ <title>Creepy Crawlies</title>
74
+ <genre>Horror</genre>
75
+ <price>4.95</price>
76
+ <publish_date>2000-12-06</publish_date>
77
+ <description>An anthology of horror stories about roaches,
78
+ centipedes, scorpions and other insects.</description>
79
+ </book>
80
+ <book id="bk109">
81
+ <author>Kress, Peter</author>
82
+ <title>Paradox Lost</title>
83
+ <genre>Science Fiction</genre>
84
+ <price>6.95</price>
85
+ <publish_date>2000-11-02</publish_date>
86
+ <description>After an inadvertant trip through a Heisenberg
87
+ Uncertainty Device, James Salway discovers the problems
88
+ of being quantum.</description>
89
+ </book>
90
+ <book id="bk110">
91
+ <author>O'Brien, Tim</author>
92
+ <title>Microsoft .NET: The Programming Bible</title>
93
+ <genre>Computer</genre>
94
+ <price>36.95</price>
95
+ <publish_date>2000-12-09</publish_date>
96
+ <description>Microsoft's .NET initiative is explored in
97
+ detail in this deep programmer's reference.</description>
98
+ </book>
99
+ <book id="bk111">
100
+ <author>O'Brien, Tim</author>
101
+ <title>MSXML3: A Comprehensive Guide</title>
102
+ <genre>Computer</genre>
103
+ <price>36.95</price>
104
+ <publish_date>2000-12-01</publish_date>
105
+ <description>The Microsoft MSXML3 parser is covered in
106
+ detail, with attention to XML DOM interfaces, XSLT processing,
107
+ SAX and more.</description>
108
+ </book>
109
+ <book id="bk112">
110
+ <author>Galos, Mike</author>
111
+ <title>Visual Studio 7: A Comprehensive Guide</title>
112
+ <genre>Computer</genre>
113
+ <price>49.95</price>
114
+ <publish_date>2001-04-16</publish_date>
115
+ <description>Microsoft Visual Studio 7 is explored in depth,
116
+ looking at how Visual Basic, Visual C++, C#, and ASP+ are
117
+ integrated into a comprehensive development
118
+ environment.</description>
119
+ </book>
120
+ </catalog>