lanyon 0.3.4 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
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.