lanyon 0.3.4 → 0.4.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c6cb7a805a0eb3c37772d55e691f36ac3e1c2ab6
4
- data.tar.gz: 3269b6445233679a7aa0f5cdf120950e8674bb78
2
+ SHA256:
3
+ metadata.gz: a2f2ed82be1b1a0e4a4ca74b9ef4bf855fd321fbfdab480711e19b506c29e79e
4
+ data.tar.gz: e8713bd319fb150aa8763f9b977a6d3407cef1f2fe1edef01e712a8d0c5f09e4
5
5
  SHA512:
6
- metadata.gz: ec3bc073134f90350a6b8129c811fae79c6f4284b95c830ee01662e2480f3fbf97eea1e75e232ef5e3a97a83f8a9b8e5fb65d0c94d4988b4b2906c804739fdb4
7
- data.tar.gz: 573de99ab0c5d7255dbdde58464797a64f7c2f9f3c54b7bd3e0874b007ea115d6e3cd594e03ff26d534d76a96a54ba6224fdd3b22e584417dd53553dc37ad1af
6
+ metadata.gz: b4acef77523d343f1dcf1b2c13037cf2ca3aafd9c34613daf52aaae6697811a2b571278e52c2b75db653881fe467ddcb54abdbc991aca7ab8fed87a7cbebf946
7
+ data.tar.gz: 02b0eb0279f08fde9307f01c5190efc3d2197d5b7f6205aea87383811091582a9d85fd11cddd656f33a7ef5de850dd671e9770cb92a062c4af7530116321c7f4
data/History.md CHANGED
@@ -1,6 +1,29 @@
1
1
  Release History
2
2
  ===============
3
3
 
4
+ ## 0.4.3
5
+
6
+ * Use Rack::ContentLength middleware to fix missing
7
+ Content-Length headers for rack 2.1.0 and later
8
+ * Update development dependencies
9
+
10
+ ## 0.4.2
11
+
12
+ * Avoid deprecation warnings for minitest expectations
13
+ * Improve code style
14
+
15
+ ## 0.4.1
16
+
17
+ * Drop pessimistic constraint on Jekyll version
18
+ * Remove Jekyll cache directory after tests
19
+ * Let "clean" task remove Jekyll cache directory
20
+ * Add Jekyll cache directory to .gitignore
21
+ * Add magic comments for frozen string literals
22
+
23
+ ## 0.4.0
24
+
25
+ * Support .html extension stripping
26
+
4
27
  ## 0.3.4
5
28
 
6
29
  * Allow Rack 2
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015-2016 Marcus Stollsteimer
3
+ Copyright (c) 2015-2022 Marcus Stollsteimer
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -56,7 +56,7 @@ or as Lanyon initialization options in `config.ru`.
56
56
  Example:
57
57
 
58
58
  ``` ruby
59
- run Lanyon.application(:destination => "mysite")
59
+ run Lanyon.application(destination: "mysite")
60
60
  ```
61
61
 
62
62
  This will set a custom destination path, overriding the default (`_site`)
@@ -70,7 +70,7 @@ Additional Lanyon initialization options:
70
70
  (default: false)
71
71
 
72
72
  Note that on read-only filesystems a site build will fail,
73
- so you must set `:skip_build => true` in these cases.
73
+ so you must set `skip_build: true` in these cases.
74
74
 
75
75
  ### Custum 404 Page
76
76
 
@@ -83,6 +83,20 @@ This can also be a file generated by Jekyll from e.g. Markdown sources.
83
83
 
84
84
  - Gem dependencies (runtime): `jekyll`, `rack`
85
85
 
86
+ ## How URLs are resolved
87
+
88
+ Lanyon maps URLs to corresponding files as follows:
89
+
90
+ 1. a `path/` with a trailing slash is changed to `path/index.html`,
91
+ 2. then, Lanyon checks for an exactly corresponding file,
92
+ 3. when `path` does not exist but `path/index.html` does,
93
+ the response will be a redirect to `path/`,
94
+ 4. when neither 2. nor 3. apply, +path.html+ is tried.
95
+
96
+ To avoid confusion, it's probably a good idea to have only one
97
+ of `resource`, `resource/index.html`, and `resource.html` present
98
+ as file in your site.
99
+
86
100
  ## Reporting Bugs
87
101
 
88
102
  Report bugs on the Lanyon home page: <https://github.com/stomar/lanyon/>
@@ -93,7 +107,7 @@ Lanyon was inspired by [rack-jekyll][rack-jekyll] and written as a replacement.
93
107
 
94
108
  ## License
95
109
 
96
- Copyright &copy; 2015-2016 Marcus Stollsteimer
110
+ Copyright &copy; 2015-2022 Marcus Stollsteimer
97
111
 
98
112
  Lanyon is licensed under the [MIT License][MIT].
99
113
  See also the included `LICENSE` file for more information.
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ def gemspec_file
7
7
  end
8
8
 
9
9
 
10
- task :default => [:test]
10
+ task default: [:test]
11
11
 
12
12
  Rake::TestTask.new do |t|
13
13
  t.pattern = "test/**/test_*.rb"
@@ -25,6 +25,7 @@ end
25
25
  desc "Remove generated files"
26
26
  task :clean do
27
27
  FileUtils.rm_rf("demo/_site")
28
+ FileUtils.rm_rf("demo/.jekyll-cache")
28
29
  FileUtils.rm(Dir.glob("*.gem"))
29
30
  end
30
31
 
data/lanyon.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
 
