jekyll_plugin_support 1.1.0 → 3.0.0
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/.rubocop.yml +17 -1
- data/CHANGELOG.md +17 -6
- data/README.md +430 -2
- data/jekyll_plugin_support.gemspec +2 -1
- data/lib/block/jekyll_plugin_support_block.rb +2 -4
- data/lib/block/jekyll_plugin_support_block_noarg.rb +0 -2
- data/lib/generator/jekyll_plugin_support_generator.rb +1 -7
- data/lib/helper/jekyll_plugin_helper.rb +5 -5
- data/lib/helper/jekyll_plugin_helper_class.rb +2 -2
- data/lib/hooks/a_page.rb +69 -0
- data/lib/hooks/all_collections_hooks.rb +61 -0
- data/lib/hooks/all_files.rb +48 -0
- data/lib/hooks/class_methods.rb +50 -0
- data/lib/jekyll_all_collections/all_collections_tag.rb +157 -0
- data/lib/jekyll_plugin_support/jekyll_plugin_support_class.rb +3 -5
- data/lib/jekyll_plugin_support/jekyll_plugin_support_spec_support.rb +1 -3
- data/lib/jekyll_plugin_support/version.rb +1 -1
- data/lib/jekyll_plugin_support.rb +17 -12
- data/lib/tag/jekyll_plugin_support_tag.rb +1 -4
- data/lib/tag/jekyll_plugin_support_tag_noarg.rb +0 -2
- data/lib/util/mslinn_binary_search.rb +152 -0
- data/lib/util/send_chain.rb +56 -0
- data/spec/all_collections_tag/all_collections_tag_sort_spec.rb +112 -0
- data/spec/bsearch_spec.rb +50 -0
- data/spec/custom_error_spec.rb +9 -9
- data/spec/date_sort_spec.rb +84 -0
- data/spec/jekyll_plugin_helper_options_spec.rb +7 -3
- data/spec/liquid_variable_parsing_spec.rb +6 -6
- data/spec/mslinn_binary_search_spec.rb +47 -0
- data/spec/send_chain_spec.rb +72 -0
- data/spec/send_spec.rb +28 -0
- data/spec/sorted_lru_files_spec.rb +82 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/status_persistence.txt +3 -9
- data/spec/testable_spec.rb +38 -0
- metadata +45 -5
@@ -0,0 +1,56 @@
|
|
1
|
+
# Supports one chain at a time
|
2
|
+
module SendChain
|
3
|
+
# See https://stackoverflow.com/a/79333706/553865
|
4
|
+
# This method can be called directly if no methods in the chain require arguments
|
5
|
+
# Does not use any external state
|
6
|
+
def send_chain(chain)
|
7
|
+
Array(chain).inject(self) { |o, a| o.send(*a) }
|
8
|
+
end
|
9
|
+
|
10
|
+
# Saves @chain structure containing :placeholders for arguments to be supplied later
|
11
|
+
# Call when a different chain with :placeholders is desired
|
12
|
+
def new_chain(chain)
|
13
|
+
abort "new_chain error: chain must be an array ('#{chain}' was an #{chain.class.name})" \
|
14
|
+
unless chain.instance_of?(Array)
|
15
|
+
@chain = chain
|
16
|
+
end
|
17
|
+
|
18
|
+
# Call after new_chain, to evaluate @chain with values
|
19
|
+
def substitute_and_send_chain_with(values)
|
20
|
+
send_chain substitute_chain_with values
|
21
|
+
end
|
22
|
+
|
23
|
+
alias evaluate_with substitute_and_send_chain_with
|
24
|
+
|
25
|
+
# Call this method after calling new_chain to perform error checking and replace :placeholders with values.
|
26
|
+
# @chain is not modified.
|
27
|
+
# @return [Array] Modified chain
|
28
|
+
def substitute_chain_with(values)
|
29
|
+
values = [values] unless values.instance_of?(Array)
|
30
|
+
|
31
|
+
placeholder_count = @chain.flatten.count { |x| x == :placeholder }
|
32
|
+
if values.length != placeholder_count
|
33
|
+
abort "with_values error: number of values (#{values.length}) does not match the number of placeholders (#{placeholder_count})"
|
34
|
+
end
|
35
|
+
|
36
|
+
eval_chain @chain, values
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Replaces :placeholders with values
|
42
|
+
# Does not use any external state
|
43
|
+
# @return modified chain
|
44
|
+
def eval_chain(chain, values)
|
45
|
+
chain.map do |c|
|
46
|
+
case c
|
47
|
+
when :placeholder
|
48
|
+
values.shift
|
49
|
+
when Array
|
50
|
+
eval_chain c, values
|
51
|
+
else
|
52
|
+
c
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative '../../lib/jekyll_all_collections'
|
3
|
+
|
4
|
+
class APageStub
|
5
|
+
attr_reader :date, :last_modified, :label
|
6
|
+
|
7
|
+
def initialize(date, last_modified, label = '')
|
8
|
+
@date = Date.parse date
|
9
|
+
@last_modified = Date.parse last_modified
|
10
|
+
@label = label
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
@label
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def show(lambda_string, result, expected)
|
19
|
+
p "For lambda_string: #{lambda_string}"
|
20
|
+
p " result: #{result.map(&:label).join(', ')} <==> expected: #{expected.map(&:label).join(', ')}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# See https://stackoverflow.com/a/75388137/553865
|
24
|
+
RSpec.describe(AllCollectionsTag::AllCollectionsTag) do
|
25
|
+
let(:o1) { APageStub.new('2020-01-01', '2020-01-01', 'a_A') }
|
26
|
+
let(:o2) { APageStub.new('2021-01-01', '2020-01-01', 'b_A') }
|
27
|
+
let(:o3) { APageStub.new('2021-01-01', '2023-01-01', 'b_B') }
|
28
|
+
let(:o4) { APageStub.new('2022-01-01', '2023-01-01', 'c_B') }
|
29
|
+
let(:objs) { [o1, o2, o3, o4] }
|
30
|
+
|
31
|
+
it 'defines sort_by lambda with last_modified' do
|
32
|
+
sort_lambda = ->(a, b) { [a.last_modified] <=> [b.last_modified] }
|
33
|
+
result = objs.sort(&sort_lambda)
|
34
|
+
expect(result).to eq([o1, o2, o3, o4])
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'makes sort_by lambdas from stringified date' do
|
38
|
+
sort_lambda = eval '->(a, b) { a.last_modified <=> b.last_modified }',
|
39
|
+
NullBinding.new.min_binding, __FILE__, __LINE__ - 1
|
40
|
+
result = objs.sort(&sort_lambda)
|
41
|
+
expect(result).to eq([o1, o2, o3, o4])
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'makes sort_by lambdas from stringified array of last_modified' do
|
45
|
+
sort_lambda = eval '->(a, b) { [a.last_modified] <=> [b.last_modified] }',
|
46
|
+
NullBinding.new.min_binding, __FILE__, __LINE__ - 1
|
47
|
+
result = objs.sort(&sort_lambda)
|
48
|
+
expect(result).to eq([o1, o2, o3, o4])
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'makes sort_by lambdas with descending keys from stringified array of last_modified' do
|
52
|
+
sort_lambda = eval '->(a, b) { [b.last_modified] <=> [a.last_modified] }',
|
53
|
+
NullBinding.new.min_binding, __FILE__, __LINE__ - 1
|
54
|
+
result = objs.sort(&sort_lambda)
|
55
|
+
expected = [o3, o4, o1, o2]
|
56
|
+
expect(result).to eq(expected)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'create_lambda with 1 date key, descending' do
|
60
|
+
lambda_string = described_class.create_lambda_string('-last_modified')
|
61
|
+
sort_lambda = described_class.evaluate(lambda_string)
|
62
|
+
result = objs.sort(&sort_lambda)
|
63
|
+
expected = [o3, o4, o1, o2]
|
64
|
+
# show(lambda_string, result, expected)
|
65
|
+
expect(result).to eq(expected)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'create_lambda with 1 date key, ascending' do
|
69
|
+
lambda_string = described_class.create_lambda_string('date')
|
70
|
+
sort_lambda = described_class.evaluate(lambda_string)
|
71
|
+
result = objs.sort(&sort_lambda)
|
72
|
+
expected = [o1, o2, o3, o4]
|
73
|
+
# show(lambda_string, result, expected)
|
74
|
+
expect(result).to eq(expected)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'create_lambda with 2 date keys, both ascending' do
|
78
|
+
lambda_string = described_class.create_lambda_string(%w[date last_modified])
|
79
|
+
sort_lambda = described_class.evaluate(lambda_string)
|
80
|
+
result = objs.sort(&sort_lambda)
|
81
|
+
expected = [o1, o2, o3, o4]
|
82
|
+
# show(lambda_string, result, expected)
|
83
|
+
expect(result).to eq(expected)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'create_lambda with 2 date keys, both descending' do
|
87
|
+
lambda_string = described_class.create_lambda_string(['-date', '-last_modified'])
|
88
|
+
sort_lambda = described_class.evaluate(lambda_string)
|
89
|
+
result = objs.sort(&sort_lambda)
|
90
|
+
expected = [o4, o3, o2, o1]
|
91
|
+
# show(lambda_string, result, expected)
|
92
|
+
expect(result).to eq(expected)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'create_lambda with 2 date keys, first descending and second ascending' do
|
96
|
+
lambda_string = described_class.create_lambda_string(['-date', 'last_modified'])
|
97
|
+
sort_lambda = described_class.evaluate(lambda_string)
|
98
|
+
result = objs.sort(&sort_lambda)
|
99
|
+
expected = [o4, o2, o3, o1]
|
100
|
+
# show(lambda_string, result, expected)
|
101
|
+
expect(result).to eq(expected)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'create_lambda with 2 date keys, first ascending and second descending' do
|
105
|
+
lambda_string = described_class.create_lambda_string(['date', '-last_modified'])
|
106
|
+
sort_lambda = described_class.evaluate(lambda_string)
|
107
|
+
result = objs.sort(&sort_lambda)
|
108
|
+
expected = [o1, o3, o2, o4]
|
109
|
+
# show(lambda_string, result, expected)
|
110
|
+
expect(result).to eq(expected)
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Ruby's binary search is unsuitable because ordering requirements are not stable.
|
4
|
+
# the value to be searched for changes the required ordering
|
5
|
+
|
6
|
+
RSpec.describe(Array) do
|
7
|
+
before { skip('Never gonna give you up/Never gonna let you down') }
|
8
|
+
|
9
|
+
sorted_ints = [0, 4, 7, 10, 12]
|
10
|
+
sorted_strings = %w[aaa aab aac bbb bbc bbd ccc ccd cce].sort.reverse
|
11
|
+
|
12
|
+
it 'returns index of first int match' do
|
13
|
+
actual = sorted_ints.bsearch_index { |x| x >= 4 }
|
14
|
+
expect(actual).to eq(1)
|
15
|
+
|
16
|
+
actual = sorted_ints.bsearch_index { |x| x >= 6 }
|
17
|
+
expect(actual).to eq(2)
|
18
|
+
|
19
|
+
actual = sorted_ints.bsearch_index { |x| x >= -1 }
|
20
|
+
expect(actual).to eq(0)
|
21
|
+
|
22
|
+
actual = sorted_ints.bsearch_index { |x| x >= 100 }
|
23
|
+
expect(actual).to be_nil
|
24
|
+
end
|
25
|
+
|
26
|
+
# See https://stackoverflow.com/q/79333097/553865
|
27
|
+
it 'returns index of first string match' do
|
28
|
+
puts(sorted_strings.map { |x| x.start_with? 'a' })
|
29
|
+
index = sorted_strings.bsearch_index { |x| x.start_with? 'a' }
|
30
|
+
expect(sorted_strings[index]).to eq('aac')
|
31
|
+
|
32
|
+
index = sorted_strings.bsearch_index { |x| x.start_with? 'aa' }
|
33
|
+
expect(sorted_strings[index]).to eq('aac')
|
34
|
+
|
35
|
+
index = sorted_strings.bsearch_index { |x| x.start_with? 'aaa' }
|
36
|
+
expect(sorted_strings[index]).to eq('aaa')
|
37
|
+
|
38
|
+
index = sorted_strings.bsearch_index { |x| x.start_with? 'b' }
|
39
|
+
expect(sorted_strings[index]).to eq('bbd')
|
40
|
+
|
41
|
+
index = sorted_strings.bsearch_index { |x| x.start_with? 'bb' }
|
42
|
+
expect(sorted_strings[index]).to eq('bbd')
|
43
|
+
|
44
|
+
index = sorted_strings.bsearch_index { |x| x.start_with? 'bbc' }
|
45
|
+
expect(sorted_strings[index]).to eq('bbc')
|
46
|
+
|
47
|
+
index = sorted_strings.bsearch_index { |x| x.start_with? 'cc' }
|
48
|
+
expect(sorted_strings[index]).to eq('cce')
|
49
|
+
end
|
50
|
+
end
|
data/spec/custom_error_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require_relative '../lib/jekyll_custom_error'
|
2
|
-
require_relative '../lib/jekyll_plugin_support_class'
|
1
|
+
require_relative '../lib/error/jekyll_custom_error'
|
2
|
+
require_relative '../lib/jekyll_plugin_support/jekyll_plugin_support_class'
|
3
3
|
|
4
4
|
class Dummy
|
5
5
|
def just_for_testing; end
|
@@ -8,7 +8,7 @@ end
|
|
8
8
|
class CustomErrorSpec
|
9
9
|
tag_name = 'test_tag'
|
10
10
|
argument_string = 'This is the argument string'
|
11
|
-
AnError = JekyllSupport.define_error
|
11
|
+
AnError = ::JekyllSupport.define_error
|
12
12
|
AnError.class_variable_set(:@@tag_name, tag_name)
|
13
13
|
AnError.class_variable_set(:@@argument_string, argument_string)
|
14
14
|
|
@@ -17,21 +17,21 @@ class CustomErrorSpec
|
|
17
17
|
raise AnError, 'Oops'
|
18
18
|
rescue AnError => e
|
19
19
|
puts "Caught AnError: #{e.message}"
|
20
|
-
rescue JekyllSupport::CustomError => e
|
20
|
+
rescue ::JekyllSupport::CustomError => e
|
21
21
|
puts "Caught CustomError: #{e.message}"
|
22
22
|
end
|
23
23
|
|
24
|
-
RSpec.describe JekyllPluginHelper do
|
24
|
+
RSpec.describe JekyllSupport::JekyllPluginHelper do
|
25
25
|
it 'generates messages' do
|
26
26
|
msg = described_class.generate_message(Dummy, tag_name, '0.1.0')
|
27
27
|
puts msg
|
28
|
-
expect(msg).to include(
|
29
|
-
expect(msg).to include(
|
30
|
-
expect(msg).to include(
|
28
|
+
expect(msg).to include('Error class: DummyError')
|
29
|
+
expect(msg).to include('CSS class for error messages: dummy_error')
|
30
|
+
expect(msg).to include('die_on_dummy_error: false')
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
RSpec.describe JekyllSupport::CustomError do
|
34
|
+
RSpec.describe ::JekyllSupport::CustomError do
|
35
35
|
it 'can create custom errors' do
|
36
36
|
expect { raise AnError, 'Oops' }.to raise_error(AnError)
|
37
37
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative '../lib/jekyll_plugin_support'
|
3
|
+
|
4
|
+
# Verifies how data comparisons work
|
5
|
+
|
6
|
+
class Obj
|
7
|
+
# `last_modified` is primary sort key
|
8
|
+
# `date` (when specified) is secondary sort key
|
9
|
+
attr_reader :date, :last_modified
|
10
|
+
|
11
|
+
def initialize(param1, param2)
|
12
|
+
@last_modified = Date.parse(param1)
|
13
|
+
@date = Date.parse(param2)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec.describe(Obj) do
|
18
|
+
let(:o1) { described_class.new('2000-01-01', '2001-01-01') }
|
19
|
+
let(:o2) { described_class.new('2010-01-01', '2001-01-01') }
|
20
|
+
let(:o3) { described_class.new('2010-01-01', '2011-01-01') }
|
21
|
+
let(:o4) { described_class.new('2020-01-01', '2011-01-01') }
|
22
|
+
let(:objs) { [o1, o2, o3, o4] }
|
23
|
+
|
24
|
+
# See https://ruby-doc.org/3.2.0/Comparable.html
|
25
|
+
it 'compares one key with ascending dates' do
|
26
|
+
expect([o1.last_modified] <=> [o2.last_modified]).to eq(-1)
|
27
|
+
expect([o2.last_modified] <=> [o3.last_modified]).to eq(0)
|
28
|
+
expect([o3.last_modified] <=> [o4.last_modified]).to eq(-1)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'compares two keys with ascending dates' do
|
32
|
+
expect([o1.last_modified, o1.date] <=> [o2.last_modified, o2.date]).to eq(-1)
|
33
|
+
expect([o2.last_modified, o2.date] <=> [o3.last_modified, o3.date]).to eq(-1)
|
34
|
+
expect([o3.last_modified, o3.date] <=> [o4.last_modified, o4.date]).to eq(-1)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'compares one key with descending dates' do
|
38
|
+
expect([o1.last_modified] <=> [o2.last_modified]).to eq(-1)
|
39
|
+
expect([o2.last_modified] <=> [o3.last_modified]).to eq(0)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'compares two keys with descending dates' do
|
43
|
+
expect([o2.last_modified, o2.date] <=> [o1.last_modified, o1.date]).to eq(1)
|
44
|
+
expect([o3.last_modified, o3.date] <=> [o2.last_modified, o2.date]).to eq(1)
|
45
|
+
expect([o4.last_modified, o4.date] <=> [o3.last_modified, o3.date]).to eq(1)
|
46
|
+
end
|
47
|
+
|
48
|
+
# See https://ruby-doc.org/3.2.0/Enumerable.html#method-i-sort
|
49
|
+
it 'sort with one key ascending' do
|
50
|
+
sort_lambda = ->(a, b) { [a.last_modified] <=> [b.last_modified] }
|
51
|
+
result = objs.sort(&sort_lambda)
|
52
|
+
expect(result).to eq([o1, o2, o3, o4])
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'sort with one key descending' do
|
56
|
+
sort_lambda = ->(a, b) { [b.last_modified] <=> [a.last_modified] }
|
57
|
+
result = objs.sort(&sort_lambda)
|
58
|
+
expect(result).to eq([o4, o2, o3, o1])
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'sort with two keys ascending' do
|
62
|
+
sort_lambda = ->(a, b) { [a.last_modified, a.date] <=> [b.last_modified, b.date] }
|
63
|
+
result = objs.sort(&sort_lambda)
|
64
|
+
expect(result).to eq([o1, o2, o3, o4])
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'sort with both keys descending' do
|
68
|
+
sort_lambda = ->(a, b) { [b.last_modified, b.date] <=> [a.last_modified, a.date] }
|
69
|
+
result = objs.sort(&sort_lambda)
|
70
|
+
expect(result).to eq([o4, o3, o2, o1])
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'sort with last_modified descending and date ascending' do
|
74
|
+
sort_lambda = ->(a, b) { [b.last_modified, a.date] <=> [a.last_modified, b.date] }
|
75
|
+
result = objs.sort(&sort_lambda)
|
76
|
+
expect(result).to eq([o4, o2, o3, o1])
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'sort with last_modified ascending and date descending' do
|
80
|
+
sort_lambda = ->(a, b) { [a.last_modified, b.date] <=> [b.last_modified, a.date] }
|
81
|
+
result = objs.sort(&sort_lambda)
|
82
|
+
expect(result).to eq([o1, o3, o2, o4])
|
83
|
+
end
|
84
|
+
end
|
@@ -1,14 +1,15 @@
|
|
1
1
|
require 'jekyll_plugin_logger'
|
2
|
-
require 'rspec/match_ignoring_whitespace'
|
2
|
+
# require 'rspec/match_ignoring_whitespace'
|
3
3
|
require_relative '../lib/jekyll_plugin_support'
|
4
|
-
require_relative '../lib/jekyll_plugin_support_spec_support'
|
4
|
+
require_relative '../lib/jekyll_plugin_support/jekyll_plugin_support_spec_support'
|
5
5
|
|
6
6
|
class JekyllPluginHelperOptionsTest
|
7
|
-
RSpec.describe JekyllPluginHelper do
|
7
|
+
RSpec.describe ::JekyllSupport::JekyllPluginHelper do
|
8
8
|
logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
|
9
9
|
|
10
10
|
it 'parses quoted string options' do
|
11
11
|
helper = described_class.new('my_tag', "colors='blue or green' blah ick", logger, false)
|
12
|
+
helper.reinitialize helper.markup
|
12
13
|
expect(helper.keys_values.keys).to eq(%w[colors blah ick])
|
13
14
|
|
14
15
|
colors = helper.parameter_specified? 'colors'
|
@@ -19,6 +20,7 @@ class JekyllPluginHelperOptionsTest
|
|
19
20
|
|
20
21
|
it 'parses unquoted string options' do
|
21
22
|
helper = described_class.new('my_tag', 'color=blue blah ick', logger, false)
|
23
|
+
helper.reinitialize helper.markup
|
22
24
|
expect(helper.keys_values.keys).to eq(%w[color blah ick])
|
23
25
|
|
24
26
|
color = helper.parameter_specified? 'color'
|
@@ -29,6 +31,7 @@ class JekyllPluginHelperOptionsTest
|
|
29
31
|
|
30
32
|
it 'parses quoted booleans' do
|
31
33
|
helper = described_class.new('my_tag', "bool1='true' bool2='false' blah ick", logger, false)
|
34
|
+
helper.reinitialize helper.markup
|
32
35
|
expect(helper.keys_values.keys).to eq(%w[bool1 bool2 blah ick])
|
33
36
|
|
34
37
|
bool1 = helper.parameter_specified? 'bool1'
|
@@ -44,6 +47,7 @@ class JekyllPluginHelperOptionsTest
|
|
44
47
|
|
45
48
|
it 'parses unquoted booleans' do
|
46
49
|
helper = described_class.new('my_tag', 'bool1=true bool2=false blah ick', logger, false)
|
50
|
+
helper.reinitialize helper.markup
|
47
51
|
expect(helper.keys_values.keys).to eq(%w[bool1 bool2 blah ick])
|
48
52
|
|
49
53
|
bool1 = helper.parameter_specified? 'bool1'
|
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'jekyll_plugin_logger'
|
2
|
-
require 'rspec/match_ignoring_whitespace'
|
2
|
+
# require 'rspec/match_ignoring_whitespace'
|
3
3
|
require_relative '../lib/jekyll_plugin_support'
|
4
|
-
require_relative '../lib/jekyll_plugin_support_spec_support'
|
4
|
+
require_relative '../lib/jekyll_plugin_support/jekyll_plugin_support_spec_support'
|
5
5
|
|
6
6
|
class LiquidVariableParsing
|
7
7
|
# @return copy of str with references to defined variables replaced by the values of the variables
|
8
|
-
def variable_replace(str, scopes)
|
8
|
+
def self.variable_replace(str, scopes)
|
9
9
|
result = str.clone
|
10
10
|
match_data_list = str.to_enum(:scan, /{{[a-z_][a-zA-Z_0-9]*}}/).map { Regexp.last_match }.reverse
|
11
11
|
match_data_list&.each do |md|
|
@@ -22,13 +22,13 @@ class LiquidVariableParsing
|
|
22
22
|
result
|
23
23
|
end
|
24
24
|
|
25
|
-
RSpec.describe JekyllPluginHelper do
|
25
|
+
RSpec.describe ::JekyllSupport::JekyllPluginHelper do
|
26
26
|
it 'substitutes variable references for values without recursion' do
|
27
27
|
scopes = [{ 'a' => '{{', 'b' => 'asdf', 'c' => '}}' }]
|
28
28
|
str = '{{a}}{{b}}{{c}} This should be unchanged: {{d}}'
|
29
|
-
new_str = variable_replace(str, scopes)
|
29
|
+
new_str = LiquidVariableParsing.variable_replace(str, scopes)
|
30
30
|
expect(str).to start_with('{{a}}')
|
31
|
-
expect(new_str).to
|
31
|
+
expect(new_str).to eq('{{asdf}} This should be unchanged: {{d}}')
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative '../lib/hooks/all_files'
|
3
|
+
|
4
|
+
def build_msbs(sorted_strings)
|
5
|
+
sorted_strings.each do |string|
|
6
|
+
$msbs.insert LruFile.new(string.reverse, "Page #{string}") # { |x| x.url.start_with? string }
|
7
|
+
end
|
8
|
+
$msbs.enable_search
|
9
|
+
end
|
10
|
+
|
11
|
+
RSpec.describe(MSlinnBinarySearch) do
|
12
|
+
$msbs = described_class.new [:url, %i[start_with? placeholder]]
|
13
|
+
build_msbs %w[aaa.html baa.html caa.html bbb.html cbb.html dbb.html ccc.html ccd.html cce.html]
|
14
|
+
|
15
|
+
it 'handles an empty search string by returning the index of the first item (0)' do
|
16
|
+
index = $msbs.find_index '' # { |x| x.url.start_with? '' }
|
17
|
+
expect(index).to be_zero
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns the index of the first partial match' do
|
21
|
+
index = $msbs.find_index 'a.html' # { |x| x.url.start_with? 'a.html' }
|
22
|
+
expect(index).to eq(0)
|
23
|
+
|
24
|
+
index = $msbs.find_index 'baa.html' # { |x| x.url.start_with? 'baa.html' }
|
25
|
+
expect(index).to eq(1)
|
26
|
+
|
27
|
+
index = $msbs.find_index 'c.html' # { |x| x.url.start_with? 'c.html' }
|
28
|
+
expect(index).to eq(6)
|
29
|
+
|
30
|
+
index = $msbs.find_index 'cce.html' # { |x| x.url.start_with? 'cce.html' }
|
31
|
+
expect(index).to eq(8)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns the item of the first match' do
|
35
|
+
item = $msbs.find 'a.html' # { |x| x.url.start_with? 'a.html' }
|
36
|
+
expect(item.url.reverse).to eq('aaa.html')
|
37
|
+
|
38
|
+
item = $msbs.find 'baa.html' # { |x| x.url.start_with? 'baa.html' }
|
39
|
+
expect(item.url.reverse).to eq('baa.html')
|
40
|
+
|
41
|
+
item = $msbs.find 'c.html' # { |x| x.url.start_with? 'c.html' }
|
42
|
+
expect(item.url.reverse).to eq('ccc.html')
|
43
|
+
|
44
|
+
item = $msbs.find 'cce.html' # { |x| x.url.start_with? 'cce.html' }
|
45
|
+
expect(item.url.reverse).to eq('cce.html')
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative '../lib/util/send_chain'
|
3
|
+
|
4
|
+
unless defined? LruFile
|
5
|
+
LruFile = Struct.new(:url, :page) do
|
6
|
+
include SendChain
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
RSpec.describe(LruFile) do
|
11
|
+
lru_file = described_class.new 'abc', 'def'
|
12
|
+
|
13
|
+
it 'can perform a simple call if no arguments are required' do
|
14
|
+
# Equivalent to: lru_file.url.reverse
|
15
|
+
actual = lru_file.send_chain %i[url reverse]
|
16
|
+
expect(actual).to eq('cba')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'can accept a scalar argument in stages' do
|
20
|
+
lru_file.new_chain [:url, %i[end_with? placeholder]]
|
21
|
+
# Equivalent to: lru_file.url.end_with?('bc')
|
22
|
+
substituted_chain = lru_file.substitute_chain_with 'bc'
|
23
|
+
actual = lru_file.send_chain substituted_chain
|
24
|
+
expect(actual).to be true
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'can accept a vector argument in stages' do
|
28
|
+
lru_file.new_chain [:url, %i[end_with? placeholder]]
|
29
|
+
# Next 2 lines are equivalent to: lru_file.url.end_with?('bc')
|
30
|
+
substituted_chain = lru_file.substitute_chain_with ['bc']
|
31
|
+
actual = lru_file.send_chain substituted_chain
|
32
|
+
expect(actual).to be true
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'can accept a scalar argument in one stage' do
|
36
|
+
lru_file.new_chain [:url, %i[end_with? placeholder]]
|
37
|
+
# Equivalent to: lru_file.url.end_with?('bc')
|
38
|
+
actual = lru_file.substitute_and_send_chain_with 'bc'
|
39
|
+
expect(actual).to be true
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'can accept an array argument in one stage' do
|
43
|
+
lru_file.new_chain [:url, %i[end_with? placeholder]]
|
44
|
+
# Equivalent to: lru_file.url.end_with?('bc')
|
45
|
+
actual = lru_file.substitute_and_send_chain_with ['bc']
|
46
|
+
expect(actual).to be true
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'can use the evaluate_with alias' do
|
50
|
+
lru_file.new_chain [:url, %i[end_with? placeholder]]
|
51
|
+
# Equivalent to: lru_file.url.end_with?('bc')
|
52
|
+
actual = lru_file.evaluate_with ['bc']
|
53
|
+
expect(actual).to be true
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'can reuse the chain with different values' do
|
57
|
+
lru_file.new_chain [:url, %i[end_with? placeholder]]
|
58
|
+
|
59
|
+
# Equivalent to: lru_file.url.end_with?('bc')
|
60
|
+
actual = lru_file.substitute_and_send_chain_with 'bc'
|
61
|
+
expect(actual).to be true
|
62
|
+
|
63
|
+
# Equivalent to: lru_file.url.end_with?('abc')
|
64
|
+
substituted_chain = lru_file.substitute_chain_with ['abc']
|
65
|
+
actual = lru_file.send_chain substituted_chain
|
66
|
+
expect(actual).to be true
|
67
|
+
|
68
|
+
# Equivalent to: lru_file.url.end_with?('de')
|
69
|
+
actual = lru_file.substitute_and_send_chain_with 'de'
|
70
|
+
expect(actual).to be false
|
71
|
+
end
|
72
|
+
end
|
data/spec/send_spec.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Exploring how to set date attributes in an object
|
4
|
+
|
5
|
+
class Obj
|
6
|
+
# `last_modified` is primary sort key
|
7
|
+
# `date` (when specified) is secondary sort key
|
8
|
+
attr_reader :date, :last_modified
|
9
|
+
|
10
|
+
def initialize(param1, param2)
|
11
|
+
@last_modified = Date.parse(param1)
|
12
|
+
@date = Date.parse(param2)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
RSpec.describe(Obj) do
|
17
|
+
let(:obj) { described_class.new('2000-01-01', '2001-01-01') }
|
18
|
+
|
19
|
+
it 'can send date' do
|
20
|
+
date = obj.send :date
|
21
|
+
expect(obj.date).to eq(date)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'can send last_modified' do
|
25
|
+
last_modified = obj.send :last_modified
|
26
|
+
expect(obj.last_modified).to eq(last_modified)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative '../lib/hooks/all_files'
|
3
|
+
|
4
|
+
RSpec.describe(SortedLruFiles) do
|
5
|
+
expected1 = 'first-page.html'
|
6
|
+
expected2 = 'second-page.html'
|
7
|
+
expected3 = 'third-page.html'
|
8
|
+
|
9
|
+
it 'can read back an inserted item' do
|
10
|
+
sorted_files = described_class.new
|
11
|
+
sorted_files.insert(expected1, "https://mslinn.com/#{expected1}") # insert reverses expected1
|
12
|
+
sorted_files.enable_search
|
13
|
+
|
14
|
+
actual = sorted_files.select expected1
|
15
|
+
expect(actual.length).to eq(1)
|
16
|
+
expect(actual.first&.reverse&.start_with?(expected1.reverse)).to be true
|
17
|
+
|
18
|
+
actual = sorted_files.select expected1[5..]
|
19
|
+
expect(actual.length).to eq(1)
|
20
|
+
expect(actual.first&.reverse&.start_with?(expected1[5..].reverse)).to be true
|
21
|
+
|
22
|
+
actual = sorted_files.select 'should_not_match'
|
23
|
+
expect(actual).to be_empty
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'works with 2 items and one match' do
|
27
|
+
sorted_files = described_class.new
|
28
|
+
sorted_files.insert(expected1, "https://mslinn.com/#{expected1}") # insert reverses expected1
|
29
|
+
sorted_files.insert(expected2, "https://mslinn.com/#{expected2}")
|
30
|
+
sorted_files.enable_search
|
31
|
+
|
32
|
+
expect(sorted_files.msbs.array[0].url).to be <= sorted_files.msbs.array[1].url
|
33
|
+
|
34
|
+
actual = sorted_files.select expected1
|
35
|
+
expect(actual.length).to eq(1)
|
36
|
+
expect(actual.first&.end_with?(expected1)).to be true
|
37
|
+
|
38
|
+
actual = sorted_files.select expected2
|
39
|
+
expect(actual.length).to eq(1)
|
40
|
+
expect(actual.first&.end_with?(expected2)).to be true
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'handles multiple matches' do
|
44
|
+
sorted_files = described_class.new
|
45
|
+
sorted_files.insert(expected1, "https://mslinn.com/#{expected1}") # insert reverses expected1
|
46
|
+
sorted_files.insert(expected2, "https://mslinn.com/#{expected2}")
|
47
|
+
sorted_files.enable_search
|
48
|
+
|
49
|
+
expected = '.html'
|
50
|
+
actual = sorted_files.select expected
|
51
|
+
expect(actual.length).to eq(2)
|
52
|
+
expect(actual.first&.end_with?(expected)).to be true
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'works with 3 items' do
|
56
|
+
sorted_files = described_class.new
|
57
|
+
sorted_files.insert(expected1, "https://mslinn.com/#{expected1}") # insert reverses expected1
|
58
|
+
sorted_files.insert(expected2, "https://mslinn.com/#{expected2}")
|
59
|
+
sorted_files.insert(expected3, "https://mslinn.com/#{expected3}")
|
60
|
+
sorted_files.enable_search
|
61
|
+
|
62
|
+
expect(sorted_files.msbs.array[0].url).to be <= sorted_files.msbs.array[1].url
|
63
|
+
expect(sorted_files.msbs.array[1].url).to be <= sorted_files.msbs.array[2].url
|
64
|
+
|
65
|
+
actual = sorted_files.select expected1
|
66
|
+
expect(actual.length).to eq(1)
|
67
|
+
expect(actual.first&.end_with?(expected1)).to be true
|
68
|
+
|
69
|
+
actual = sorted_files.select expected2
|
70
|
+
expect(actual.length).to eq(1)
|
71
|
+
expect(actual.first&.end_with?(expected2)).to be true
|
72
|
+
|
73
|
+
actual = sorted_files.select expected3
|
74
|
+
expect(actual.length).to eq(1)
|
75
|
+
expect(actual.first&.end_with?(expected3)).to be true
|
76
|
+
|
77
|
+
expected = '.html'
|
78
|
+
actual = sorted_files.select expected
|
79
|
+
expect(actual.length).to eq(3)
|
80
|
+
expect(actual.first&.end_with?(expected)).to be true
|
81
|
+
end
|
82
|
+
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/status_persistence.txt
CHANGED
@@ -1,9 +1,3 @@
|
|
1
|
-
example_id
|
2
|
-
|
3
|
-
./spec/
|
4
|
-
./spec/custom_error_spec.rb[2:1] | passed | 0.0011 seconds |
|
5
|
-
./spec/jekyll_plugin_helper_options_spec.rb[1:1] | failed | 0.00005 seconds |
|
6
|
-
./spec/jekyll_plugin_helper_options_spec.rb[1:2] | failed | 0.00003 seconds |
|
7
|
-
./spec/jekyll_plugin_helper_options_spec.rb[1:3] | failed | 0.00003 seconds |
|
8
|
-
./spec/jekyll_plugin_helper_options_spec.rb[1:4] | failed | 0.00003 seconds |
|
9
|
-
./spec/liquid_variable_parsing_spec.rb[1:1] | failed | 0.00003 seconds |
|
1
|
+
example_id | status | run_time |
|
2
|
+
----------------------------------------------- | ------ | --------------- |
|
3
|
+
./spec/jekyll_block_plugin_support_spec.rb[1:1] | passed | 0.00062 seconds |
|