jekyll-test-harness 0.1.0.alpha
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 +7 -0
- data/lib/jekyll_test_harness/core/configuration.rb +117 -0
- data/lib/jekyll_test_harness/core/data_tools.rb +41 -0
- data/lib/jekyll_test_harness/core/errors.rb +78 -0
- data/lib/jekyll_test_harness/core/file_tree.rb +31 -0
- data/lib/jekyll_test_harness/core/files_dsl.rb +157 -0
- data/lib/jekyll_test_harness/core/fixture_loader.rb +104 -0
- data/lib/jekyll_test_harness/core/jekyll_blueprint.rb +31 -0
- data/lib/jekyll_test_harness/core/paths.rb +94 -0
- data/lib/jekyll_test_harness/core/site_harness.rb +148 -0
- data/lib/jekyll_test_harness/core/temporary_directory.rb +101 -0
- data/lib/jekyll_test_harness/entrypoint.rb +19 -0
- data/lib/jekyll_test_harness/framework/helpers.rb +105 -0
- data/lib/jekyll_test_harness/framework/installer.rb +158 -0
- data/lib/jekyll_test_harness/version.rb +6 -0
- data/lib/jekyll_test_harness.rb +4 -0
- data/readme.md +231 -0
- metadata +134 -0
data/readme.md
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Jekyll Test Harness
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Simple integration testing for Jekyll plugins. Extends RSpec or Minitest with helper methods for building a real Jekyll site, with your plugin available, to test how it actually runs within Jekyll.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## Setup
|
|
9
|
+
|
|
10
|
+
```ruby
|
|
11
|
+
# Gemfile
|
|
12
|
+
group :test do
|
|
13
|
+
gem 'jekyll-test-harness'
|
|
14
|
+
gem 'rspec', '~> 3.13' # if using RSpec
|
|
15
|
+
gem 'minitest', '>= 5.0' # if using Minitest
|
|
16
|
+
end
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Load the harness:
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
# spec/spec_helper.rb or test/test_helper.rb
|
|
23
|
+
require 'rspec' # or below
|
|
24
|
+
require 'minitest/autorun' # or above
|
|
25
|
+
require 'jekyll_test_harness'
|
|
26
|
+
require 'my_plugin'
|
|
27
|
+
|
|
28
|
+
JekyllTestHarness.install!
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`JekyllTestHarness.install!` auto-detects your test framework. You can also pass global configuration options:
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
JekyllTestHarness.install!(
|
|
35
|
+
framework: :rspec # or :minitest, to be explicit
|
|
36
|
+
failures: :clean, # or :keep
|
|
37
|
+
output: nil # nil => system temp, or project-relative string like 'tmp/jekyll-sites'
|
|
38
|
+
)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If both RSpec and Minitest are loaded in the same process, set `framework:` explicitly.
|
|
42
|
+
|
|
43
|
+
Options:
|
|
44
|
+
|
|
45
|
+
- `failures:`
|
|
46
|
+
- `:clean` (default): remove temporary site directories after failures.
|
|
47
|
+
- `:keep`: keep failed build directories for debugging.
|
|
48
|
+
- `output:`
|
|
49
|
+
- `nil` (default): build under system temp.
|
|
50
|
+
- relative path: resolved from the project root captured during `install!`.
|
|
51
|
+
- absolute path: used as-is.
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
## Compatibility
|
|
55
|
+
|
|
56
|
+
- Ruby: `>= 2.4.4`
|
|
57
|
+
- Jekyll: `>= 3.8.5`, `< 5.0`
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## Test DSL
|
|
61
|
+
|
|
62
|
+
After calling `install!`, your examples/tests get these helper methods:
|
|
63
|
+
|
|
64
|
+
- `jekyll_build(...) { |site, files| ... }`
|
|
65
|
+
- `jekyll_config(hash = nil, file: nil)`
|
|
66
|
+
- `jekyll_files { ... }`
|
|
67
|
+
- `jekyll_blueprint(config:, files:)`
|
|
68
|
+
- `jekyll_merge(base, new)`
|
|
69
|
+
|
|
70
|
+
### `jekyll_build`
|
|
71
|
+
|
|
72
|
+
Builds a fresh throwaway Jekyll site for one test, runs a real Jekyll build (`Jekyll::Site#process`), and yields:
|
|
73
|
+
|
|
74
|
+
- `site`: the built `Jekyll::Site` object (collections, documents, metadata, etc.)
|
|
75
|
+
- `files`: inspect the files that were output by Jekyll
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
jekyll_build(blueprint = nil, config: nil, files: nil) do |site, files|
|
|
79
|
+
# assertions
|
|
80
|
+
end
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
No default scaffold is written automatically. Supply your own files/layouts/content.
|
|
84
|
+
|
|
85
|
+
When the first argument is a blueprint, `jekyll_build` runs in explicit blueprint mode:
|
|
86
|
+
|
|
87
|
+
- buffered values from `jekyll_config` and `jekyll_files` are ignored for that build.
|
|
88
|
+
- only blueprint data plus explicit `config:`/`files:` overrides are used.
|
|
89
|
+
- every `jekyll_build` call flushes buffered config/files, whether buffers are used in that call or not.
|
|
90
|
+
|
|
91
|
+
### `files` object
|
|
92
|
+
|
|
93
|
+
`jekyll_build` yields a `files` helper with:
|
|
94
|
+
|
|
95
|
+
- `dir`:
|
|
96
|
+
absolute output directory.
|
|
97
|
+
- `path(relative_path)`:
|
|
98
|
+
absolute path under output directory.
|
|
99
|
+
- `read(relative_path)`:
|
|
100
|
+
reads file from output directory.
|
|
101
|
+
- `list(root = nil)`:
|
|
102
|
+
returns output file paths relative to output directory.
|
|
103
|
+
|
|
104
|
+
Source inspection methods are also available:
|
|
105
|
+
|
|
106
|
+
- `source_dir`
|
|
107
|
+
- `source_path(relative_path)`
|
|
108
|
+
- `source_read(relative_path)`
|
|
109
|
+
- `source_list(root = nil)`
|
|
110
|
+
|
|
111
|
+
`relative_path` arguments are validated to prevent path traversal outside the temporary site.
|
|
112
|
+
|
|
113
|
+
### `jekyll_config(hash = nil, file: nil)`
|
|
114
|
+
|
|
115
|
+
Builds config data and appends it to the internal config buffer.
|
|
116
|
+
|
|
117
|
+
- `hash` can be provided directly.
|
|
118
|
+
- `file:` loads YAML from a fixture path relative to project root.
|
|
119
|
+
- if both are provided, `hash` merges over loaded fixture YAML.
|
|
120
|
+
|
|
121
|
+
Each call returns the resolved hash and merges it into the buffer.
|
|
122
|
+
|
|
123
|
+
When calling `jekyll_build`, if `config:` is omitted and no blueprint is passed, the buffered value from `jekyll_config` is used. Either way, the buffer is then flushed.
|
|
124
|
+
|
|
125
|
+
Safety rule:
|
|
126
|
+
|
|
127
|
+
- user-provided `source` and `destination` config keys are ignored.
|
|
128
|
+
- the harness always enforces its own temporary `source`/`destination` paths.
|
|
129
|
+
- a warning is emitted when either key is provided.
|
|
130
|
+
|
|
131
|
+
### `jekyll_files { ... }`
|
|
132
|
+
|
|
133
|
+
Use this helper to specify the files within the test Jekyll site. Builds nested file hashes with DSL methods and appends result to the internal files buffer.
|
|
134
|
+
|
|
135
|
+
```ruby
|
|
136
|
+
files = jekyll_files do
|
|
137
|
+
folder '_layouts' do
|
|
138
|
+
file 'default.html' do
|
|
139
|
+
'<html><body>{{ content }}</body></html>'
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
file 'index.md' do
|
|
143
|
+
frontmatter('layout' => 'default')
|
|
144
|
+
contents('Hello from buffered files')
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
- `folder(name) { ... }` can contain nested `folder`/`file` calls.
|
|
150
|
+
- `file(name) { ... }` block defines file contents.
|
|
151
|
+
- Inside a `file` block, these helpers are available:
|
|
152
|
+
- `frontmatter(hash = nil, file: nil)`
|
|
153
|
+
- YAML-dumps hash between `---` separators.
|
|
154
|
+
- `file:` loads YAML fixture first, then merges inline hash over it.
|
|
155
|
+
- `contents(string = nil, file: nil)`
|
|
156
|
+
- passes string through directly.
|
|
157
|
+
- `file:` loads raw fixture text.
|
|
158
|
+
- If `frontmatter`/`contents` are not used, file block can directly return:
|
|
159
|
+
- `String` (written directly)
|
|
160
|
+
- `Array` (joined with newlines)
|
|
161
|
+
- `Hash` (YAML-dumped)
|
|
162
|
+
|
|
163
|
+
Each `jekyll_files` call both returns the generated hash and merges it into the internal files buffer. The returned hash could be passed to `jekyll_build` or `jekyll_blueprint`.
|
|
164
|
+
|
|
165
|
+
When calling `jekyll_build`, if `files:` is omitted and no blueprint is passed, the buffered value from `jekyll_files` is used. Either way, the buffer is then flushed.
|
|
166
|
+
|
|
167
|
+
### `jekyll_blueprint(config:, files:)`
|
|
168
|
+
|
|
169
|
+
Creates a reusable blueprint object that stores config and file hashes for composition.
|
|
170
|
+
|
|
171
|
+
```ruby
|
|
172
|
+
base_blueprint = jekyll_blueprint(
|
|
173
|
+
config: { 'my_plugin' => { 'mode' => 'base' } },
|
|
174
|
+
files: {
|
|
175
|
+
'_layouts' => { 'default.html' => '<html><body>{{ content }}</body></html>' },
|
|
176
|
+
'index.md' => "---\nlayout: default\n---\nBase body\n"
|
|
177
|
+
}
|
|
178
|
+
)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
A blueprint can be passed as the first parameter of `jekyll_build`. If `config` or `files` are also passed, these are merged over the blueprint.
|
|
182
|
+
|
|
183
|
+
Passing a blueprint also disables buffered `jekyll_config`/`jekyll_files` input for that build.
|
|
184
|
+
|
|
185
|
+
### `jekyll_merge(base, new)`
|
|
186
|
+
|
|
187
|
+
Used for deep merges:
|
|
188
|
+
|
|
189
|
+
- Hash + Hash => deep hash merge
|
|
190
|
+
- JekyllBlueprint + JekyllBlueprint => new merged blueprint.
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
## Example
|
|
194
|
+
|
|
195
|
+
```ruby
|
|
196
|
+
RSpec.describe 'my plugin integration' do
|
|
197
|
+
it 'renders expected output' do
|
|
198
|
+
jekyll_config(file: 'spec/fixtures/jekyll/base_config.yml')
|
|
199
|
+
|
|
200
|
+
jekyll_files do
|
|
201
|
+
folder '_layouts' do
|
|
202
|
+
file 'default.html' do
|
|
203
|
+
'<html><body>{{ content }}</body></html>'
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
folder '_posts' do
|
|
208
|
+
file '2026-01-01-demo.md' do
|
|
209
|
+
frontmatter('layout' => 'default', 'permalink' => '/docs/demo.html')
|
|
210
|
+
contents('Hello')
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
jekyll_build do |site, files|
|
|
216
|
+
post = site.collections.fetch('posts').docs.first
|
|
217
|
+
html = files.read('docs/demo.html')
|
|
218
|
+
expect(post).not_to be_nil
|
|
219
|
+
expect(html).to include('Hello')
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Release Notes
|
|
226
|
+
|
|
227
|
+
See `CHANGELOG.md`.
|
|
228
|
+
|
|
229
|
+
## Licence
|
|
230
|
+
|
|
231
|
+
`jekyll-test-harness` is licensed under `LGPL-3.0-or-later`. See `LICENSE.txt`.
|
metadata
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: jekyll-test-harness
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0.alpha
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Convincible
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-02-23 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: jekyll
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 3.8.5
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '5.0'
|
|
23
|
+
type: :runtime
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: 3.8.5
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '5.0'
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: pry
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0.13'
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: 0.13.1
|
|
43
|
+
type: :development
|
|
44
|
+
prerelease: false
|
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
46
|
+
requirements:
|
|
47
|
+
- - "~>"
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: '0.13'
|
|
50
|
+
- - ">="
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: 0.13.1
|
|
53
|
+
- !ruby/object:Gem::Dependency
|
|
54
|
+
name: pry-byebug
|
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - "~>"
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '3.9'
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: 3.9.0
|
|
63
|
+
type: :development
|
|
64
|
+
prerelease: false
|
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - "~>"
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '3.9'
|
|
70
|
+
- - ">="
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: 3.9.0
|
|
73
|
+
- !ruby/object:Gem::Dependency
|
|
74
|
+
name: rspec
|
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - "~>"
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '3.10'
|
|
80
|
+
type: :development
|
|
81
|
+
prerelease: false
|
|
82
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - "~>"
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '3.10'
|
|
87
|
+
description: Builds isolated temporary Jekyll sites for plugin testing with RSpec
|
|
88
|
+
or Minitest, plus optional helper DSL.
|
|
89
|
+
email:
|
|
90
|
+
- development@convincible.media
|
|
91
|
+
executables: []
|
|
92
|
+
extensions: []
|
|
93
|
+
extra_rdoc_files: []
|
|
94
|
+
files:
|
|
95
|
+
- lib/jekyll_test_harness.rb
|
|
96
|
+
- lib/jekyll_test_harness/core/configuration.rb
|
|
97
|
+
- lib/jekyll_test_harness/core/data_tools.rb
|
|
98
|
+
- lib/jekyll_test_harness/core/errors.rb
|
|
99
|
+
- lib/jekyll_test_harness/core/file_tree.rb
|
|
100
|
+
- lib/jekyll_test_harness/core/files_dsl.rb
|
|
101
|
+
- lib/jekyll_test_harness/core/fixture_loader.rb
|
|
102
|
+
- lib/jekyll_test_harness/core/jekyll_blueprint.rb
|
|
103
|
+
- lib/jekyll_test_harness/core/paths.rb
|
|
104
|
+
- lib/jekyll_test_harness/core/site_harness.rb
|
|
105
|
+
- lib/jekyll_test_harness/core/temporary_directory.rb
|
|
106
|
+
- lib/jekyll_test_harness/entrypoint.rb
|
|
107
|
+
- lib/jekyll_test_harness/framework/helpers.rb
|
|
108
|
+
- lib/jekyll_test_harness/framework/installer.rb
|
|
109
|
+
- lib/jekyll_test_harness/version.rb
|
|
110
|
+
- readme.md
|
|
111
|
+
homepage: https://github.com/ConvincibleMedia/jekyll-test-harness
|
|
112
|
+
licenses:
|
|
113
|
+
- LGPL-3.0-or-later
|
|
114
|
+
metadata: {}
|
|
115
|
+
post_install_message:
|
|
116
|
+
rdoc_options: []
|
|
117
|
+
require_paths:
|
|
118
|
+
- lib
|
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - ">="
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: 2.4.4
|
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
|
+
requirements:
|
|
126
|
+
- - ">"
|
|
127
|
+
- !ruby/object:Gem::Version
|
|
128
|
+
version: 1.3.1
|
|
129
|
+
requirements: []
|
|
130
|
+
rubygems_version: 3.2.3
|
|
131
|
+
signing_key:
|
|
132
|
+
specification_version: 4
|
|
133
|
+
summary: Reusable integration test harness for Jekyll plugin development.
|
|
134
|
+
test_files: []
|