11
11
  s.summary = "Lanyon serves your Jekyll site as a Rack application."
12
12
  s.description =
13
- "Lanyon is a good friend of Jekyll, the static site generator, " +
13
+ "Lanyon is a good friend of Jekyll, the static site generator, " \
14
14
  "and transforms your website into a Rack application."
15
15
 
16
16
  s.authors = ["Marcus Stollsteimer"]
@@ -21,11 +21,11 @@ Gem::Specification.new do |s|
21
21
 
22
22
  s.required_ruby_version = ">= 2.0.0"
23
23
 
24
- s.add_dependency "jekyll", ">= 2.0", "< 4.0"
24
+ s.add_dependency "jekyll", ">= 2.0"
25
25
  s.add_dependency "rack", ">= 1.6", "< 3.0"
26
26
 
27
- s.add_development_dependency "rake", "~> 11.2"
28
27
  s.add_development_dependency "minitest", "~> 5.8"
28
+ s.add_development_dependency "rake", "~> 13.0"
29
29
 
30
30
  s.require_paths = ["lib"]
31
31
 
@@ -40,7 +40,7 @@ Gem::Specification.new do |s|
40
40
  ] +
41
41
  Dir.glob("lib/**/*") +
42
42
  Dir.glob("test/**/*") +
43
- Dir.glob("demo/**/*").reject {|f| f =~ %r(\Ademo/_site/) }
43
+ Dir.glob("demo/**/*").reject {|f| f.start_with?("demo/_site/") }
44
44
 
45
45
  s.extra_rdoc_files = %w[README.md LICENSE History.md]
46
46
  s.rdoc_options = ["--charset=UTF-8", "--main=README.md"]
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rack/mime"
2
4
  require "rack/request"
3
5
  require "rack/response"
@@ -42,7 +44,7 @@ module Lanyon
42
44
 
43
45
  def response(filename) # :nodoc:
44
46
  response = Rack::Response.new(File.binread(filename))
45
- response["Content-Type"] = media_type(filename)
47
+ response["Content-Type"] = media_type(filename)
46
48
 
47
49
  response.finish
48
50
  end
@@ -61,7 +63,7 @@ module Lanyon
61
63
  end
62
64
 
63
65
  def html_wrap(title, content) # :nodoc:
64
- <<-document.gsub(/^ {6}/, "")
66
+ <<-DOCUMENT.gsub(/^ {6}/, "")
65
67
  <!DOCTYPE html>
66
68
  <html lang="en">
67
69
  <head>
@@ -71,7 +73,7 @@ module Lanyon
71
73
  #{content}
72
74
  </body>
73
75
  </html>
74
- document
76
+ DOCUMENT
75
77
  end
76
78
 
77
79
  def default_404_body # :nodoc:
@@ -95,7 +97,7 @@ module Lanyon
95
97
  end
96
98
 
97
99
  def redirect_body(to_path) # :nodoc:
