middleman-caching-proxy 0.1.3 → 0.1.4
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 +4 -4
- data/lib/middleman/caching_proxy/cache.rb +41 -37
- data/lib/middleman/caching_proxy/cache_item.rb +5 -3
- data/lib/middleman/caching_proxy/cache_manifest.rb +58 -57
- data/lib/middleman/caching_proxy/cached_resource.rb +22 -20
- data/lib/middleman/caching_proxy/extension.rb +76 -74
- data/lib/middleman/caching_proxy/version.rb +2 -4
- data/middleman-caching-proxy.gemspec +1 -0
- data/spec/middleman/caching_proxy/cache_item_spec.rb +12 -0
- data/spec/middleman/caching_proxy/cache_manifest_spec.rb +108 -0
- data/spec/middleman/caching_proxy/cache_spec.rb +100 -0
- data/spec/middleman/caching_proxy/cached_resource_spec.rb +54 -0
- data/spec/middleman/caching_proxy/extension_spec.rb +7 -0
- data/spec/middleman/caching_proxy/version_spec.rb +8 -0
- data/spec/middleman/caching_proxy_spec.rb +12 -3
- data/spec/spec_helper.rb +3 -1
- data/spec/support/matchers/raise_error_matching.rb +52 -0
- data/spec/support/matchers/require_parameter.rb +52 -0
- data/spec/support/simplecov.rb +5 -0
- metadata +25 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55aa289cbda88555e44bd3e30d37cb59b71e241f
|
4
|
+
data.tar.gz: 7ab8901daea4d287e109070e2d9cb1f575483cfa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19da52ec7f45cda78fb0733ce0e50e892c3c84d0cad9a83c9987901ecb3be0a56555ad0ce299c982204338261ad4270da5861f8426bfb45ca471d03252ea39f4
|
7
|
+
data.tar.gz: f38a7becaba16807e730b599370279c13a018e613893f7f713b6b87e15cc56f5500b2b51e4314e6d31fab8d2b67ee8c9c6b4d5106234b063af83ff1f179679c7
|
@@ -3,42 +3,46 @@ require "fileutils"
|
|
3
3
|
|
4
4
|
require "middleman/caching_proxy/cache_manifest"
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
6
|
+
module Middleman::CachingProxy
|
7
|
+
class Cache
|
8
|
+
def initialize(path:, key:)
|
9
|
+
@manifest = nil
|
10
|
+
end
|
11
|
+
include Autostruct::Wrap
|
12
|
+
|
13
|
+
def has?(item)
|
14
|
+
cached_path = full_path(item: item)
|
15
|
+
return false if !File.exist?(cached_path)
|
16
|
+
manifest.has?(item)
|
17
|
+
end
|
18
|
+
|
19
|
+
def add(item:, source:)
|
20
|
+
manifest.add item
|
21
|
+
cached_path = full_path(item: item)
|
22
|
+
copy_in source, cached_path
|
23
|
+
end
|
24
|
+
|
25
|
+
def full_path(item:)
|
26
|
+
File.join(path, "items", item.path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def save
|
30
|
+
manifest.save
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def manifest
|
36
|
+
@manifest ||= CacheManifest.new(
|
37
|
+
path: path, key: key
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def copy_in(source, cached_path)
|
42
|
+
cache_subdirectory = File.dirname(cached_path)
|
43
|
+
FileUtils.mkdir_p cache_subdirectory
|
44
|
+
|
45
|
+
FileUtils.cp source, cached_path
|
46
|
+
end
|
43
47
|
end
|
44
48
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require "autostruct/wrap"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
module Middleman::CachingProxy
|
4
|
+
class CacheItem
|
5
|
+
def initialize(path:, template:, proxy_options:, fingerprint:); end
|
6
|
+
include Autostruct::Wrap
|
7
|
+
end
|
6
8
|
end
|
@@ -3,77 +3,78 @@ require "fileutils"
|
|
3
3
|
|
4
4
|
require "middleman/caching_proxy/version"
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
module Middleman::CachingProxy
|
7
|
+
class CacheManifest
|
8
|
+
FILENAME = ".manifest.json"
|
9
|
+
KEY = "key"
|
10
|
+
ITEMS = "items"
|
11
|
+
VERSION = "version"
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
def initialize(path:, key:)
|
14
|
+
@manifest = nil
|
15
|
+
@items = nil
|
16
|
+
end
|
17
|
+
include Autostruct::Wrap
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
def has?(item)
|
20
|
+
items[item.path] == item.fingerprint
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
def add(item)
|
24
|
+
items[item.path] = item.fingerprint
|
25
|
+
end
|
26
|
+
|
27
|
+
def save
|
28
|
+
ensure_cache_directory
|
25
29
|
|
26
|
-
|
27
|
-
ensure_cache_directory
|
28
|
-
File.open(manifest_path, "w") do |f|
|
29
|
-
f.write build(items: items).to_json
|
30
|
+
File.write manifest_path, build(items: items).to_json
|
30
31
|
end
|
31
|
-
end
|
32
32
|
|
33
|
-
|
33
|
+
private
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
def items
|
36
|
+
@items ||= manifest[ITEMS]
|
37
|
+
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
def manifest_path
|
40
|
+
::File.join(path, FILENAME)
|
41
|
+
end
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
43
|
+
def manifest
|
44
|
+
return @manifest if @manifest
|
45
|
+
@manifest = build
|
46
|
+
if File.exist?(manifest_path)
|
47
|
+
from_disk = JSON.load(File.read(manifest_path))
|
48
|
+
if is_ok?(from_disk)
|
49
|
+
@manifest = from_disk
|
50
|
+
end
|
50
51
|
end
|
52
|
+
@manifest
|
51
53
|
end
|
52
|
-
@manifest
|
53
|
-
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
55
|
+
def is_ok?(manifest)
|
56
|
+
return false if manifest.nil?
|
57
|
+
return false if manifest[VERSION] != version
|
58
|
+
# Clear cache if key changes
|
59
|
+
return false if manifest[KEY] != key
|
60
|
+
return false if !manifest[ITEMS].is_a?(Hash)
|
61
|
+
true
|
62
|
+
end
|
63
63
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
64
|
+
def build(items: {})
|
65
|
+
{
|
66
|
+
KEY => key,
|
67
|
+
ITEMS => items,
|
68
|
+
VERSION => version
|
69
|
+
}
|
70
|
+
end
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
def version
|
73
|
+
Middleman::CachingProxy::VERSION
|
74
|
+
end
|
75
75
|
|
76
|
-
|
77
|
-
|
76
|
+
def ensure_cache_directory
|
77
|
+
FileUtils.mkdir_p path
|
78
|
+
end
|
78
79
|
end
|
79
80
|
end
|
@@ -1,30 +1,32 @@
|
|
1
1
|
require "autostruct/wrap"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
module Middleman::CachingProxy
|
4
|
+
class CachedResource
|
5
|
+
def initialize(path:, cached_path:, build_path:); end
|
6
|
+
include Autostruct::Wrap
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
def destination_path
|
9
|
+
path[1..-1]
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
def ext
|
13
|
+
""
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
def ignored?
|
17
|
+
false # Seems to mean "actually include in build?"
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
def binary?
|
21
|
+
true # Seems to mean "do a binary copy or make a rack request?"
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
def source_file
|
25
|
+
cached_path
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
28
|
+
def content_type
|
29
|
+
"text/html"
|
30
|
+
end
|
29
31
|
end
|
30
32
|
end
|
@@ -5,98 +5,100 @@ require "middleman/caching_proxy/cache"
|
|
5
5
|
require "middleman/caching_proxy/cache_item"
|
6
6
|
require "middleman/caching_proxy/cached_resource"
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
8
|
+
module Middleman::CachingProxy
|
9
|
+
class Extension < ::Middleman::Extension
|
10
|
+
option :cache_directory,
|
11
|
+
"tmp/proxy_cache",
|
12
|
+
"The directory where cache files will be stored"
|
13
|
+
option :cache_key,
|
14
|
+
nil,
|
15
|
+
"A global cache key"
|
16
|
+
|
17
|
+
if Semantic::Version.new(Middleman::VERSION).major >= 4
|
18
|
+
expose_to_config :proxy_with_cache
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
21
|
+
module InstanceMethods
|
22
|
+
def proxy_with_cache(path:, template:, proxy_options:, fingerprint:)
|
23
|
+
item = CacheItem.new(
|
24
|
+
path: path,
|
25
|
+
template: template,
|
26
|
+
proxy_options: proxy_options,
|
27
|
+
fingerprint: fingerprint
|
28
|
+
)
|
29
|
+
will_use_cache = extensions[:caching_proxy].add(item)
|
30
|
+
if !will_use_cache
|
31
|
+
proxy item.path, item.template, item.proxy_options
|
32
|
+
end
|
31
33
|
end
|
32
34
|
end
|
33
|
-
end
|
34
35
|
|
35
|
-
|
36
|
-
|
36
|
+
attr_reader :copy_from_cache
|
37
|
+
attr_reader :add_to_cache
|
37
38
|
|
38
|
-
|
39
|
-
|
39
|
+
def initialize(app, options_hash = {}, &block)
|
40
|
+
super
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
42
|
+
if Semantic::Version.new(Middleman::VERSION).major <= 3
|
43
|
+
app.send :include, InstanceMethods
|
44
|
+
end
|
44
45
|
|
45
|
-
|
46
|
-
|
47
|
-
|
46
|
+
if !options.cache_key
|
47
|
+
raise "Please supply a cache_key value"
|
48
|
+
end
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
@copy_from_cache = []
|
51
|
+
@add_to_cache = []
|
52
|
+
@cache = nil
|
53
|
+
end
|
53
54
|
|
54
|
-
|
55
|
-
|
56
|
-
|
55
|
+
def manipulate_resource_list(resources)
|
56
|
+
resources + cached_resources
|
57
|
+
end
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
def after_build(_builder)
|
60
|
+
copy_new_files_to_cache
|
61
|
+
cache.save
|
62
|
+
end
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
64
|
+
def add(item)
|
65
|
+
if cache.has?(item)
|
66
|
+
copy_from_cache << item
|
67
|
+
true
|
68
|
+
else
|
69
|
+
add_to_cache << item
|
70
|
+
false
|
71
|
+
end
|
70
72
|
end
|
71
|
-
end
|
72
73
|
|
73
|
-
|
74
|
+
private
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
76
|
+
def cache
|
77
|
+
@cache ||= Cache.new(path: options.cache_directory, key: options.cache_key)
|
78
|
+
end
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
80
|
+
def copy_new_files_to_cache
|
81
|
+
add_to_cache.each do |item|
|
82
|
+
# Handle directory_indexes extension
|
83
|
+
resource = app.sitemap.find_resource_by_path(item.path)
|
84
|
+
build_path = relative_build_path(resource.destination_path)
|
85
|
+
cache.add item: item, source: build_path
|
86
|
+
end
|
85
87
|
end
|
86
|
-
end
|
87
88
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
89
|
+
def cached_resources
|
90
|
+
copy_from_cache.map do |item|
|
91
|
+
cached_path = cache.full_path(item: item)
|
92
|
+
# TODO: Handle directory_indexes extension
|
93
|
+
build_path = relative_build_path(item.path)
|
94
|
+
CachedResource.new(
|
95
|
+
path: item.path, cached_path: cached_path, build_path: build_path
|
96
|
+
)
|
97
|
+
end
|
96
98
|
end
|
97
|
-
end
|
98
99
|
|
99
|
-
|
100
|
-
|
100
|
+
def relative_build_path(path)
|
101
|
+
File.join("build", path)
|
102
|
+
end
|
101
103
|
end
|
102
104
|
end
|
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_runtime_dependency "autostruct"
|
25
25
|
|
26
26
|
spec.add_development_dependency "bundler", "~> 1.13"
|
27
|
+
spec.add_development_dependency 'simplecov'
|
27
28
|
spec.add_development_dependency "rake", "~> 10.0"
|
28
29
|
spec.add_development_dependency "rspec", "~> 3.0"
|
29
30
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "middleman/caching_proxy/cache_item"
|
3
|
+
|
4
|
+
RSpec.describe Middleman::CachingProxy::CacheItem do
|
5
|
+
describe ".new" do
|
6
|
+
%w(path template proxy_options fingerprint).each do |param|
|
7
|
+
it "requires a #{param} parameter" do
|
8
|
+
expect(described_class).to require_parameter(param)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "middleman/caching_proxy/cache_manifest"
|
3
|
+
require "middleman/caching_proxy/cache_item"
|
4
|
+
|
5
|
+
module Middleman::CachingProxy
|
6
|
+
RSpec.describe CacheManifest do
|
7
|
+
let(:path) { "path" }
|
8
|
+
let(:key) { "key" }
|
9
|
+
let(:manifest_path) { File.join(path, ".manifest.json") }
|
10
|
+
let(:manifest_exists) { true }
|
11
|
+
let(:item) { double(CacheItem, path: item_path, fingerprint: fingerprint) }
|
12
|
+
let(:item_path) { "item/path" }
|
13
|
+
let(:fingerprint) { "fingerprint" }
|
14
|
+
let(:initial_contents) { JSON.generate(initial_data) }
|
15
|
+
let(:initial_data) do
|
16
|
+
{
|
17
|
+
"version" => VERSION,
|
18
|
+
"key" => key,
|
19
|
+
"items" => initial_items
|
20
|
+
}
|
21
|
+
end
|
22
|
+
let(:initial_items) { {} }
|
23
|
+
|
24
|
+
subject { described_class.new(path: path, key: key) }
|
25
|
+
|
26
|
+
before do
|
27
|
+
allow(File).to receive(:exist?).and_call_original
|
28
|
+
allow(File).to receive(:exist?).with(manifest_path) { manifest_exists }
|
29
|
+
allow(File).to receive(:read).and_call_original
|
30
|
+
allow(File).to receive(:read).with(manifest_path) { initial_contents }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#has?" do
|
34
|
+
context "when the item was in the JSON file" do
|
35
|
+
let(:initial_items) { {item_path => fingerprint} }
|
36
|
+
|
37
|
+
it "is true" do
|
38
|
+
expect(subject.has?(item)).to be_truthy
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when the item was not in the JSON file" do
|
43
|
+
it "is false" do
|
44
|
+
expect(subject.has?(item)).to be_falsey
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when the JSON file did not get loaded" do
|
49
|
+
let(:manifest_exists) { false }
|
50
|
+
|
51
|
+
it "is false" do
|
52
|
+
expect(subject.has?(item)).to be_falsey
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when the item was added" do
|
57
|
+
it "is true" do
|
58
|
+
subject.add(item)
|
59
|
+
expect(subject.has?(item)).to be_truthy
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#save" do
|
65
|
+
let(:initial_items) { {"foo" => "bar"} }
|
66
|
+
|
67
|
+
before do
|
68
|
+
@parsed = nil
|
69
|
+
allow(File).to receive(:write).with(manifest_path, anything) do |_, j|
|
70
|
+
@parsed = JSON.load(j)
|
71
|
+
end
|
72
|
+
subject.save
|
73
|
+
end
|
74
|
+
|
75
|
+
it "saves to disk" do
|
76
|
+
expect(File).to have_received(:write)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "saves the version" do
|
80
|
+
expect(@parsed["version"]).to eq(VERSION)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "saves the key" do
|
84
|
+
expect(@parsed["key"]).to eq(key)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "re-saves initial items" do
|
88
|
+
expect(@parsed["items"]["foo"]).to eq("bar")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#add" do
|
93
|
+
before do
|
94
|
+
@parsed = nil
|
95
|
+
allow(File).to receive(:write).with(manifest_path, anything) do |_, j|
|
96
|
+
@parsed = JSON.load(j)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it "is saved in the disk format" do
|
101
|
+
subject.add(item)
|
102
|
+
subject.save
|
103
|
+
|
104
|
+
expect(@parsed["items"][item_path]).to eq(fingerprint)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "middleman/caching_proxy/cache"
|
3
|
+
require "middleman/caching_proxy/cache_item"
|
4
|
+
|
5
|
+
module Middleman::CachingProxy
|
6
|
+
RSpec.describe Cache do
|
7
|
+
let(:manifest) do
|
8
|
+
instance_double(CacheManifest, has?: in_manifest, add: nil, save: nil)
|
9
|
+
end
|
10
|
+
let(:cache_path) { "/cache/path" }
|
11
|
+
let(:key) { "key" }
|
12
|
+
let(:in_manifest) { true }
|
13
|
+
let(:item) { double(CacheItem, path: item_path) }
|
14
|
+
let(:item_path) { "item/path" }
|
15
|
+
let(:item_cache_path) { File.join(cache_path, "items", item_path) }
|
16
|
+
let(:item_cache_directory) { File.dirname(item_cache_path) }
|
17
|
+
let(:item_build_path) { File.join(build_path, item_path) }
|
18
|
+
let(:build_path) { "/build/path" }
|
19
|
+
|
20
|
+
subject { described_class.new(path: cache_path, key: key) }
|
21
|
+
|
22
|
+
before do
|
23
|
+
allow(CacheManifest).to receive(:new) { manifest }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe ".new" do
|
27
|
+
%w(path key).each do |param|
|
28
|
+
it "requires a #{param} parameter" do
|
29
|
+
expect(described_class).to require_parameter(param)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#has?" do
|
35
|
+
before do
|
36
|
+
allow(File).to receive(:exist?).and_call_original
|
37
|
+
allow(File).to receive(:exist?).with(item_cache_path) { exists }
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when the file exists on disk" do
|
41
|
+
let(:exists) { true }
|
42
|
+
|
43
|
+
context "when the item is in the manifest" do
|
44
|
+
let(:in_manifest) { true }
|
45
|
+
|
46
|
+
it "is true" do
|
47
|
+
expect(subject.has?(item)).to be_truthy
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when the item is not in the manifest" do
|
52
|
+
let(:in_manifest) { false }
|
53
|
+
|
54
|
+
it "is true" do
|
55
|
+
expect(subject.has?(item)).to be_falsey
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when the file does not exist on disk" do
|
61
|
+
let(:exists) { false }
|
62
|
+
|
63
|
+
it "is false" do
|
64
|
+
expect(subject.has?(item)).to be_falsey
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#add" do
|
70
|
+
before do
|
71
|
+
allow(FileUtils).to receive(:mkdir_p).with(item_cache_directory)
|
72
|
+
allow(FileUtils).to receive(:cp).with(item_build_path, item_cache_path)
|
73
|
+
|
74
|
+
subject.add(item: item, source: item_build_path)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "adds the item to the manifest" do
|
78
|
+
expect(manifest).to have_received(:add).with(item)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "ensures the cache directory exists" do
|
82
|
+
expect(FileUtils).to have_received(:mkdir_p).with(item_cache_directory)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "copies the file" do
|
86
|
+
expect(FileUtils). to have_received(:cp).with(
|
87
|
+
item_build_path, item_cache_path
|
88
|
+
)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#save" do
|
93
|
+
it "saves the manifest" do
|
94
|
+
subject.save
|
95
|
+
|
96
|
+
expect(manifest).to have_received(:save)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "middleman/caching_proxy/cached_resource"
|
3
|
+
|
4
|
+
RSpec.describe Middleman::CachingProxy::CachedResource do
|
5
|
+
describe ".new" do
|
6
|
+
%w(path cached_path build_path).each do |param|
|
7
|
+
it "requires a #{param} parameter" do
|
8
|
+
expect(described_class).to require_parameter(param)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:path) { "/foo/bar" }
|
14
|
+
let(:cached_path) { "/cached/path" }
|
15
|
+
let(:build_path) { "/build/path" }
|
16
|
+
|
17
|
+
subject do
|
18
|
+
described_class.new(
|
19
|
+
path: path, cached_path: cached_path, build_path: build_path
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#destination_path" do
|
24
|
+
it "is the path without the leading slash" do
|
25
|
+
expect(subject.destination_path).to eq("foo/bar")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#ignored?" do
|
30
|
+
it { is_expected.to_not be_ignored }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#binary?" do
|
34
|
+
it { is_expected.to be_binary }
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#ext" do
|
38
|
+
it "is the an enpty string" do
|
39
|
+
expect(subject.ext).to eq("")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#source_file" do
|
44
|
+
it "is the cached path" do
|
45
|
+
expect(subject.source_file).to eq(cached_path)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#content_type" do
|
50
|
+
it "is HTML" do
|
51
|
+
expect(subject.content_type).to eq("text/html")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -1,7 +1,16 @@
|
|
1
1
|
require "spec_helper"
|
2
|
+
require "middleman-core"
|
2
3
|
|
3
|
-
describe Middleman::CachingProxy do
|
4
|
-
|
5
|
-
|
4
|
+
RSpec.describe Middleman::CachingProxy do
|
5
|
+
before do
|
6
|
+
allow(Middleman::Extensions).to receive(:register)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "registers the extension" do
|
10
|
+
require "middleman/caching_proxy"
|
11
|
+
expect(Middleman::Extensions).
|
12
|
+
to have_received(:register).with(
|
13
|
+
:caching_proxy, Middleman::CachingProxy::Extension
|
14
|
+
)
|
6
15
|
end
|
7
16
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,52 @@
|
|
1
|
+
# This code is derived from shoulda-matchers version 2.7.0
|
2
|
+
|
3
|
+
RSpec::Matchers.define :raise_error_matching do |klass: StandardError, message:|
|
4
|
+
def supports_block_expectations?
|
5
|
+
true
|
6
|
+
end
|
7
|
+
|
8
|
+
match do |block|
|
9
|
+
@actual = nil
|
10
|
+
|
11
|
+
begin
|
12
|
+
block.call
|
13
|
+
rescue => ex
|
14
|
+
@actual = ex
|
15
|
+
end
|
16
|
+
|
17
|
+
@actual &&
|
18
|
+
@actual.is_a?(klass) &&
|
19
|
+
@actual.message.match(message)
|
20
|
+
end
|
21
|
+
|
22
|
+
def failure_message
|
23
|
+
msg = "Block should have failed with #{expected[:klass]}, with a message matching '#{expected[:message]}'"
|
24
|
+
|
25
|
+
if @actual
|
26
|
+
if !@actual.is_a?(expected[:klass])
|
27
|
+
msg << ", actually failed with #{@actual.class} '#{@actual.message}'"
|
28
|
+
else
|
29
|
+
msg << ", actually failed with the message '#{@actual.message}'"
|
30
|
+
end
|
31
|
+
else
|
32
|
+
msg << ", but did not fail."
|
33
|
+
end
|
34
|
+
|
35
|
+
msg
|
36
|
+
end
|
37
|
+
|
38
|
+
def failure_message_for_should
|
39
|
+
failure_message
|
40
|
+
end
|
41
|
+
|
42
|
+
def failure_message_when_negated
|
43
|
+
msg = "Block should not have failed with #{expected[:klass]}, with message including '#{expected[:message]}'"
|
44
|
+
msg << ", but did."
|
45
|
+
|
46
|
+
msg
|
47
|
+
end
|
48
|
+
|
49
|
+
def failure_message_for_should_not
|
50
|
+
failure_message_when_negated
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
RSpec::Matchers.define :require_parameter do |expected|
|
2
|
+
match do |klass|
|
3
|
+
@actual = nil
|
4
|
+
|
5
|
+
begin
|
6
|
+
klass.new
|
7
|
+
rescue => ex
|
8
|
+
@actual = ex
|
9
|
+
end
|
10
|
+
|
11
|
+
@actual &&
|
12
|
+
@actual.is_a?(ArgumentError) &&
|
13
|
+
@actual.message.match(matcher_for(expected))
|
14
|
+
end
|
15
|
+
|
16
|
+
def matcher_for(param)
|
17
|
+
Regexp.new("missing keywords: .*?\\b#{param}\\b")
|
18
|
+
end
|
19
|
+
|
20
|
+
def failure_message
|
21
|
+
msg = "The constructor should require #{expected}"
|
22
|
+
|
23
|
+
if @actual
|
24
|
+
if @actual.is_a?(ArgumentError) &&
|
25
|
+
@actual.message.start_with?("missing keywords: ")
|
26
|
+
m = /missing keywords: (.*)$/.match(@actual.message)
|
27
|
+
msg << ", actually requires #{m[1]}"
|
28
|
+
else
|
29
|
+
msg << ", actually failed with the message '#{@actual.message}'"
|
30
|
+
end
|
31
|
+
else
|
32
|
+
msg << ", but does not require any parameters."
|
33
|
+
end
|
34
|
+
|
35
|
+
msg
|
36
|
+
end
|
37
|
+
|
38
|
+
def failure_message_for_should
|
39
|
+
failure_message
|
40
|
+
end
|
41
|
+
|
42
|
+
def failure_message_when_negated
|
43
|
+
msg = "FFFFFFUUUUUUUUUUUUUUUUUUUUUUUUU Block should not have failed with #{expected[:klass]}, with message including '#{expected[:message]}'"
|
44
|
+
msg << ", but did."
|
45
|
+
|
46
|
+
msg
|
47
|
+
end
|
48
|
+
|
49
|
+
def failure_message_for_should_not
|
50
|
+
failure_message_when_negated
|
51
|
+
end
|
52
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: middleman-caching-proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Yates
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: middleman
|
@@ -72,6 +72,20 @@ dependencies:
|
|
72
72
|
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '1.13'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: simplecov
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
75
89
|
- !ruby/object:Gem::Dependency
|
76
90
|
name: rake
|
77
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -127,8 +141,17 @@ files:
|
|
127
141
|
- lib/middleman/caching_proxy/extension.rb
|
128
142
|
- lib/middleman/caching_proxy/version.rb
|
129
143
|
- middleman-caching-proxy.gemspec
|
144
|
+
- spec/middleman/caching_proxy/cache_item_spec.rb
|
145
|
+
- spec/middleman/caching_proxy/cache_manifest_spec.rb
|
146
|
+
- spec/middleman/caching_proxy/cache_spec.rb
|
147
|
+
- spec/middleman/caching_proxy/cached_resource_spec.rb
|
148
|
+
- spec/middleman/caching_proxy/extension_spec.rb
|
149
|
+
- spec/middleman/caching_proxy/version_spec.rb
|
130
150
|
- spec/middleman/caching_proxy_spec.rb
|
131
151
|
- spec/spec_helper.rb
|
152
|
+
- spec/support/matchers/raise_error_matching.rb
|
153
|
+
- spec/support/matchers/require_parameter.rb
|
154
|
+
- spec/support/simplecov.rb
|
132
155
|
homepage: https://github.com/joeyates/middleman-caching-proxy
|
133
156
|
licenses:
|
134
157
|
- MIT
|