integtest/spec/all_books_sub_dir_spec.rb (253 lines of code) (raw):
# frozen_string_literal: true
require_relative 'spec_helper'
RSpec.describe 'building all books' do
describe '--sub_dir' do
##
# Setups up a repo that looks like:
# master sub_me
# original master-------->subbed
# |
# new master
# |
# too new master
#
# Optionally runs the build once on the commit "new master". Then it always
# runs the build, substituting sub_me for the master branch. If:
# * --keep_hash isn't specified or
# * the sub_me branch has outstanding changes or
# * there was a merge conflict or
# * the build wasn't run against "new master"
# then --sub_dir will pick up the contents of the directory and the build
# won't have "new maser" because it was forked from "original master".
# Otherwise, --keep_hash and --sub_dir will cause the build to merge
# "new master" and "subbed" and build against *that*.
def self.convert_with_sub(keep_hash: true, commit_sub: true,
build_with_init: true,
cause_merge_conflict: false, premerge: false)
convert_before do |src, dest|
repo = setup_repo src
setup_book src, repo
dest.prepare_convert_all(src.conf).convert if build_with_init
modify_master_after_build repo
setup_sub repo, commit_sub, cause_merge_conflict, premerge
second_convert src, repo, dest, keep_hash
end
end
def self.prefix
'docs/'
end
def self.setup_repo(src)
repo = src.repo 'repo'
repo.write "#{prefix}index.adoc", index
repo.write "#{prefix}from_master.adoc", 'original master'
repo.write "#{prefix}from_subbed.adoc", 'unsubbed'
repo.commit 'original master'
repo.write "#{prefix}from_master.adoc", 'new master'
repo.write "#{prefix}conflict", 'from master'
repo.commit 'new master'
repo
end
def self.setup_book(src, repo)
book = src.book 'Test'
book.index = "#{prefix}index.adoc"
book.source repo, 'docs'
end
def self.modify_master_after_build(repo)
repo.write "#{prefix}from_master.adoc", 'too new master'
repo.commit 'too new master'
end
def self.setup_sub(repo, commit_sub, cause_merge_conflict, premerge)
repo.switch_to_branch 'HEAD~2'
repo.switch_to_new_branch 'sub_me'
repo.write "#{prefix}from_subbed.adoc", 'now subbed'
repo.write "#{prefix}conflict", 'from subbed' if cause_merge_conflict
repo.commit 'subbed' if commit_sub
repo.merge 'master' if premerge
end
def self.second_convert(src, repo, dest, keep_hash)
builder = dest.prepare_convert_all src.conf
builder.sub_dir repo, 'master'
builder.keep_hash if keep_hash
builder.convert
dest.checkout_conversion
end
def self.index
<<~ASCIIDOC
= Title
[[chapter]]
== Chapter
include::from_master.adoc[]
include::from_subbed.adoc[]
ASCIIDOC
end
let(:logs) { outputs[-1] }
shared_examples 'examples' do |master|
file_context 'raw/test/master/chapter.html' do
it "contains the #{master} master changes" do
expect(contents).to include("<p>#{master} master</p>")
end
it 'contains the subbed changes' do
expect(contents).to include('<p>now subbed</p>')
end
end
end
shared_examples 'contains the original master and subbed changes' do
include_examples 'examples', 'original'
end
shared_examples 'contains the new master and subbed changes' do
include_examples 'examples', 'new'
end
shared_examples 'contains the too new master and subbed changes' do
include_examples 'examples', 'too new'
end
shared_examples 'log merge' do |path|
it "log that it started merging [#{path}]" do
expect(logs).to include(<<~LOGS)
Test: Merging the subbed dir for [repo][master][#{path}] into the last successful build.
LOGS
end
it "log that it merged [#{path}]" do
expect(logs).to include(<<~LOGS)
Test: Merged the subbed dir for [repo][master][#{path}] into the last successful build.
LOGS
end
end
describe 'without --keep_hash' do
convert_with_sub keep_hash: false
it "doesn't log that it won't merge because of uncommitted changes" do
expect(logs).not_to include(<<~LOGS)
Test: Not merging the subbed dir for [repo][master][docs] because it has uncommitted changes.
LOGS
end
include_examples 'contains the original master and subbed changes'
end
describe 'with --keep_hash' do
describe 'when there are uncommitted changes' do
convert_with_sub commit_sub: false
it "logs that it won't merge because of uncommitted changes" do
expect(logs).to include(<<~LOGS)
Test: Not merging the subbed dir for [repo][master][docs] because it has uncommitted changes.
LOGS
end
include_examples 'contains the original master and subbed changes'
end
describe 'when the source is new' do
convert_with_sub build_with_init: false
it "log that it won't merge because the source is new" do
expect(logs).to include(<<~LOGS)
Test: Not merging the subbed dir for [repo][master][docs] because it is new.
LOGS
end
include_examples 'contains the original master and subbed changes'
end
describe 'when the subbed dir can be merged' do
convert_with_sub
include_examples 'log merge', 'docs'
include_examples 'contains the new master and subbed changes'
end
describe 'when the source path is the entire repo' do
def self.setup_book(src, repo)
book = src.book 'Test'
book.index = 'docs/index.adoc'
book.source repo, '/'
end
convert_with_sub
include_examples 'log merge', '.'
include_examples 'contains the new master and subbed changes'
end
describe 'when the source path has a *' do
def self.setup_book(src, repo)
book = src.book 'Test'
book.index = 'docs/index.adoc'
book.source repo, '/*/'
end
convert_with_sub
include_examples 'log merge', '*'
include_examples 'contains the new master and subbed changes'
end
describe 'when the source path has a deep *' do
describe 'when the config was used for the first book' do
def self.prefix
'foo/bar/docs/foo/'
end
def self.setup_book(src, repo)
book = src.book 'Test'
book.index = 'foo/bar/docs/foo/index.adoc'
book.source repo, '/foo/*/docs/*'
end
convert_with_sub
include_examples 'log merge', 'foo/*/docs/*'
include_examples 'contains the new master and subbed changes'
end
describe 'when the config is new' do
# TODO: remove these parameters by overriding this sub in more places.
def self.setup_sub(
repo, _commit_sub, _cause_merge_conflict, _premerge
)
repo.switch_to_branch 'HEAD~2'
repo.switch_to_new_branch 'sub_me'
repo.write "#{prefix}from_subbed.adoc", <<~ASCIIDOC
include::../foo/bar/docs/baz/foo.adoc[]
ASCIIDOC
repo.write 'foo/bar/docs/baz/foo.adoc', 'now subbed'
repo.commit 'subbed'
end
def self.second_convert(src, repo, dest, keep_hash)
book = src.book 'Test'
book.source repo, '/foo/*/docs/*'
super
end
convert_with_sub
include_examples 'log merge', 'docs'
it "log that it won't merge because the source is new" do
expect(logs).to include(<<~LOGS)
Test: Not merging the subbed dir for [repo][master][foo/*/docs/*] because it is new.
LOGS
end
include_examples 'contains the new master and subbed changes'
end
end
describe 'when the subbed dir has already been merged' do
# This simulates what github will do if you ask it to build the "sha"
# of the merged PR instead of the "head" of the branch.
convert_with_sub premerge: true
include_examples 'log merge', 'docs'
include_examples 'contains the too new master and subbed changes'
end
describe 'when there is a conflict merging the subbed dir' do
convert_with_sub cause_merge_conflict: true
it 'logs that it failed to merge' do
expect(logs).to include(<<~LOGS)
Test: Failed to merge the subbed dir for [repo][master][docs] into the last successful build:
LOGS
end
it 'logs the conflict' do
expect(logs).to include(<<~LOGS)
CONFLICT (add/add): Merge conflict in docs/conflict
LOGS
end
include_examples 'contains the original master and subbed changes'
end
describe 'when there is more than one source using the same repo' do
def self.setup_book(src, repo)
book = src.book 'Test'
book.index = 'docs/index.adoc'
book.source repo, 'docs/index.adoc'
book.source repo, 'docs/from_master.adoc'
book.source repo, 'docs/from_subbed.adoc'
end
convert_with_sub
include_examples 'log merge', 'docs/index.adoc'
include_examples 'log merge', 'docs/from_master.adoc'
include_examples 'log merge', 'docs/from_subbed.adoc'
include_examples 'contains the new master and subbed changes'
end
describe 'when the book uses sources with glob patterns' do
def self.setup_book(src, repo)
book = src.book 'Test'
book.index = 'docs/index.adoc'
book.source repo, 'docs/index.adoc'
book.source repo, ':(glob)**/from_master.adoc'
book.source repo, ':(glob)**/from_subbed.adoc'
end
convert_with_sub
include_examples 'log merge', 'docs/index.adoc'
include_examples 'log merge', ':(glob)**/from_master.adoc'
include_examples 'log merge', ':(glob)**/from_subbed.adoc'
include_examples 'contains the new master and subbed changes'
end
describe 'when more than one book uses the same source' do
def self.setup_book(src, repo)
%w[Test Test2].each do |name|
book = src.book name
book.index = 'docs/index.adoc'
book.source repo, 'docs'
end
end
convert_with_sub
include_examples 'log merge', 'docs'
it 'logs only one merge' do
# This asserts that we log a single merge. We *should* be using the
# cache instead.
expect(logs).not_to match(/Merged.+Merged/m)
end
include_examples 'contains the new master and subbed changes'
end
end
end
end