98
- message = %Q{<p>Redirecting to <a href="#{to_path}">#{to_path}</a>.</p>}
100
+ message = %Q(<p>Redirecting to <a href="#{to_path}">#{to_path}</a>.</p>)
99
101
 
100
102
  html_wrap("Redirection", message)
101
103
  end
@@ -108,9 +110,9 @@ module Lanyon
108
110
 
109
111
  body = redirect_body(location)
110
112
  headers = {
111
- "Location" => location,
113
+ "Location" => location,
112
114
  "Cache-Control" => "max-age=#{cache_time}, must-revalidate",
113
- "Expires" => (Time.now + cache_time).httpdate
115
+ "Expires" => (Time.now + cache_time).httpdate
114
116
  }
115
117
 
116
118
  html_response(body, 301, headers)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "uri"
2
4
 
3
5
 
data/lib/lanyon/router.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rack/utils"
2
4
 
3
5
 
@@ -16,9 +18,17 @@ module Lanyon
16
18
  # Returns the full file system path of the file corresponding to
17
19
  # the given URL +path+, or
18
20
  #
19
- # - +:not_found+ if no corresponding file exists,
20
- # - +:must_redirect+ if the request must be redirected to <tt>path/</tt>.
21
+ # - +:must_redirect+ if the request must be redirected to +path/+,
22
+ # - +:not_found+ if no corresponding file exists.
23
+ #
24
+ # The return value is found as follows:
21
25
  #
26
+ # 1. a +path/+ with a trailing slash is changed to +path/index.html+,
27
+ # 2. then, the method checks for an exactly corresponding file,
28
+ # 3. when +path+ does not exist but +path/index.html+ does,
29
+ # a redirect will be indicated,
30
+ # 4. finally, when no exactly corresponding file or redirect
31
+ # can be found, +path.html+ is tried.
22
32
  def endpoint(path)
23
33
  normalized = normalize_path_info(path)
24
34
 
@@ -27,6 +37,8 @@ module Lanyon
27
37
  fullpath
28
38
  elsif needs_redirect_to_dir?(fullpath)
29
39
  :must_redirect
40
+ elsif FileTest.file?(fullpath_html = "#{fullpath}.html")
41
+ fullpath_html
30
42
  else
31
43
  :not_found
32
44
  end
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lanyon
2
- VERSION = "0.3.4"
3
- DATE = "2016-08-01"
4
+ VERSION = "0.4.3"
5
+ DATE = "2022-01-06"
4
6
  end
data/lib/lanyon.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # = lanyon.rb
2
4
  #
3
5
  # See Lanyon module for documentation.
@@ -49,6 +51,7 @@ module Lanyon
49
51
 
50
52
  Rack::Builder.new do
51
53
  use Rack::Head
54
+ use Rack::ContentLength
52
55
  use Rack::ConditionalGet
53
56
  use Rack::ETag, nil, nil
54
57
 
@@ -68,7 +71,7 @@ module Lanyon
68
71
 
69
72
  # @private
70
73
  def self.default_options # :nodoc:
71
- { :skip_build => false }
74
+ { skip_build: false }
72
75
  end
73
76
 
74
77
  # @private
data/test/helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "minitest/autorun"
2
4
  require "fileutils"
3
5
  require "stringio"
@@ -6,7 +8,11 @@ require "rack/mock"
6
8
  require "lanyon"
7
9
 
8
10
 
9
- TEST_DIR = File.expand_path("..", __FILE__)
11
+ TEST_DIR = File.expand_path(__dir__)
12
+
13
+ SOURCE_DIR = File.join(TEST_DIR, "source")
14
+ CACHE_DIR = File.join(SOURCE_DIR, ".jekyll-cache")
15
+
10
16
  TEMP_DIR = File.join(TEST_DIR, "tmp")
11
17
 
12
18
 
@@ -24,10 +30,13 @@ def chdir_tempdir
24
30
  Dir.chdir(TEMP_DIR)
25
31
  end
26
32
 
27
- def sourcedir
28
- File.join(TEST_DIR, "source")
33
+ def teardown_cachedir
34
+ FileUtils.rm_rf(CACHE_DIR) if File.exist?(CACHE_DIR)
29
35
  end
30
36
 
37
+ def sourcedir
38
+ SOURCE_DIR
39
+ end
31
40
 
32
41
  def silence_output
33
42
  original_stderr, original_stdout = $stderr, $stdout
@@ -38,7 +47,6 @@ ensure
38
47
  $stderr, $stdout = original_stderr, original_stdout
39
48
  end
40
49
 
41
-
42
50
  def file_must_exist(filename)
43
51
  assert File.exist?(filename),
44
52
  "Expected file `#{filename}' to exist."
data/test/test_build.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "helper"
2
4
 
3
5
 
@@ -9,7 +11,7 @@ describe "when creating a Lanyon application" do
9
11
 
10
12
  destdir = File.join(tempdir, "_site")
11
13
 
12
- @dir_options = { :source => sourcedir, :destination => destdir }
14
+ @dir_options = { source: sourcedir, destination: destdir }
13
15
  @page = File.join(destdir, "index.html")
14
16
  @no_page = File.join(destdir, "not_a_page.html")
15
17
 
@@ -21,6 +23,7 @@ describe "when creating a Lanyon application" do
21
23
 
22
24
  after do
23
25
  teardown_tempdir
26
+ teardown_cachedir
24
27
  end
25
28
 
26
29
  it "builds the site by default, removing old content" do
@@ -33,7 +36,7 @@ describe "when creating a Lanyon application" do
33
36
  end
34
37
 
35
38
  it "does not build the site when :skip_build option is set" do
36
- options = {:skip_build => true}.merge(@dir_options)
39
+ options = { skip_build: true }.merge(@dir_options)
37
40
  silence_output do
38
41
  Lanyon.application(options)
39
42
  end
@@ -43,7 +46,7 @@ describe "when creating a Lanyon application" do
43
46
  end
44
47
 
45
48
  it "does always build the site with ::build" do
46
- options = {:skip_build => true}.merge(@dir_options)
49
+ options = { skip_build: true }.merge(@dir_options)
47
50
  silence_output do
48
51
  Lanyon.build(options)
49
52
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "helper"
2
4
 
3
5
 
@@ -23,7 +25,7 @@ describe "when configuring site" do
23
25
 
24
26
  it "loads the correct default destination" do
25
27
  config = get_jekyll_config
26
- config["destination"].must_equal File.join(Dir.pwd, "_site")
28
+ _(config["destination"]).must_equal File.join(Dir.pwd, "_site")
27
29
  end
28
30
  end
29
31
 
@@ -41,8 +43,8 @@ describe "when configuring site" do
41
43
 
42
44
  it "loads the configuration from file" do
43
45
  config = get_jekyll_config
44
- config.must_include "config_file_opt"
45
- config["config_file_opt"].must_equal "ok"
46
+ _(config).must_include "config_file_opt"
47
+ _(config["config_file_opt"]).must_equal "ok"
46
48
  end
47
49
  end
48
50
 
@@ -59,28 +61,28 @@ describe "when configuring site" do
59
61
  end
60
62
 
61
63
  it "loads the configuration from file" do
62
- config = get_jekyll_config(:config => "_my_config.yml")
63
- config.must_include "config_file_opt"
64
- config["config_file_opt"].must_equal "ok"
64
+ config = get_jekyll_config(config: "_my_config.yml")
65
+ _(config).must_include "config_file_opt"
66
+ _(config["config_file_opt"]).must_equal "ok"
65
67
  end
66
68
  end
67
69
 
68
70
  describe "when initialization options are given" do
69
71
 
70
72
  it "has the initialization options" do
71
- config = get_jekyll_config(:init_opt => "ok")
72
- config.must_include "init_opt"
73
- config["init_opt"].must_equal "ok"
73
+ config = get_jekyll_config(init_opt: "ok")
74
+ _(config).must_include "init_opt"
75
+ _(config["init_opt"]).must_equal "ok"
74
76
  end
75
77
 
76
78
  it "has the correct destination" do
77
- config = get_jekyll_config(:destination => "/project/_site")
78
- config["destination"].must_equal "/project/_site"
79
+ config = get_jekyll_config(destination: "/project/_site")
80
+ _(config["destination"]).must_equal "/project/_site"
79
81
  end
80
82
 
81
83
  it "does not pass :skip_build on to Jekyll" do
82
- config = get_jekyll_config(:skip_build => "ok")
83
- config.wont_include "skip_build"
84
+ config = get_jekyll_config(skip_build: "ok")
85
+ _(config).wont_include "skip_build"
84
86
  end
85
87
  end
86
88
 
@@ -99,17 +101,16 @@ describe "when configuring site" do
99
101
  end
100
102
 
101
103
  it "has all options and initialization options override file options" do
102
- config = get_jekyll_config(:init_opt => "ok",
103
- :common_opt => "from init")
104
- config.must_include "init_opt"
105
- config.must_include "config_file_opt"
106
- config.must_include "common_opt"
107
- config["common_opt"].must_equal "from init"
104
+ config = get_jekyll_config(init_opt: "ok", common_opt: "from init")
105
+ _(config).must_include "init_opt"
106
+ _(config).must_include "config_file_opt"
107
+ _(config).must_include "common_opt"
108
+ _(config["common_opt"]).must_equal "from init"
108
109
  end
109
110
 
110
111
  it "has the correct destination" do
111
- config = get_jekyll_config(:destination => "/project/_site_from_init")
112
- config["destination"].must_equal "/project/_site_from_init"
112
+ config = get_jekyll_config(destination: "/project/_site_from_init")
113
+ _(config["destination"]).must_equal "/project/_site_from_init"
113
114
  end
114
115
  end
115
116
  end
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require_relative "helper"
4
4
 
@@ -18,12 +18,13 @@ describe "when handling requests" do
18
18
 
19
19
  @destdir = File.join(tempdir, "_site")
20
20
 
21
- app = get_app(:source => sourcedir, :destination => @destdir)
21
+ app = get_app(source: sourcedir, destination: @destdir)
22
22
  @request = Rack::MockRequest.new(app)
23
23
  end
24
24
 
25
25
  after do
26
26
  teardown_tempdir
27
+ teardown_cachedir
27
28
  end
28
29
 
29
30
 
@@ -34,23 +35,23 @@ describe "when handling requests" do
34
35
  end
35
36
 
36
37
  it "returns status 200" do
37
- @response.status.must_equal 200
38
+ _(@response.status).must_equal 200
38
39
  end
39
40
 
40
41
  it "returns correct Content-Length header" do
41
- @response.original_headers["Content-Length"].must_equal "17"
42
+ _(@response.original_headers["Content-Length"]).must_equal "17"
42
43
  end
43
44
 
44
45
  it "returns correct Content-Type header" do
45
- @response.headers["Content-Type"].must_equal "text/html"
46
+ _(@response.headers["Content-Type"]).must_equal "text/html"
46
47
  end
47
48
 
48
49
  it "returns an ETag header" do
49
- @response.headers["ETag"].wont_be_nil
50
+ _(@response.headers["ETag"]).wont_be_nil
50
51
  end
51
52
 
52
53
  it "returns correct body" do
53
- @response.body.must_match %r{<p>Home Page</p>}
54
+ _(@response.body).must_match %r{<p>Home Page</p>}
54
55
  end
55
56
  end
56
57
 
@@ -61,21 +62,21 @@ describe "when handling requests" do
61
62
  @response = @request.get("/not/a/page")
62
63
  end
63
64
 
64
- it "returns status 200" do
65
- @response.status.must_equal 404
65
+ it "returns status 404" do
66
+ _(@response.status).must_equal 404
66
67
  end
67
68
 
68
69
  it "returns correct Content-Length header" do
69
- @response.original_headers["Content-Length"].must_equal "142"
70
+ _(@response.original_headers["Content-Length"]).must_equal "142"
70
71
  end
71
72
 
72
73
  it "returns correct Content-Type header" do
73
- @response.headers["Content-Type"].must_equal "text/html"
74
+ _(@response.headers["Content-Type"]).must_equal "text/html"
74
75
  end
75
76
 
76
77
  it "returns correct body" do
77
78
  expected = %r{<!DOCTYPE html>.*<p>404: Not Found</p>}m
78
- @response.body.must_match expected
79
+ _(@response.body).must_match expected
79
80
  end
80
81
  end
81
82
 
@@ -86,7 +87,7 @@ describe "when handling requests" do
86
87
  @custom_404 = File.join(sourcedir, "404.html")
87
88
  File.open(@custom_404, "w") {|f| f.print "Custom 404" }
88
89
 
89
- app = get_app(:source => sourcedir, :destination => @destdir)
90
+ app = get_app(source: sourcedir, destination: @destdir)
90
91
  request = Rack::MockRequest.new(app)
91
92
  @response = request.get("/not/a/page")
92
93
  end
@@ -96,15 +97,15 @@ describe "when handling requests" do
96
97
  end
97
98
 
98
99
  it "returns correct Content-Length header" do
99
- @response.original_headers["Content-Length"].must_equal "10"
100
+ _(@response.original_headers["Content-Length"]).must_equal "10"
100
101
  end
101
102
 
102
103
  it "returns correct Content-Type header" do
103
- @response.headers["Content-Type"].must_equal "text/html"
104
+ _(@response.headers["Content-Type"]).must_equal "text/html"
104
105
  end
105
106
 
106
107
  it "returns correct body" do
107
- @response.body.must_equal "Custom 404"
108
+ _(@response.body).must_equal "Custom 404"
108
109
  end
109
110
  end
110
111
 
@@ -116,19 +117,19 @@ describe "when handling requests" do
116
117
  end
117
118
 
118
119
  it "returns status 200" do
119
- @response.status.must_equal 200
120
+ _(@response.status).must_equal 200
120
121
  end
121
122
 
122
123
  it "returns correct Content-Type header" do
123
- @response.headers["Content-Type"].must_equal "text/html"
124
+ _(@response.headers["Content-Type"]).must_equal "text/html"
124
125
  end
125
126
 
126
127
  it "returns correct Content-Length header" do
127
- @response.original_headers["Content-Length"].must_equal "19"
128
+ _(@response.original_headers["Content-Length"]).must_equal "19"
128
129
  end
129
130
 
130
131
  it "returns correct body" do
131
- @response.body.must_match %r{<p>A Blog Post</p>}
132
+ _(@response.body).must_match %r{<p>A Blog Post</p>}
132
133
  end
133
134
  end
134
135
 
@@ -140,12 +141,12 @@ describe "when handling requests" do
140
141
  end
141
142
 
142
143
  it "returns status 200" do
143
- @response.status.must_equal 200
144
+ _(@response.status).must_equal 200
144
145
  end
145
146
 
146
147
  it "returns Content-Type 'application/octet-stream'" do
147
148
  type = @response.headers["Content-Type"]
148
- type.must_equal "application/octet-stream"
149
+ _(type).must_equal "application/octet-stream"
149
150
  end
150
151
  end
151
152
 
@@ -154,12 +155,12 @@ describe "when handling requests" do
154
155
 
155
156
  it "returns correct Content-Type for *.css" do
156
157
  type = @request.get("/css/test.css").headers["Content-Type"]
157
- type.must_equal "text/css"
158
+ _(type).must_equal "text/css"
158
159
  end
159
160
 
160
161
  it "returns correct Content-Type for *.min.js" do
161
162
  type = @request.get("/js/test.min.js").headers["Content-Type"]
162
- type.must_equal "application/javascript"
163
+ _(type).must_equal "application/javascript"
163
164
  end
164
165
  end
165
166
 
@@ -167,11 +168,11 @@ describe "when handling requests" do
167
168
  describe "when asked for partially matching paths" do
168
169
 
169
170
  it "returns status 404 for path 1" do
170
- @request.get("/2015/10/05/hello").status.must_equal 404
171
+ _(@request.get("/2015/10/05/hello").status).must_equal 404
171
172
  end
172
173
 
173
174
  it "returns status 404 for path 2" do
174
- @request.get("/10/05/hello-world.html").status.must_equal 404
175
+ _(@request.get("/10/05/hello-world.html").status).must_equal 404
175
176
  end
176
177
  end
177
178
 
@@ -182,8 +183,8 @@ describe "when handling requests" do
182
183
  filename = File.join(@destdir, "/../_site/index.html")
183
184
  assert File.exist?(filename)
184
185
 
185
- @response = @request.get("/../_site/index.html")
186
- @response.status.must_equal 404
186
+ response = @request.get("/../_site/index.html")
187
+ _(response.status).must_equal 404
187
188
  end
188
189
  end
189
190
 
@@ -191,23 +192,24 @@ describe "when handling requests" do
191
192
  describe "when a directory is requested" do
192
193
 
193
194
  it "redirects to 'directory/' for 'directory' with index.html" do
194
- @request.get("/dir-with-index").status.must_equal 301
195
+ _(@request.get("/dir-with-index").status).must_equal 301
195
196
  end
196
197
 
197
198
  it "returns status 200 for 'directory/' with index.html" do
198
- @request.get("/dir-with-index/").status.must_equal 200
199
+ _(@request.get("/dir-with-index/").status).must_equal 200
199
200
  end
200
201
 
201
202
  it "returns correct body for 'directory/' with index.html" do
202
- @request.get("/dir-with-index/").body.must_match %r{<p>Index of dir-with-index/</p>}
203
+ response_body = @request.get("/dir-with-index/").body
204
+ _(response_body).must_match %r{<p>Index of dir-with-index/</p>}
203
205
  end
204
206
 
205
207
  it "returns status 404 for 'directory' without index.html" do
206
- @request.get("/dir-without-index").status.must_equal 404
208
+ _(@request.get("/dir-without-index").status).must_equal 404
207
209
  end
208
210
 
209
211
  it "returns status 404 for 'directory/' without index.html" do
210
- @request.get("/dir-without-index/").status.must_equal 404
212
+ _(@request.get("/dir-without-index/").status).must_equal 404
211
213
  end
212
214
  end
213
215
 
@@ -219,20 +221,20 @@ describe "when handling requests" do
219
221
  end
220
222
 
221
223
  it "returns status 301" do
222
- @response.status.must_equal 301
224
+ _(@response.status).must_equal 301
223
225
  end
224
226
 
225
227
  it "returns correct Location header" do
226
- @response.headers["Location"].must_equal "/dir-with-index/"
228
+ _(@response.headers["Location"]).must_equal "/dir-with-index/"
227
229
  end
228
230
 
229
231
  it "returns a Cache-Control header" do
230
- @response.headers["Cache-Control"].wont_be_nil
232
+ _(@response.headers["Cache-Control"]).wont_be_nil
231
233
  end
232
234
 
233
235
  it "returns correct body" do
234
236
  expected = %r{<!DOCTYPE html>.*<a href="/dir-with-index/">}m
235
- @request.get("/dir-with-index").body.must_match expected
237
+ _(@request.get("/dir-with-index").body).must_match expected
236
238
  end
237
239
  end
238
240
 
@@ -245,11 +247,11 @@ describe "when handling requests" do
245
247
 
246
248
  it "returns correct body" do
247
249
  response_body = @response.body.force_encoding("UTF-8")
248
- response_body.must_match %r{<p>¡Buenos días!</p>}
250
+ _(response_body).must_match %r{<p>¡Buenos días!</p>}
249
251
  end
250
252
 
251
253
  it "returns the bytesize as Content-Length header" do
252
- @response.original_headers["Content-Length"].must_equal "23"
254
+ _(@response.original_headers["Content-Length"]).must_equal "23"
253
255
  end
254
256
  end
255
257
 
@@ -262,11 +264,11 @@ describe "when handling requests" do
262
264
 
263
265
  it "returns correct body" do
264
266
  expected = "File\r\nwith\r\nCRLF\r\nnewlines\r\n"
265
- @response.body.must_equal expected
267
+ _(@response.body).must_equal expected
266
268
  end
267
269
 
268
270
  it "returns the bytesize as Content-Length header" do
269
- @response.original_headers["Content-Length"].must_equal "28"
271
+ _(@response.original_headers["Content-Length"]).must_equal "28"
270
272
  end
271
273
  end
272
274
 
@@ -274,18 +276,18 @@ describe "when handling requests" do
274
276
  describe "when URL contains special characters" do
275
277
 
276
278
  it "returns status 200 for URL with escapes" do
277
- @response = @request.get("%2F2015%2F11%2F05%2Fhello-world.html")
278
- @response.status.must_equal 200
279
+ response = @request.get("%2F2015%2F11%2F05%2Fhello-world.html")
280
+ _(response.status).must_equal 200
279
281
  end
280
282
 
281
283
  it "returns status 200 for resource name with blank" do
282
- @response = @request.get("with%20blank.html")
283
- @response.status.must_equal 200
284
+ response = @request.get("with%20blank.html")
285
+ _(response.status).must_equal 200
284
286
  end
285
287
 
286
288
  it "returns status 200 for resource name with plus" do
287
- @response = @request.get("with+plus.html")
288
- @response.status.must_equal 200
289
+ response = @request.get("with+plus.html")
290
+ _(response.status).must_equal 200
289
291
  end
290
292
  end
291
293
 
@@ -303,20 +305,20 @@ describe "when handling requests" do
303
305
  end
304
306
 
305
307
  it "returns correct status code for unchanged '/'" do
306
- @request.get("/", @correct_etag).status.must_equal 304
308
+ _(@request.get("/", @correct_etag).status).must_equal 304
307
309
  end
308
310
 
309
311
  it "does not return a Content-Length header for unchanged '/'" do
310
312
  response = @request.get("/", @correct_etag)
311
- response.original_headers["Content-Length"].must_be_nil
313
+ _(response.original_headers["Content-Length"]).must_be_nil
312
314
  end
313
315
 
314
316
  it "returns correct status code for changed '/'" do
315
- @request.get("/", @other_etag).status.must_equal 200
317
+ _(@request.get("/", @other_etag).status).must_equal 200
316
318
  end
317
319
 
318
320
  it "returns correct status code for 404" do
319
- @request.get("/not/a/page", @other_etag).status.must_equal 404
321
+ _(@request.get("/not/a/page", @other_etag).status).must_equal 404
320
322
  end
321
323
  end
322
324
 
@@ -324,15 +326,15 @@ describe "when handling requests" do
324
326
  describe "when handling HEAD requests" do
325
327
 
326
328
  it "returns status 200 for '/'" do
327
- @request.head("/").status.must_equal 200
329
+ _(@request.head("/").status).must_equal 200
328
330
  end
329
331
 
330
332
  it "returns correct Content-Length header for '/'" do
331
- @request.head("/").original_headers["Content-Length"].must_equal "17"
333
+ _(@request.head("/").original_headers["Content-Length"]).must_equal "17"
332
334
  end
333
335
 
334
336
  it "does not return a body" do
335
- @request.head("/").body.must_equal ""
337
+ _(@request.head("/").body).must_equal ""
336
338
  end
337
339
  end
338
340
 
@@ -340,36 +342,41 @@ describe "when handling requests" do
340
342
  describe "when handling OPTIONS requests" do
341
343
 
342
344
  it "returns status 200" do
343
- @request.options("/").status.must_equal 200
345
+ _(@request.options("/").status).must_equal 200
344
346
  end
345
347
 
346
348
  it "returns correct Allow header" do
347
- @request.options("/").original_headers["Allow"].must_equal "GET,HEAD,OPTIONS"
349
+ response_allow_header = @request.options("/").original_headers["Allow"]
350
+ _(response_allow_header).must_equal "GET,HEAD,OPTIONS"
348
351
  end
349
352
 
350
353
  it "does not return a body" do
351
- @request.options("/").body.must_equal ""
354
+ _(@request.options("/").body).must_equal ""
352
355
  end
353
356
 
354
357
  it "returns 404 for nonexistent resource" do
355
- @request.options("/not/a/page").status.must_equal 404
356
- @request.options("/not/a/page").body.must_match %r{<p>404: Not Found</p>}
358
+ _(@request.options("/not/a/page").status).must_equal 404
359
+ _(@request.options("/not/a/page").body).must_match %r{<p>404: Not Found</p>}
357
360
  end
358
361
  end
359
362
 
360
363
 
361
- describe "when handling POST, PUT, DELETE, and other requests" do
364
+ describe "when handling POST, PUT, DELETE, and other not allowed requests" do
362
365
 
363
366
  it "returns status 405" do
364
- @request.post("/").status.must_equal 405
365
- @request.put("/").status.must_equal 405
366
- @request.delete("/").status.must_equal 405
367
- @request.request("OTHER", "/").status.must_equal 405
367
+ _(@request.post("/").status).must_equal 405
368
+ _(@request.put("/").status).must_equal 405
369
+ _(@request.delete("/").status).must_equal 405
370
+ _(@request.request("OTHER", "/").status).must_equal 405
368
371
  end
369
372
 
370
373
  it "returns correct body" do
371
374
  expected = %r{<!DOCTYPE html>.*<p>405: Method Not Allowed</p>}m
372
- @request.post("/").body.must_match expected
375
+ _(@request.post("/").body).must_match expected
376
+ end
377
+
378
+ it "returns correct Content-Length header" do
379
+ _(@request.post("/").original_headers["Content-Length"]).must_equal "151"
373
380
  end
374
381
  end
375
382
  end
data/test/test_router.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "helper"
2
4
 
3
5
 
@@ -17,6 +19,10 @@ describe Lanyon::Router do
17
19
  dir-with-index/index.html
18
20
  dir-without-index/page.html
19
21
  dir1/dir2/dir3/index.html
22
+ foo
23
+ foo.html
24
+ bar.html
25
+ bar/index.html
20
26
  ]
21
27
 
22
28
  files.each do |path|
@@ -37,44 +43,78 @@ describe Lanyon::Router do
37
43
 
38
44
  it "returns path for '/'" do
39
45
  filename = File.join(@sitedir, "index.html")
40
- @router.endpoint("/").must_equal filename
46
+ _(@router.endpoint("/")).must_equal filename
41
47
  end
42
48
 
43
49
  it "returns existing path" do
44
50
  filename = File.join(@sitedir, "page.html")
45
- @router.endpoint("/page.html").must_equal filename
51
+ _(@router.endpoint("/page.html")).must_equal filename
46
52
  end
47
53
 
48
54
  it "returns existing path for resource without extension" do
49
55
  filename = File.join(@sitedir, "README")
50
- @router.endpoint("/README").must_equal filename
56
+ _(@router.endpoint("/README")).must_equal filename
51
57
  end
52
58
 
53
59
  it "returns :not_found for non-existent path" do
54
- @router.endpoint("/not-a-page.html").must_equal :not_found
60
+ _(@router.endpoint("/not-a-page.html")).must_equal :not_found
55
61
  end
56
62
 
57
63
  it "returns :not_found for partially matching paths" do
58
- @router.endpoint("/dir1/dir2/").must_equal :not_found
59
- @router.endpoint("/dir2/dir3").must_equal :not_found
60
- @router.endpoint("ir1/di").must_equal :not_found
64
+ _(@router.endpoint("/dir1/dir2/")).must_equal :not_found
65
+ _(@router.endpoint("/dir2/dir3")).must_equal :not_found
66
+ _(@router.endpoint("ir1/di")).must_equal :not_found
61
67
  end
62
68
 
63
69
  it "returns path for '/path/to/dir/' with index" do
64
70
  filename = File.join(@sitedir, "dir-with-index/index.html")
65
- @router.endpoint("/dir-with-index/").must_equal filename
71
+ _(@router.endpoint("/dir-with-index/")).must_equal filename
66
72
  end
67
73
 
68
74
  it "returns :must_redirect for '/path/to/dir' with index" do
69
- @router.endpoint("/dir-with-index").must_equal :must_redirect
75
+ _(@router.endpoint("/dir-with-index")).must_equal :must_redirect
70
76
  end
71
77
 
72
78
  it "returns :not_found for '/path/to/dir/' without index" do
73
- @router.endpoint("/dir-without-index/").must_equal :not_found
79
+ _(@router.endpoint("/dir-without-index/")).must_equal :not_found
74
80
  end
75
81
 
76
82
  it "returns :not_found for '/path/to/dir' without index" do
77
- @router.endpoint("/dir-without-index").must_equal :not_found
83
+ _(@router.endpoint("/dir-without-index")).must_equal :not_found
84
+ end
85
+ end
86
+
87
+
88
+ describe "when automatically adding .html extension" do
89
+
90
+ it "returns existing path" do
91
+ filename = File.join(@sitedir, "page.html")
92
+ _(@router.endpoint("/page")).must_equal filename
93
+ end
94
+
95
+ describe "when both `foo' and `foo.html' exist" do
96
+
97
+ it "returns `foo' and not `foo.html' when asked for `foo'" do
98
+ filename = File.join(@sitedir, "foo")
99
+ _(@router.endpoint("/foo")).must_equal filename
100
+ end
101
+
102
+ it "can also serve `foo.html'" do
103
+ filename = File.join(@sitedir, "foo.html")
104
+ _(@router.endpoint("/foo.html")).must_equal filename
105
+ end
106
+ end
107
+
108
+ describe "when both `bar.html' and `bar/index.html' exist" do
109
+
110
+ it "returns :must_redirect and not `bar.html' when asked for `bar'" do
111
+ _(@router.endpoint("/bar")).must_equal :must_redirect
112
+ end
113
+
114
+ it "can also serve `bar.html'" do
115
+ filename = File.join(@sitedir, "bar.html")
116
+ _(@router.endpoint("/bar.html")).must_equal filename
117
+ end
78
118
  end
79
119
  end
80
120
 
@@ -83,27 +123,27 @@ describe Lanyon::Router do
83
123
 
84
124
  it "discards leading '..' for existing path" do
85
125
  filename = File.join(@sitedir, "page.html")
86
- @router.endpoint("/../../page.html").must_equal filename
126
+ _(@router.endpoint("/../../page.html")).must_equal filename
87
127
  end
88
128
 
89
129
  it "allows safe directory traversal" do
90
130
  filename = File.join(@sitedir, "index.html")
91
- @router.endpoint("/dir1/../").must_equal filename
131
+ _(@router.endpoint("/dir1/../")).must_equal filename
92
132
  end
93
133
 
94
134
  it "returns :not_found for unsafe directory traversal 1" do
95
135
  filename = File.join(@sitedir, "/../_site/page.html")
96
136
  assert File.exist?(filename)
97
137
 
98
- @router.endpoint("/../_site/page.html").must_equal :not_found
138
+ _(@router.endpoint("/../_site/page.html")).must_equal :not_found
99
139
  end
100
140
 
101
141
  it "returns :not_found for unsafe directory traversal 2" do
102
- @router.endpoint("/%2E%2E/_site/").must_equal :not_found
142
+ _(@router.endpoint("/%2E%2E/_site/")).must_equal :not_found
103
143
  end
104
144
 
105
145
  it "returns :not_found for unsafe directory traversal 3" do
106
- @router.endpoint("/dir1/../dir1/../../_site/").must_equal :not_found
146
+ _(@router.endpoint("/dir1/../dir1/../../_site/")).must_equal :not_found
107
147
  end
108
148
  end
109
149
 
@@ -113,7 +153,7 @@ describe Lanyon::Router do
113
153
  describe "when 404.html does not exist" do
114
154
 
115
155
  it "returns nil" do
116
- @router.custom_404_body.must_be_nil
156
+ _(@router.custom_404_body).must_be_nil
117
157
  end
118
158
  end
119
159
 
@@ -129,7 +169,7 @@ describe Lanyon::Router do
129
169
  end
130
170
 
131
171
  it "returns correct body" do
132
- @router.custom_404_body.must_equal "Custom 404"
172
+ _(@router.custom_404_body).must_equal "Custom 404"
133
173
  end
134
174
  end
135
175
  end
@@ -139,14 +179,14 @@ describe Lanyon::Router do
139
179
 
140
180
  it "strips trailing slash from root" do
141
181
  router = Lanyon::Router.new(@sitedir + "/")
142
- router.root.must_equal @sitedir
182
+ _(router.root).must_equal @sitedir
143
183
  end
144
184
 
145
185
  it "does not append a trailing slash to root" do
146
186
  assert !@sitedir.end_with?("/")
147
187
 
148
188
  router = Lanyon::Router.new(@sitedir)
149
- router.root.must_equal @sitedir
189
+ _(router.root).must_equal @sitedir
150
190
  end
151
191
  end
152
192
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lanyon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcus Stollsteimer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-01 00:00:00.000000000 Z
11
+ date: 2022-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -17,9 +17,6 @@ dependencies:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '2.0'
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '4.0'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
@@ -27,9 +24,6 @@ dependencies:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '2.0'
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '4.0'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: rack
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -51,33 +45,33 @@ dependencies:
51
45
  - !ruby/object:Gem::Version
52
46
  version: '3.0'
53
47
  - !ruby/object:Gem::Dependency
54
- name: rake
48
+ name: minitest
55
49
  requirement: !ruby/object:Gem::Requirement
56
50
  requirements:
57
51
  - - "~>"
58
52
  - !ruby/object:Gem::Version
59
- version: '11.2'
53
+ version: '5.8'
60
54
  type: :development
61
55
  prerelease: false
62
56
  version_requirements: !ruby/object:Gem::Requirement
63
57
  requirements:
64
58
  - - "~>"
65
59
  - !ruby/object:Gem::Version
66
- version: '11.2'
60
+ version: '5.8'
67
61
  - !ruby/object:Gem::Dependency
68
- name: minitest
62
+ name: rake
69
63
  requirement: !ruby/object:Gem::Requirement
70
64
  requirements:
71
65
  - - "~>"
72
66
  - !ruby/object:Gem::Version
73
- version: '5.8'
67
+ version: '13.0'
74
68
  type: :development
75
69
  prerelease: false
76
70
  version_requirements: !ruby/object:Gem::Requirement
77
71
  requirements:
78
72
  - - "~>"
79
73
  - !ruby/object:Gem::Version
80
- version: '5.8'
74
+ version: '13.0'
81
75
  description: Lanyon is a good friend of Jekyll, the static site generator, and transforms
82
76
  your website into a Rack application.
83
77
  email: sto.mar@web.de
@@ -146,8 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
140
  - !ruby/object:Gem::Version
147
141
  version: '0'
148
142
  requirements: []
149
- rubyforge_project:
150
- rubygems_version: 2.5.1
143
+ rubygems_version: 3.3.3
151
144
  signing_key:
152
145
  specification_version: 4
153
146
  summary: Lanyon serves your Jekyll site as a Rack application.