diff -Nru nanoc-4.11.0/.circleci/config.yml nanoc-4.11.14/.circleci/config.yml --- nanoc-4.11.0/.circleci/config.yml 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/.circleci/config.yml 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,425 @@ +version: 2 + +defaults_cruby24: &defaults_cruby24 + working_directory: ~/project + docker: + - image: circleci/ruby:2.4 + environment: + ENV: "CI" + BUNDLE_JOBS: "4" + BUNDLE_RETRY: "3" + BUNDLE_PATH: vendor/bundle + +defaults_cruby25: &defaults_cruby25 + working_directory: ~/project + docker: + - image: circleci/ruby:2.5 + environment: + ENV: "CI" + BUNDLE_JOBS: "4" + BUNDLE_RETRY: "3" + BUNDLE_PATH: vendor/bundle + +defaults_cruby26: &defaults_cruby26 + working_directory: ~/project + docker: + - image: circleci/ruby:2.6 + environment: + ENV: "CI" + BUNDLE_JOBS: "4" + BUNDLE_RETRY: "3" + BUNDLE_PATH: vendor/bundle + +jobs: + setup_cruby24: + <<: *defaults_cruby24 + steps: + - checkout + - attach_workspace: + at: ~/project + - restore_cache: + keys: + - nanoc-cruby24-{{ arch }}-{{ checksum "Gemfile" }} + - run: + name: Install dependencies + command: bundle + - save_cache: + key: nanoc-cruby24-{{ arch }}-{{ checksum "Gemfile" }} + paths: + - vendor/bundle + - persist_to_workspace: + root: . + paths: vendor/bundle + + setup_cruby25: + <<: *defaults_cruby25 + steps: + - checkout + - attach_workspace: + at: ~/project + - restore_cache: + keys: + - nanoc-cruby25-{{ arch }}-{{ checksum "Gemfile" }} + - run: + name: Install dependencies + command: bundle + - save_cache: + key: nanoc-cruby25-{{ arch }}-{{ checksum "Gemfile" }} + paths: + - vendor/bundle + - persist_to_workspace: + root: . + paths: vendor/bundle + + setup_cruby26: + <<: *defaults_cruby26 + steps: + - checkout + - attach_workspace: + at: ~/project + - restore_cache: + keys: + - nanoc-cruby26-{{ arch }}-{{ checksum "Gemfile" }} + - run: + name: Install dependencies + command: bundle + - save_cache: + key: nanoc-cruby26-{{ arch }}-{{ checksum "Gemfile" }} + paths: + - vendor/bundle + - persist_to_workspace: + root: . + paths: vendor/bundle + + check_style_cruby26: + <<: *defaults_cruby26 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + - run: + name: Check style + command: bundle exec rake rubocop + + test_nanoc_cruby24: + <<: *defaults_cruby24 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/nanoc + - run: + name: Test nanoc + command: bundle exec rake test + working_directory: ~/project/nanoc + - store_test_results: + path: ~/project/nanoc/test-results + + test_nanoc_core_cruby24: + <<: *defaults_cruby24 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/nanoc-core + - run: + name: Test nanoc-core + command: bundle exec rake test + working_directory: ~/project/nanoc-core + - store_test_results: + path: ~/project/nanoc-core/test-results + + test_nanoc_external_cruby24: + <<: *defaults_cruby24 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/nanoc-external + - run: + name: Test nanoc-external + command: bundle exec rake test + working_directory: ~/project/nanoc-external + - store_test_results: + path: ~/project/nanoc-external/test-results + + test_nanoc_live_cruby24: + <<: *defaults_cruby24 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/nanoc-live + - run: + name: Test nanoc-live + command: bundle exec rake test + working_directory: ~/project/nanoc-live + - store_test_results: + path: ~/project/nanoc-live/test-results + + test_guard_nanoc_cruby24: + <<: *defaults_cruby24 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/guard-nanoc + - run: + name: Test guard-nanoc + command: bundle exec rake test + working_directory: ~/project/guard-nanoc + - store_test_results: + path: ~/project/guard-nanoc/test-results + + test_nanoc_cruby25: + <<: *defaults_cruby25 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/nanoc + - run: + name: Test nanoc + command: bundle exec rake test + working_directory: ~/project/nanoc + - store_test_results: + path: ~/project/nanoc/test-results + + test_nanoc_core_cruby25: + <<: *defaults_cruby25 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/nanoc-core + - run: + name: Test nanoc-core + command: bundle exec rake test + working_directory: ~/project/nanoc-core + - store_test_results: + path: ~/project/nanoc-core/test-results + + test_nanoc_external_cruby25: + <<: *defaults_cruby25 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/nanoc-external + - run: + name: Test nanoc-external + command: bundle exec rake test + working_directory: ~/project/nanoc-external + - store_test_results: + path: ~/project/nanoc-external/test-results + + test_nanoc_live_cruby25: + <<: *defaults_cruby25 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/nanoc-live + - run: + name: Test nanoc-live + command: bundle exec rake test + working_directory: ~/project/nanoc-live + - store_test_results: + path: ~/project/nanoc-live/test-results + + test_guard_nanoc_cruby25: + <<: *defaults_cruby25 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/guard-nanoc + - run: + name: Test guard-nanoc + command: bundle exec rake test + working_directory: ~/project/guard-nanoc + - store_test_results: + path: ~/project/guard-nanoc/test-results + + test_nanoc_cruby26: + <<: *defaults_cruby26 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/nanoc + - run: + name: Test nanoc + command: bundle exec rake test + working_directory: ~/project/nanoc + - store_test_results: + path: ~/project/nanoc/test-results + + test_nanoc_core_cruby26: + <<: *defaults_cruby26 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/nanoc-core + - run: + name: Test nanoc-core + command: bundle exec rake test + working_directory: ~/project/nanoc-core + - store_test_results: + path: ~/project/nanoc-core/test-results + + test_nanoc_external_cruby26: + <<: *defaults_cruby26 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/nanoc-external + - run: + name: Test nanoc-external + command: bundle exec rake test + working_directory: ~/project/nanoc-external + - store_test_results: + path: ~/project/nanoc-external/test-results + + test_nanoc_live_cruby26: + <<: *defaults_cruby26 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/nanoc-live + - run: + name: Test nanoc-live + command: bundle exec rake test + working_directory: ~/project/nanoc-live + - store_test_results: + path: ~/project/nanoc-live/test-results + + test_guard_nanoc_cruby26: + <<: *defaults_cruby26 + steps: + - checkout + - attach_workspace: + at: ~/project + - run: + name: Install dependencies + command: bundle + working_directory: ~/project/guard-nanoc + - run: + name: Test guard-nanoc + command: bundle exec rake test + working_directory: ~/project/guard-nanoc + - store_test_results: + path: ~/project/guard-nanoc/test-results + +workflows: + version: 2 + test: + jobs: + # setup + - setup_cruby24 + - setup_cruby25 + - setup_cruby26 + + # check style + - check_style_cruby26: + requires: + - setup_cruby26 + + # test [CRuby 2.4] + - test_nanoc_cruby24: + requires: + - setup_cruby24 + - test_nanoc_core_cruby24: + requires: + - setup_cruby24 + - test_nanoc_external_cruby24: + requires: + - setup_cruby24 + - test_nanoc_live_cruby24: + requires: + - setup_cruby24 + - test_guard_nanoc_cruby24: + requires: + - setup_cruby24 + + # test [CRuby 2.5] + - test_nanoc_cruby25: + requires: + - setup_cruby25 + - test_nanoc_core_cruby25: + requires: + - setup_cruby25 + - test_nanoc_external_cruby25: + requires: + - setup_cruby25 + - test_nanoc_live_cruby25: + requires: + - setup_cruby25 + - test_guard_nanoc_cruby25: + requires: + - setup_cruby25 + + # test [CRuby 2.6] + - test_nanoc_cruby26: + requires: + - setup_cruby26 + - test_nanoc_core_cruby26: + requires: + - setup_cruby26 + - test_nanoc_external_cruby26: + requires: + - setup_cruby26 + - test_nanoc_live_cruby26: + requires: + - setup_cruby26 + - test_guard_nanoc_cruby26: + requires: + - setup_cruby26 diff -Nru nanoc-4.11.0/common/spec/spec_helper_foot_core.rb nanoc-4.11.14/common/spec/spec_helper_foot_core.rb --- nanoc-4.11.0/common/spec/spec_helper_foot_core.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/common/spec/spec_helper_foot_core.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,664 @@ +# frozen_string_literal: true +# frozen_string_literal: true + +module Nanoc + module Spec + module Helper + def chdir(dir) + here = Dir.getwd + Dir.chdir(dir) + yield + ensure + Dir.chdir(here) + end + + def command?(cmd) + TTY::Which.exist?(cmd) + end + + def skip_unless_have_command(cmd) + skip "Could not find external command \"#{cmd}\"" unless command?(cmd) + end + + def skip_unless_gem_available(gem) + require gem + rescue LoadError + skip "Could not load gem \"#{gem}\"" + end + + def sleep_until(max: 3.0) + start = Time.now + loop do + diff = (Time.now - start).to_f + if diff > max + raise "Waited for #{diff}s for condition to become true, but it never did" + end + + break if yield + + sleep 0.1 + end + end + end + + class HelperContext + # @return [Nanoc::Core::DependencyTracker] + attr_reader :dependency_tracker + + attr_reader :erbout + + # @param [Module] mod The helper module to create a context for + def initialize(mod) + @mod = mod + + @erbout = +'' + @action_sequence = {} + @config = Nanoc::Core::Configuration.new(dir: Dir.getwd).with_defaults + @reps = Nanoc::Core::ItemRepRepo.new + @items = Nanoc::Core::ItemCollection.new(@config) + @layouts = Nanoc::Core::LayoutCollection.new(@config) + @dependency_tracker = Nanoc::Core::DependencyTracker.new(Object.new) + @compiled_content_store = Nanoc::Core::CompiledContentStore.new + @action_provider = new_action_provider + end + + # Creates a new item and adds it to the site’s collection of items. + # + # @param [String] content The uncompiled item content + # + # @param [Hash] attributes A hash containing this item's attributes + # + # @param [Nanoc::Core::Identifier, String] identifier This item's identifier + # + # @return [Nanoc::Core::CompilationItemView] A view for the newly created item + def create_item(content, attributes, identifier) + item = Nanoc::Core::Item.new(content, attributes, identifier) + @items = @items.add(item) + self + end + + # Creates a new layout and adds it to the site’s collection of layouts. + # + # @param [String] content The raw layout content + # + # @param [Hash] attributes A hash containing this layout's attributes + # + # @param [Nanoc::Core::Identifier, String] identifier This layout's identifier + # + # @return [Nanoc::Core::CompilationItemView] A view for the newly created layout + def create_layout(content, attributes, identifier) + layout = Nanoc::Core::Layout.new(content, attributes, identifier) + @layouts = @layouts.add(layout) + self + end + + # Creates a new representation for the given item. + # + # @param [Nanoc::Core::CompilationItemView] item The item to create a represetation for + # + # @param [String] path The path of the `:last` snapshot of this item representation + # @param [Symbol] rep The rep name to create + def create_rep(item, path, rep = :default) + rep = Nanoc::Core::ItemRep.new(item._unwrap, rep) + rep.paths[:last] = [path] + @reps << rep + self + end + + # @return [Object] An object that includes the helper functions + def helper + mod = @mod + klass = Class.new(Nanoc::Core::Context) { include mod } + klass.new(assigns) + end + + def item=(item) + @item = item ? item._unwrap : nil + end + + def item_rep=(item_rep) + @item_rep = item_rep ? item_rep._unwrap : nil + end + + # @return [Nanoc::Core::MutableConfigView] + def config + assigns[:config] + end + + # @return [Nanoc::Core::CompilationItemView, nil] + def item + assigns[:item] + end + + # @return [Nanoc::Core::BasicItemRepView, nil] + def item_rep + assigns[:item_rep] + end + + # @return [Nanoc::Core::ItemCollectionWithRepsView] + def items + assigns[:items] + end + + # @return [Nanoc::Core::LayoutCollectionView] + def layouts + assigns[:layouts] + end + + def action_sequence_for(obj) + @action_sequence.fetch(obj, []) + end + + def update_action_sequence(obj, memory) + @action_sequence[obj] = memory + end + + def compiled_content_store + view_context.compiled_content_store + end + + private + + def view_context + compilation_context = + Nanoc::Core::CompilationContext.new( + action_provider: @action_provider, + reps: @reps, + site: site, + compiled_content_cache: Nanoc::Core::CompiledContentCache.new(config: @config), + compiled_content_store: @compiled_content_store, + ) + + Nanoc::Core::ViewContextForCompilation.new( + reps: @reps, + items: @items, + dependency_tracker: @dependency_tracker, + compilation_context: compilation_context, + compiled_content_store: @compiled_content_store, + ) + end + + def new_action_provider + Class.new(Nanoc::Core::ActionProvider) do + def self.for(_context) + raise NotImplementedError + end + + def initialize(context) + @context = context + end + + def rep_names_for(_item) + [:default] + end + + def action_sequence_for(obj) + @context.action_sequence_for(obj) + end + + def snapshots_defs_for(_rep) + [Nanoc::Core::SnapshotDef.new(:last, binary: false)] + end + end.new(self) + end + + def new_compiler_for(site) + Nanoc::Core::CompilerLoader.new.load(site, action_provider: @action_provider) + end + + def site + @_site ||= + Nanoc::Core::Site.new( + config: @config, + code_snippets: [], + data_source: Nanoc::Core::InMemoryDataSource.new(@items, @layouts), + ) + end + + def assigns + { + config: Nanoc::Core::MutableConfigView.new(@config, view_context), + item_rep: @item_rep ? Nanoc::Core::CompilationItemRepView.new(@item_rep, view_context) : nil, + item: @item ? Nanoc::Core::CompilationItemView.new(@item, view_context) : nil, + items: Nanoc::Core::ItemCollectionWithRepsView.new(@items, view_context), + layouts: Nanoc::Core::LayoutCollectionView.new(@layouts, view_context), + _erbout: @erbout, + } + end + end + + module HelperHelper + def ctx + @_ctx ||= HelperContext.new(described_class) + end + + def helper + @_helper ||= ctx.helper + end + end + end +end + +def __nanoc_core_chdir(dir) + here = Dir.getwd + Dir.chdir(dir) + yield +ensure + Dir.chdir(here) +end + +def __nanoc_core_with_env_vars(hash, &_block) + orig_env_hash = ENV.to_hash + hash.each_pair { |k, v| ENV[k] = v } + yield +ensure + orig_env_hash.each_pair { |k, v| ENV[k] = v } +end + +RSpec.configure do |c| + c.include(Nanoc::Spec::Helper) + + c.include(Nanoc::Spec::HelperHelper, helper: true) + + # TODO: Only really relevant when using the filesystem data source + c.before(:each, site: true) do + FileUtils.mkdir_p('content') + FileUtils.mkdir_p('layouts') + FileUtils.mkdir_p('lib') + FileUtils.mkdir_p('output') + + File.write('nanoc.yaml', '{}') + + File.write('Rules', 'passthrough "/**/*"') + end + + c.fuubar_progress_bar_options = { + format: '%c/%C |<%b>%i| %p%%', + } + + c.before(:each, fork: true) do + skip 'fork() is not supported on Windows' if Nanoc::Core.on_windows? + end + + c.before do + Nanoc::Core::NotificationCenter.reset + end + + c.around do |example| + should_chdir = + !example.metadata.key?(:chdir) || + example.metadata[:chdir] + + if should_chdir + Dir.mktmpdir('nanoc-test') do |dir| + __nanoc_core_chdir(dir) { example.run } + end + else + example.run + end + end + + c.around(:each, stdio: true) do |example| + orig_stdout = $stdout + orig_stderr = $stderr + + unless ENV['QUIET'] == 'false' + $stdout = StringIO.new + $stderr = StringIO.new + end + + example.run + + $stdout = orig_stdout + $stderr = orig_stderr + end +end + +RSpec::Matchers.define_negated_matcher :not_match, :match + +RSpec::Matchers.define :send_notification do |name, *expected_args| + supports_block_expectations + + include RSpec::Matchers::Composable + + match do |actual| + @actual_notifications = [] + Nanoc::Core::NotificationCenter.on(name, self) do |*actual_args| + @actual_notifications << actual_args + end + + actual.call + Nanoc::Core::NotificationCenter.sync + + @actual_notifications.any? { |c| c == expected_args } + end + + description do + "send notification #{name.inspect} with args #{expected_args.inspect}" + end + + failure_message do |_actual| + s = +"expected that proc would send notification #{name.inspect} with args #{expected_args.inspect}" + if @actual_notifications.any? + s << " (received #{@actual_notifications.size} times with other arguments: #{@actual_notifications.map(&:inspect).join(', ')})" + end + s + end + + failure_message_when_negated do |_actual| + "expected that proc would not send notification #{name.inspect} with args #{expected_args.inspect}" + end +end + +RSpec::Matchers.define :raise_frozen_error do |_expected| + match do |actual| + begin + actual.call + false + rescue => e + if e.is_a?(RuntimeError) || e.is_a?(TypeError) + e.message =~ /(^can't modify frozen |^unable to modify frozen object$)/ + else + false + end + end + end + + supports_block_expectations + + failure_message do |_actual| + 'expected that proc would raise a frozen error' + end + + failure_message_when_negated do |_actual| + 'expected that proc would not raise a frozen error' + end +end + +RSpec::Matchers.define :be_humanly_sorted do + match do |actual| + actual == sort(actual) + end + + description do + 'be humanly sorted' + end + + failure_message do |actual| + expected_order = [] + actual.zip(sort(actual)).each do |a, b| + if a != b + expected_order << b + end + end + + "expected collection to be sorted (incorrect order: #{expected_order.join(' < ')})" + end + + def sort(coll) + coll.sort_by do |elem| + elem.dup.unicode_normalize(:nfd).encode('ASCII', fallback: ->(_) { '' }).downcase + end + end +end + +RSpec::Matchers.define :finish_in_under do |expected| + supports_block_expectations + + match do |actual| + before = Time.now + actual.call + after = Time.now + @actual_duration = after - before + @actual_duration < expected + end + + chain :seconds do + end + + failure_message do |_actual| + "expected that proc would finish in under #{expected}s, but took #{format '%0.1fs', @actual_duration}" + end + + failure_message_when_negated do |_actual| + "expected that proc would not finish in under #{expected}s, but took #{format '%0.1fs', @actual_duration}" + end +end + +RSpec::Matchers.define :yield_from_fiber do |expected| + supports_block_expectations + + include RSpec::Matchers::Composable + + match do |actual| + @res = Fiber.new { actual.call }.resume + values_match?(expected, @res) + end + + description do + "yield #{expected.inspect} from fiber" + end + + failure_message do |_actual| + "expected that proc would yield #{expected.inspect} from fiber, but was #{@res.inspect}" + end + + failure_message_when_negated do |_actual| + "expected that proc would not yield #{expected.inspect} from fiber, but was #{@res.inspect}" + end +end + +RSpec::Matchers.define :be_some_textual_content do |expected| + include RSpec::Matchers::Composable + + match do |actual| + actual.is_a?(Nanoc::Core::TextualContent) && values_match?(expected, actual.string) + end + + description do + "textual content matching #{expected.inspect}" + end + + failure_message do |actual| + "expected #{actual.inspect} to be textual content matching #{expected.inspect}" + end + + failure_message_when_negated do |actual| + "expected #{actual.inspect} not to be textual content matching #{expected.inspect}" + end +end + +RSpec::Matchers.define :be_some_binary_content do |expected| + include RSpec::Matchers::Composable + + match do |actual| + actual.is_a?(Nanoc::Core::BinaryContent) && values_match?(expected, File.read(actual.filename)) + end + + description do + "binary content matching #{expected.inspect}" + end + + failure_message do |actual| + "expected #{actual.inspect} to be binary content matching #{expected.inspect}" + end + + failure_message_when_negated do |actual| + "expected #{actual.inspect} not to be binary content matching #{expected.inspect}" + end +end + +RSpec::Matchers.alias_matcher :some_textual_content, :be_some_textual_content +RSpec::Matchers.alias_matcher :some_binary_content, :be_some_binary_content + +RSpec::Matchers.define :have_correct_yard_examples do |_name, *_expected_args| + chain :in_file do |file| + root_dir = File.expand_path(__dir__ + '/../..') + YARD.parse(root_dir + '/' + file) + end + + match do |actual| + examples = + P(actual).tags(:example).flat_map do |example| + # Classify + lines = example.text.lines.map do |line| + [/^\s*# ?=>/.match?(line) ? :result : :code, line] + end + + # Join + pieces = [] + lines.each do |line| + if !pieces.empty? && pieces.last.first == line.first + pieces.last.last << line.last + else + pieces << line + end + end + lines = pieces.map(&:last) + + # Collect + lines.each_slice(2).to_a + end + + b = binding + executed_examples = examples.map do |pair| + { + input: pair.first, + expected: eval(pair.last.match(/# ?=>(.*)/)[1], b), + actual: eval(pair.first, b), + } + end + + @failing_examples = executed_examples.reject { |ex| ex[:expected] == ex[:actual] } + + @failing_examples.empty? + end + + failure_message do |_actual| + parts = + @failing_examples.map do |ex| + format( + "%s\nexpected to be\n %s\nbut was\n %s", + ex[:input], + ex[:expected].inspect, + ex[:actual].inspect, + ) + end + + parts.join("\n\n---\n\n") + end +end + +RSpec::Matchers.define :have_a_valid_manifest do + match do |actual| + manifest_lines = File.readlines(actual + '.manifest').map(&:chomp).reject(&:empty?) + gemspec_lines = eval(File.read(actual + '.gemspec'), binding, actual + '.gemspec').files + + @missing_from_manifest = gemspec_lines - manifest_lines + @extra_in_manifest = manifest_lines - gemspec_lines + + @missing_from_manifest.empty? && @extra_in_manifest.empty? + end + + description do + 'have a valid manifest' + end + + failure_message do |_actual| + reasons = [] + if @missing_from_manifest.any? + reasons << "file(s) missing from manifest (#{@missing_from_manifest.join(', ')})" + end + if @extra_in_manifest.any? + reasons << "file(s) extra in manifest (#{@extra_in_manifest.join(', ')})" + end + + "expected manifest to be valid (problems: #{reasons.join(' and ')})" + end +end + +RSpec::Matchers.define :create_dependency_on do |expected| + supports_block_expectations + + include RSpec::Matchers::Composable + + match do |actual| + @to = expected + dependency_tracker = @to._context.dependency_tracker + dependency_store = dependency_tracker.dependency_store + + from = Nanoc::Core::Item.new('x', {}, '/x.md') + + a = dependency_store.objects_causing_outdatedness_of(from) + + begin + dependency_tracker.enter(from) + actual.call + ensure + dependency_tracker.exit + end + + b = dependency_store.objects_causing_outdatedness_of(from) + + (b - a).include?(@to) + end + + description do + "create a dependency onto #{expected.inspect}" + end + + failure_message do |_actual| + "expected dependency to be created onto #{expected.inspect}" + end + + failure_message_when_negated do |_actual| + "expected no dependency to be created onto #{expected.inspect}" + end +end + +RSpec::Matchers.define :create_dependency_from do |expected| + supports_block_expectations + + include RSpec::Matchers::Composable + + match do |actual| + @from = expected + dependency_tracker = @from._context.dependency_tracker + dependency_store = dependency_tracker.dependency_store + + a = dependency_store.objects_causing_outdatedness_of(@from) + + begin + dependency_tracker.enter(@from._unwrap) + actual.call + ensure + dependency_tracker.exit + end + + b = dependency_store.objects_causing_outdatedness_of(@from) + + @actual = b - a + + if @onto + values_match?(@onto, @actual) + else + @actual.any? + end + end + + chain :onto do |onto| + @onto = onto + end + + description do + "create a dependency from #{expected.inspect}" + end + + failure_message do |_actual| + "expected a dependency to be created from #{expected.inspect}#{@onto ? " onto #{@onto.inspect}" : nil}, but generated #{@actual.inspect}" + end + + failure_message_when_negated do |_actual| + "expected no dependency to be created from #{expected.inspect}, but generated #{@actual.inspect}" + end +end diff -Nru nanoc-4.11.0/common/spec/spec_helper_foot.rb nanoc-4.11.14/common/spec/spec_helper_foot.rb --- nanoc-4.11.0/common/spec/spec_helper_foot.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/common/spec/spec_helper_foot.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,168 +1,18 @@ # frozen_string_literal: true +require_relative 'spec_helper_foot_core' + Nanoc::CLI.setup RSpec.configure do |c| - c.include(Nanoc::Spec::Helper) - - c.include(Nanoc::Spec::HelperHelper, helper: true) - - c.fuubar_progress_bar_options = { - format: '%c/%C |<%b>%i| %p%%', - } - - c.around(:each) do |example| + c.around do |example| Nanoc::CLI::ErrorHandler.disable example.run Nanoc::CLI::ErrorHandler.enable end - c.around(:each) do |example| - should_chdir = - !example.metadata.key?(:chdir) || - example.metadata[:chdir] - - if should_chdir - Dir.mktmpdir('nanoc-test') do |dir| - chdir(dir) { example.run } - end - else - example.run - end - end - - c.before(:each) do - Nanoc::Int::NotificationCenter.reset - end - - c.around(:each, stdio: true) do |example| - orig_stdout = $stdout - orig_stderr = $stderr - - unless ENV['QUIET'] == 'false' - $stdout = StringIO.new - $stderr = StringIO.new - end - - example.run - - $stdout = orig_stdout - $stderr = orig_stderr - end - - c.before(:each, site: true) do - FileUtils.mkdir_p('content') - FileUtils.mkdir_p('layouts') - FileUtils.mkdir_p('lib') - FileUtils.mkdir_p('output') - - File.write('nanoc.yaml', '{}') - - File.write('Rules', 'passthrough "/**/*"') - end - c.before(:each, fork: true) do - skip 'fork() is not supported on Windows' if Nanoc.on_windows? - end -end - -RSpec::Matchers.define_negated_matcher :not_match, :match - -RSpec::Matchers.define :raise_frozen_error do |_expected| - match do |actual| - begin - actual.call - false - rescue => e - if e.is_a?(RuntimeError) || e.is_a?(TypeError) - e.message =~ /(^can't modify frozen |^unable to modify frozen object$)/ - else - false - end - end - end - - supports_block_expectations - - failure_message do |_actual| - 'expected that proc would raise a frozen error' - end - - failure_message_when_negated do |_actual| - 'expected that proc would not raise a frozen error' - end -end - -RSpec::Matchers.define :be_humanly_sorted do - match do |actual| - actual == sort(actual) - end - - description do - 'be humanly sorted' - end - - failure_message do |actual| - expected_order = [] - actual.zip(sort(actual)).each do |a, b| - if a != b - expected_order << b - end - end - - "expected collection to be sorted (incorrect order: #{expected_order.join(' < ')})" - end - - def sort(coll) - coll.sort_by do |elem| - elem.dup.unicode_normalize(:nfd).encode('ASCII', fallback: ->(_) { '' }).downcase - end - end -end - -RSpec::Matchers.define :finish_in_under do |expected| - supports_block_expectations - - match do |actual| - before = Time.now - actual.call - after = Time.now - @actual_duration = after - before - @actual_duration < expected - end - - chain :seconds do - end - - failure_message do |_actual| - "expected that proc would finish in under #{expected}s, but took #{format '%0.1fs', @actual_duration}" - end - - failure_message_when_negated do |_actual| - "expected that proc would not finish in under #{expected}s, but took #{format '%0.1fs', @actual_duration}" - end -end - -RSpec::Matchers.define :yield_from_fiber do |expected| - supports_block_expectations - - include RSpec::Matchers::Composable - - match do |actual| - @res = Fiber.new { actual.call }.resume - values_match?(expected, @res) - end - - description do - "yield #{expected.inspect} from fiber" - end - - failure_message do |_actual| - "expected that proc would yield #{expected.inspect} from fiber, but was #{@res.inspect}" - end - - failure_message_when_negated do |_actual| - "expected that proc would not yield #{expected.inspect} from fiber, but was #{@res.inspect}" + skip 'fork() is not supported on Windows' if Nanoc::Core.on_windows? end end @@ -174,7 +24,7 @@ match do |actual| begin actual.call - rescue Nanoc::Int::Errors::CompilationError => e + rescue Nanoc::Core::Errors::CompilationError => e values_match?(expected, e.unwrap) end end @@ -192,248 +42,5 @@ end end -RSpec::Matchers.define :be_some_textual_content do |expected| - include RSpec::Matchers::Composable - - match do |actual| - actual.is_a?(Nanoc::Int::TextualContent) && values_match?(expected, actual.string) - end - - description do - "textual content matching #{expected.inspect}" - end - - failure_message do |actual| - "expected #{actual.inspect} to be textual content matching #{expected.inspect}" - end - - failure_message_when_negated do |actual| - "expected #{actual.inspect} not to be textual content matching #{expected.inspect}" - end -end - -RSpec::Matchers.define :be_some_binary_content do |expected| - include RSpec::Matchers::Composable - - match do |actual| - actual.is_a?(Nanoc::Int::BinaryContent) && values_match?(expected, File.read(actual.filename)) - end - - description do - "binary content matching #{expected.inspect}" - end - - failure_message do |actual| - "expected #{actual.inspect} to be binary content matching #{expected.inspect}" - end - - failure_message_when_negated do |actual| - "expected #{actual.inspect} not to be binary content matching #{expected.inspect}" - end -end - RSpec::Matchers.alias_matcher :some_textual_content, :be_some_textual_content RSpec::Matchers.alias_matcher :some_binary_content, :be_some_binary_content - -RSpec::Matchers.define :send_notification do |name, *expected_args| - supports_block_expectations - - include RSpec::Matchers::Composable - - match do |actual| - @actual_notifications = [] - Nanoc::Int::NotificationCenter.on(name, self) do |*actual_args| - @actual_notifications << actual_args - end - actual.call - @actual_notifications.any? { |c| c == expected_args } - end - - description do - "send notification #{name.inspect} with args #{expected_args.inspect}" - end - - failure_message do |_actual| - s = "expected that proc would send notification #{name.inspect} with args #{expected_args.inspect}" - if @actual_notifications.any? - s << " (received #{@actual_notifications.size} times with other arguments: #{@actual_notifications.map(&:inspect).join(', ')})" - end - s - end - - failure_message_when_negated do |_actual| - "expected that proc would not send notification #{name.inspect} with args #{expected_args.inspect}" - end -end - -RSpec::Matchers.define :have_correct_yard_examples do |_name, *_expected_args| - chain :in_file do |file| - root_dir = File.expand_path(__dir__ + '/../..') - YARD.parse(root_dir + '/' + file) - end - - match do |actual| - examples = - P(actual).tags(:example).flat_map do |example| - # Classify - lines = example.text.lines.map do |line| - [/^\s*# ?=>/.match?(line) ? :result : :code, line] - end - - # Join - pieces = [] - lines.each do |line| - if !pieces.empty? && pieces.last.first == line.first - pieces.last.last << line.last - else - pieces << line - end - end - lines = pieces.map(&:last) - - # Collect - lines.each_slice(2).to_a - end - - b = binding - executed_examples = examples.map do |pair| - { - input: pair.first, - expected: eval(pair.last.match(/# ?=>(.*)/)[1], b), - actual: eval(pair.first, b), - } - end - - @failing_examples = executed_examples.reject { |ex| ex[:expected] == ex[:actual] } - - @failing_examples.empty? - end - - failure_message do |_actual| - parts = - @failing_examples.map do |ex| - format( - "%s\nexpected to be\n %s\nbut was\n %s", - ex[:input], - ex[:expected].inspect, - ex[:actual].inspect, - ) - end - - parts.join("\n\n---\n\n") - end -end - -RSpec::Matchers.define :create_dependency_on do |expected| - supports_block_expectations - - include RSpec::Matchers::Composable - - match do |actual| - @to = expected - dependency_tracker = @to._context.dependency_tracker - dependency_store = dependency_tracker.dependency_store - - from = Nanoc::Int::Item.new('x', {}, '/x.md') - - a = dependency_store.objects_causing_outdatedness_of(from) - - begin - dependency_tracker.enter(from) - actual.call - ensure - dependency_tracker.exit - end - - b = dependency_store.objects_causing_outdatedness_of(from) - - (b - a).include?(@to) - end - - description do - "create a dependency onto #{expected.inspect}" - end - - failure_message do |_actual| - "expected dependency to be created onto #{expected.inspect}" - end - - failure_message_when_negated do |_actual| - "expected no dependency to be created onto #{expected.inspect}" - end -end - -RSpec::Matchers.define :create_dependency_from do |expected| - supports_block_expectations - - include RSpec::Matchers::Composable - - match do |actual| - @from = expected - dependency_tracker = @from._context.dependency_tracker - dependency_store = dependency_tracker.dependency_store - - a = dependency_store.objects_causing_outdatedness_of(@from) - - begin - dependency_tracker.enter(@from._unwrap) - actual.call - ensure - dependency_tracker.exit - end - - b = dependency_store.objects_causing_outdatedness_of(@from) - - @actual = b - a - - if @onto - values_match?(@onto, @actual) - else - @actual.any? - end - end - - chain :onto do |onto| - @onto = onto - end - - description do - "create a dependency from #{expected.inspect}" - end - - failure_message do |_actual| - "expected a dependency to be created from #{expected.inspect}#{@onto ? " onto #{@onto.inspect}" : nil}, but generated #{@actual.inspect}" - end - - failure_message_when_negated do |_actual| - "expected no dependency to be created from #{expected.inspect}, but generated #{@actual.inspect}" - end -end - -RSpec::Matchers.define :have_a_valid_manifest do - match do |actual| - manifest_lines = File.readlines(actual + '.manifest').map(&:chomp).reject(&:empty?) - gemspec_lines = eval(File.read(actual + '.gemspec'), binding, actual + '.gemspec').files - - @missing_from_manifest = gemspec_lines - manifest_lines - @extra_in_manifest = manifest_lines - gemspec_lines - - @missing_from_manifest.empty? && @extra_in_manifest.empty? - end - - description do - 'have a valid manifest' - end - - failure_message do |_actual| - reasons = [] - if @missing_from_manifest.any? - reasons << "file(s) missing from manifest (#{@missing_from_manifest.join(', ')})" - end - if @extra_in_manifest.any? - reasons << "file(s) extra in manifest (#{@extra_in_manifest.join(', ')})" - end - - "expected manifest to be valid (problems: #{reasons.join(' and ')})" - end -end diff -Nru nanoc-4.11.0/common/spec/spec_helper_head_core.rb nanoc-4.11.14/common/spec/spec_helper_head_core.rb --- nanoc-4.11.0/common/spec/spec_helper_head_core.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/common/spec/spec_helper_head_core.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'simplecov' +SimpleCov.start + +require 'codecov' +if ENV['CI'] == 'true' + SimpleCov.formatter = SimpleCov::Formatter::Codecov +end + +require 'fuubar' +require 'rspec/its' +require 'timecop' +require 'tty-command' +require 'yard' diff -Nru nanoc-4.11.0/common/spec/spec_helper_head.rb nanoc-4.11.14/common/spec/spec_helper_head.rb --- nanoc-4.11.0/common/spec/spec_helper_head.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/common/spec/spec_helper_head.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,18 +1,6 @@ # frozen_string_literal: true -require 'simplecov' -SimpleCov.start - -require 'codecov' -if ENV['CI'] == 'true' - SimpleCov.formatter = SimpleCov::Formatter::Codecov -end - -require 'timecop' -require 'rspec/its' -require 'fuubar' -require 'yard' +require_relative 'spec_helper_head_core' require 'nanoc' -require 'nanoc/cli' -require 'nanoc/spec' +require 'nanoc/orig_cli' diff -Nru nanoc-4.11.0/debian/changelog nanoc-4.11.14/debian/changelog --- nanoc-4.11.0/debian/changelog 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/changelog 2021-01-28 12:49:05.000000000 +0000 @@ -1,3 +1,64 @@ +nanoc (4.11.14-4ubuntu1) hirsute; urgency=medium + + * d/p/skip-test-failing-in-ubuntu.patch: there is a test failing in the + Ubuntu autopkgtest env due to a proxy issue, and the IP address in use is + not easily predictable to be added manually (LP: #1913586). + + -- Lucas Kanashiro Thu, 28 Jan 2021 09:49:05 -0300 + +nanoc (4.11.14-4) unstable; urgency=medium + + * Skip nanoc-live tests failing on ipv6-only builders (Closes: #972701) + * Use the correct json shema gem as dependency for ruby-nanoc-core + + -- Cédric Boutillier Wed, 18 Nov 2020 14:26:19 +0100 + +nanoc (4.11.14-3) unstable; urgency=medium + + * Use asciidoc instead of asciidoc-base package name in dependencies + (Closes: #971653) + * Remove or reshuffle some dependencies between packages + * Rules doesn't require root + + -- Cédric Boutillier Tue, 13 Oct 2020 15:40:03 +0200 + +nanoc (4.11.14-2) unstable; urgency=medium + + * Make nanoc depend on ruby-nanoc-cli (Closes: #968056) + * Bump debhelper compatibility level to 13 + * Use secure URI in Homepage field. + + -- Cédric Boutillier Wed, 26 Aug 2020 16:21:09 +0200 + +nanoc (4.11.14-1) unstable; urgency=medium + + [ Utkarsh Gupta ] + * Add salsa-ci.yml + + [ Cédric Boutillier ] + * New upstream version 4.11.14 + * Use gem installation layout + * Refresh patches + * Create new ruby-nanoc-core and ruby-nanoc-cli binary packages + * Drop nanoc-doc package + * Skip failing tests + * Add upstream/metadata and .gitattributes + * Add README.md as doc for nanoc package + * Remove symlink for gemspec in debian/ + * remove old NEWS entry + * add tests for nanoc-live + * debian/patches: + + skip gem and manifest generation specs for nanoc-live + + Force external encoding to UTF-8 for live_recompiler_spec + + Add live command if ruby-nanoc-live installed + + [ Marc Dequènes (Duck) ] + * add ruby-nanoc-live + * Add missing Ruby interpreter dependency. + * Enable dependency checking + + -- Cédric Boutillier Mon, 27 Jul 2020 12:16:36 +0200 + nanoc (4.11.0-5) unstable; urgency=medium * Replace python-pygments by python3-pygments to ease removal of Python 2 @@ -184,7 +245,7 @@ * Imported Upstream version 4.2.3 * Depend on ruby-rouge >= 2 now it is in the archive and drop test modification for older version - + -- Cédric Boutillier Sun, 03 Jul 2016 18:50:55 +0200 nanoc (4.2.2-1) unstable; urgency=medium @@ -235,7 +296,7 @@ * Imported Upstream version 4.1.2 * Bump Standards-Version to 3.9.7 (no changes needed) - * Use https to fix insecure Vcs-* fields + * Use https to fix insecure Vcs-* fields * Use debhelper compatibility level 9 * Unapply deactivate_rubygems_in_tests.patch and no_bundler_no_loadpath_modif.patch, not needed anymore diff -Nru nanoc-4.11.0/debian/compat nanoc-4.11.14/debian/compat --- nanoc-4.11.0/debian/compat 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -10 diff -Nru nanoc-4.11.0/debian/control nanoc-4.11.14/debian/control --- nanoc-4.11.0/debian/control 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/control 2021-01-28 12:49:05.000000000 +0000 @@ -1,13 +1,15 @@ Source: nanoc +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Debian Ruby Extras Maintainers +Uploaders: Cédric Boutillier Section: web +Testsuite: autopkgtest-pkg-ruby Priority: optional -Maintainer: Debian Ruby Extras Maintainers -Uploaders: Cédric Boutillier -Build-Depends: asciidoc-base, +Build-Depends: asciidoc, asciidoctor, coderay, - debhelper (>= 10~), - gem2deb, + debhelper-compat (= 13), + gem2deb (>= 1.2.1~), git, highlight, pry, @@ -15,10 +17,10 @@ rake, rsync, ruby-addressable (>= 2.5~), - ruby-adsf, + ruby-adsf (>= 1.4~), + ruby-adsf-live, ruby-builder, ruby-coffee-script, - ruby-colored, ruby-contracts, ruby-coveralls, ruby-cri (>= 2.15~), @@ -33,7 +35,7 @@ ruby-hamster, ruby-brandur-json-schema, ruby-kramdown, - ruby-listen, + ruby-listen (>= 3~), ruby-maruku, ruby-mime-types, ruby-minitest, @@ -41,7 +43,7 @@ ruby-mustache, ruby-nokogiri, ruby-nokogumbo, - ruby-parallel (>= 1.12~), + ruby-parallel, ruby-pygments.rb, ruby-rack, ruby-rdiscount, @@ -52,43 +54,38 @@ ruby-rspec, ruby-rspec-its, ruby-rubypants, - ruby-sass (>= 3.2.2~), + ruby-sass, ruby-slim, ruby-slow-enumerator-tools, ruby-timecop, - ruby-tomlrb (>= 1.2~), + ruby-tomlrb, + ruby-tty-command, + ruby-tty-platform, + ruby-tty-which, ruby-uglifier, + ruby-zeitwerk, yard -Standards-Version: 4.2.1 -Vcs-Git: https://salsa.debian.org/ruby-team/nanoc.git +Standards-Version: 4.5.0 Vcs-Browser: https://salsa.debian.org/ruby-team/nanoc -Homepage: http://nanoc.ws -Testsuite: autopkgtest-pkg-ruby +Vcs-Git: https://salsa.debian.org/ruby-team/nanoc.git +Homepage: https://nanoc.ws XS-Ruby-Versions: all +Rules-Requires-Root: no Package: nanoc -X-DhRuby-Root: nanoc Architecture: all -XB-Ruby-Versions: ${ruby:Versions} -Depends: pry, - ruby | ruby-interpreter, +Depends: ruby | ruby-interpreter, + ruby-nanoc-core (= ${source:Version}), + ruby-nanoc-cli (= ${source:Version}), ruby-addressable (>= 2.5~), ruby-adsf (>= 1.3~), ruby-colored, - ruby-cri (>= 2.15~), - ruby-ddmetrics, - ruby-ddmemoize, - ruby-ddplugin, - ruby-brandur-json-schema, - ruby-hamster, ruby-listen, - ruby-parallel (>= 1.12~), - ruby-ref, - ruby-slow-enumerator-tools, - ruby-tomlrb (>= 1.2~), + ruby-parallel, + ruby-tty-command, + ruby-tty-which, ${misc:Depends}, - ${shlibs:Depends} -Recommends: asciidoc-base, +Recommends: asciidoc, asciidoctor, ruby-builder, ruby-coffee-script, @@ -106,13 +103,13 @@ ruby-redcloth, ruby-rouge (>= 2~), ruby-rubypants, - ruby-sass (>= 3.2.2~), + ruby-sass, ruby-slim, ruby-uglifier Suggests: coderay | ruby-pygments.rb | python3-pygments | highlight, git, rsync, - ruby-fog-core (>= 0.13.0~), + ruby-fog-core, ruby-rack Description: static site generator written in Ruby Nanoc is a static site generator, fit for building anything from a small @@ -127,26 +124,64 @@ . Some knowledge of the Ruby programming language is required in order to use Nanoc. +XB-Ruby-Versions: ${ruby:Versions} +X-DhRuby-Root: nanoc -Package: nanoc-doc +Package: ruby-nanoc-core Architecture: all -Section: doc -Depends: libjs-jquery, - ${misc:Depends} -Multi-Arch: foreign -Suggests: doc-base -Description: static site generator written in Ruby - documentation +Depends: ruby-ddmemoize, + ruby-ddmetrics, + ruby-ddplugin, + ruby-hamster, + ruby-brandur-json-schema, + ruby-slow-enumerator-tools, + ruby-tomlrb, + ruby-tty-platform, + ruby-zeitwerk, + ${misc:Depends}, +Description: static site generator written in Ruby - core package Nanoc is a static site generator, fit for building anything from a small personal blog to a large corporate web site. It can transform content from one format (e.g. Haml or Markdown) into another (usually HTML) and lay out pages so that the site's look and feel is consistent across all pages. . - Extending Nanoc is easy because of its modular architecture. It comes - with only a couple of extensions, but allows new functionality to be - plugged in quickly and easily. + This package contains the core of Nanoc. +Section: ruby +X-DhRuby-Root: nanoc-core + +Package: ruby-nanoc-cli +Architecture: all +Depends: ruby-cri (>= 2.15~), + ruby-diff-lcs (>= 1.3~), + ruby-nanoc-core (= ${source:Version}), + ruby-zeitwerk, + ${misc:Depends}, +Description: static site generator written in Ruby - command line interface + Nanoc is a static site generator, fit for building anything from a small + personal blog to a large corporate web site. It can transform content + from one format (e.g. Haml or Markdown) into another (usually HTML) and + lay out pages so that the site's look and feel is consistent across all + pages. . - Some knowledge of the Ruby programming language is required in order to use - Nanoc. + This package contains the command line interface for Nanoc. +Section: ruby +X-DhRuby-Root: nanoc-cli + +Package: ruby-nanoc-live +Architecture: all +Depends: ruby-adsf-live (>= 1.4~), + ruby-cri (>= 2.13~), + ruby-listen (>= 3~), + ruby-nanoc-core (= ${source:Version}), + ${misc:Depends}, +Description: static site generator written in Ruby - live support + Nanoc is a static site generator, fit for building anything from a small + personal blog to a large corporate web site. It can transform content + from one format (e.g. Haml or Markdown) into another (usually HTML) and + lay out pages so that the site's look and feel is consistent across all + pages. . - This package contains the documentation for Nanoc. + This package contains the live support for Nanoc. +Section: ruby +X-DhRuby-Root: nanoc-live diff -Nru nanoc-4.11.0/debian/gbp.conf nanoc-4.11.14/debian/gbp.conf --- nanoc-4.11.0/debian/gbp.conf 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -[DEFAULT] -debian-branch = unstable/952038 -upstream-tag = %(version)s -debian-tag = debian/%(version)s diff -Nru nanoc-4.11.0/debian/gemspec nanoc-4.11.14/debian/gemspec --- nanoc-4.11.0/debian/gemspec 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/debian/gemspec 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -require_relative 'lib/nanoc/version' - -Gem::Specification.new do |s| - s.name = 'nanoc' - s.version = Nanoc::VERSION - s.homepage = 'http://nanoc.ws/' - s.summary = 'A static-site generator with a focus on flexibility.' - s.description = 'Nanoc is a static-site generator focused on flexibility. It transforms content from a format such as Markdown or AsciiDoc into another format, usually HTML, and lays out pages consistently to retain the site’s look and feel throughout. Static sites built with Nanoc can be deployed to any web server.' - - s.author = 'Denis Defreyne' - s.email = 'denis+rubygems@denis.ws' - s.license = 'MIT' - - s.files = Dir['*.md'] + ['LICENSE'] + Dir['bin/*'] + Dir['lib/**/*.rb'] + Dir['lib/**/*-schema.json'] - s.executables = ['nanoc'] - s.require_paths = ['lib'] - - s.required_ruby_version = '~> 2.4' - - s.add_runtime_dependency('addressable', '~> 2.5') - s.add_runtime_dependency('cri', '~> 2.15') - s.add_runtime_dependency('ddmemoize', '~> 1.0') - s.add_runtime_dependency('ddmetrics', '~> 1.0') - s.add_runtime_dependency('ddplugin', '~> 1.0') - s.add_runtime_dependency('hamster', '~> 3.0') - s.add_runtime_dependency('json_schema', '~> 0.19') - s.add_runtime_dependency('parallel', '~> 1.12') - s.add_runtime_dependency('ref', '~> 2.0') - s.add_runtime_dependency('slow_enumerator_tools', '~> 1.0') - s.add_runtime_dependency('tomlrb', '~> 1.2') -end diff -Nru nanoc-4.11.0/debian/nanoc.docs nanoc-4.11.14/debian/nanoc.docs --- nanoc-4.11.0/debian/nanoc.docs 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/debian/nanoc.docs 2021-01-27 22:00:50.000000000 +0000 @@ -0,0 +1 @@ +nanoc/README.md diff -Nru nanoc-4.11.0/debian/NEWS.Debian nanoc-4.11.14/debian/NEWS.Debian --- nanoc-4.11.0/debian/NEWS.Debian 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/NEWS.Debian 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -nanoc (4.1.2-1~exp1) experimental; urgency=medium - - The version 4 of Nanoc is not backward compatible with Nanoc 3. - In particular, Nanoc 4 brings identifiers with extensions for pages, and - introduces glob patterns to simplify the creation of rules. - - For an upgrade guide from Nanoc 3 to Nano 4, please consult the dedicated - upstream documentation, available at: - - http://nanoc.ws/doc/nanoc-4-upgrade-guide/ - - -- Cédric Boutillier Sat, 20 Feb 2016 22:06:38 +0100 diff -Nru nanoc-4.11.0/debian/patches/add-live-command.patch nanoc-4.11.14/debian/patches/add-live-command.patch --- nanoc-4.11.0/debian/patches/add-live-command.patch 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/debian/patches/add-live-command.patch 2021-01-27 22:00:50.000000000 +0000 @@ -0,0 +1,20 @@ +Description: try to load nanoc-live if installed + This enables the `live` option from the nanoc cli command +Author: Cédric Boutillier +Last-Update: 2020-07-27 +Forwarded: no + +--- a/nanoc/bin/nanoc ++++ b/nanoc/bin/nanoc +@@ -9,6 +9,11 @@ + rescue LoadError + end + ++begin ++ require 'nanoc-live' ++rescue LoadError ++end ++ + require 'nanoc/orig_cli' + + if File.file?('Gemfile') && !defined?(Bundler) diff -Nru nanoc-4.11.0/debian/patches/add_require_colored.patch nanoc-4.11.14/debian/patches/add_require_colored.patch --- nanoc-4.11.0/debian/patches/add_require_colored.patch 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/add_require_colored.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ ---- a/nanoc/lib/nanoc/checking/runner.rb -+++ b/nanoc/lib/nanoc/checking/runner.rb -@@ -1,5 +1,7 @@ - # frozen_string_literal: true - -+require "colored" -+ - module Nanoc::Checking - # Runner is reponsible for running issue checks. - # diff -Nru nanoc-4.11.0/debian/patches/encoding.patch nanoc-4.11.14/debian/patches/encoding.patch --- nanoc-4.11.0/debian/patches/encoding.patch 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/encoding.patch 2021-01-27 22:00:50.000000000 +0000 @@ -1,14 +1,14 @@ Description: force encoding to UTF-8 to fix test in clean environment Author: Cédric Boutillier -Last-Update: 2018-11-06 +Last-Update: 2020-07-27 Forwarded: not-needed ---- a/nanoc/test/cli/commands/test_create_site.rb -+++ b/nanoc/test/cli/commands/test_create_site.rb +--- a/nanoc/test/orig_cli/commands/test_create_site.rb ++++ b/nanoc/test/orig_cli/commands/test_create_site.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true -+Encoding.default_external="UTF-8" if defined? Encoding ++Encoding.default_external = "UTF-8" + require 'helper' @@ -18,34 +18,28 @@ @@ -1,5 +1,7 @@ # frozen_string_literal: true -+Encoding.default_external="UTF-8" if defined? Encoding ++Encoding.default_external = "UTF-8" + describe 'list of contributors in README', chdir: false do let(:contributors_in_readme) do File.readlines('../README.md').last.chomp("\n").split(', ') ---- a/nanoc/spec/nanoc/cli/commands/shell_spec.rb -+++ b/nanoc/spec/nanoc/cli/commands/shell_spec.rb +--- a/nanoc-cli/spec/nanoc/cli/commands/shell_spec.rb ++++ b/nanoc-cli/spec/nanoc/cli/commands/shell_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true -+Encoding.default_external="UTF-8" if defined? Encoding ++Encoding.default_external = "UTF-8" + describe Nanoc::CLI::Commands::Shell, site: true, stdio: true do describe '#run' do before do ---- a/common/spec/spec_helper_head.rb -+++ b/common/spec/spec_helper_head.rb -@@ -1,13 +1,5 @@ +--- a/nanoc-live/spec/nanoc/live/live_recompiler_spec.rb ++++ b/nanoc-live/spec/nanoc/live/live_recompiler_spec.rb +@@ -1,5 +1,7 @@ # frozen_string_literal: true --require 'simplecov' --SimpleCov.start -- --require 'codecov' --if ENV['CI'] == 'true' -- SimpleCov.formatter = SimpleCov::Formatter::Codecov --end -- - require 'timecop' - require 'rspec/its' - require 'fuubar' ++Encoding.default_external = "UTF-8" ++ + describe Nanoc::Live::LiveRecompiler, site: true, stdio: true, fork: true do + before do + Nanoc::CLI::ErrorHandler.enable diff -Nru nanoc-4.11.0/debian/patches/failing-tests-ipv6-only.patch nanoc-4.11.14/debian/patches/failing-tests-ipv6-only.patch --- nanoc-4.11.0/debian/patches/failing-tests-ipv6-only.patch 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/debian/patches/failing-tests-ipv6-only.patch 2021-01-27 22:00:50.000000000 +0000 @@ -0,0 +1,35 @@ +Description: skip tests failing on ipv6-only builders +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=972701 +Forwarded: no +Author: Cédric Boutillier +Last-Update: 2020-11-18 + +--- a/nanoc-live/spec/nanoc/live/commands/live_spec.rb ++++ b/nanoc-live/spec/nanoc/live/commands/live_spec.rb +@@ -31,7 +31,7 @@ + end + end + +- it 'watches' do ++ xit 'watches' do + run_cmd do + File.write('content/lol.html', 'hej') + sleep_until { File.file?('output/lol.html') } +@@ -43,7 +43,7 @@ + end + end + +- it 'listens' do ++ xit 'listens' do + run_cmd do + File.write('content/lol.html', 'hej') + sleep_until { File.file?('output/lol.html') } +@@ -55,7 +55,7 @@ + end + end + +- it 'listens for websocket connections' do ++ xit 'listens for websocket connections' do + run_cmd do + socket = TCPSocket.new('localhost', 35_729) + expect(socket).not_to be_closed diff -Nru nanoc-4.11.0/debian/patches/filter_out_nil_gemspec.patch nanoc-4.11.14/debian/patches/filter_out_nil_gemspec.patch --- nanoc-4.11.0/debian/patches/filter_out_nil_gemspec.patch 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/filter_out_nil_gemspec.patch 2021-01-27 22:00:50.000000000 +0000 @@ -6,8 +6,8 @@ Forwarded: not-needed Last-Update: 2017-10-17 ---- a/nanoc/lib/nanoc/cli/error_handler.rb -+++ b/nanoc/lib/nanoc/cli/error_handler.rb +--- a/nanoc-cli/lib/nanoc/cli/error_handler.rb ++++ b/nanoc-cli/lib/nanoc/cli/error_handler.rb @@ -170,7 +170,7 @@ # @return [Hash] A hash containing the gem names as keys and gem versions as value def gems_and_versions diff -Nru nanoc-4.11.0/debian/patches/missing_pathname_require.patch nanoc-4.11.14/debian/patches/missing_pathname_require.patch --- nanoc-4.11.0/debian/patches/missing_pathname_require.patch 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/debian/patches/missing_pathname_require.patch 2021-01-27 22:00:50.000000000 +0000 @@ -0,0 +1,14 @@ +Description: missign requirement on pathname lib +Author: Cédric Boutillier +Last-Update: 2020-04-12 + +--- a/nanoc-core/lib/nanoc/core/pruner.rb ++++ b/nanoc-core/lib/nanoc/core/pruner.rb +@@ -1,5 +1,7 @@ + # frozen_string_literal: true + ++require "pathname" ++ + module Nanoc + module Core + # Responsible for finding and deleting files in the site’s output directory diff -Nru nanoc-4.11.0/debian/patches/nanoc-live_missing_loader.patch nanoc-4.11.14/debian/patches/nanoc-live_missing_loader.patch --- nanoc-4.11.0/debian/patches/nanoc-live_missing_loader.patch 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/debian/patches/nanoc-live_missing_loader.patch 2021-01-27 22:00:50.000000000 +0000 @@ -0,0 +1,16 @@ +--- /dev/null ++++ b/nanoc-live/lib/nanoc-live.rb +@@ -0,0 +1,3 @@ ++# frozen_string_literal: true ++ ++require_relative 'nanoc/live' +--- a/nanoc-live/nanoc-live.manifest ++++ b/nanoc-live/nanoc-live.manifest +@@ -1,6 +1,7 @@ + NEWS.md + README.md + ++lib/nanoc-live.rb + lib/nanoc/live.rb + lib/nanoc/live/commands/live.rb + lib/nanoc/live/live_recompiler.rb diff -Nru nanoc-4.11.0/debian/patches/no_privacy_breach.patch nanoc-4.11.14/debian/patches/no_privacy_breach.patch --- nanoc-4.11.0/debian/patches/no_privacy_breach.patch 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/no_privacy_breach.patch 2021-01-27 22:00:50.000000000 +0000 @@ -13,7 +13,7 @@ @@ -1,12 +1,3 @@ -[![Gem version](https://img.shields.io/gem/v/nanoc.svg)](http://rubygems.org/gems/nanoc) -[![Gem downloads](https://img.shields.io/gem/dt/nanoc.svg)](http://rubygems.org/gems/nanoc) --[![Build status](https://img.shields.io/travis/nanoc/nanoc.svg)](https://travis-ci.org/nanoc/nanoc) +-[![Build status](https://img.shields.io/circleci/project/github/nanoc/nanoc/master.svg)](https://circleci.com/gh/nanoc/workflows/nanoc) -[![Code Climate](https://img.shields.io/codeclimate/maintainability/nanoc/nanoc.svg)](https://codeclimate.com/github/nanoc/nanoc) -[![Code Coverage](https://img.shields.io/codecov/c/github/nanoc/nanoc.svg)](https://codecov.io/gh/nanoc/nanoc) -![Contributors](https://img.shields.io/github/contributors/nanoc/nanoc.svg) @@ -22,4 +22,4 @@ - # Nanoc - Nanoc is a flexible static-site generator written in Ruby. See the [Nanoc web site](http://nanoc.ws) for more information. + Nanoc is a flexible static-site generator written in Ruby. See the [Nanoc web site](https://nanoc.ws) for more information. diff -Nru nanoc-4.11.0/debian/patches/no_simplecov.patch nanoc-4.11.14/debian/patches/no_simplecov.patch --- nanoc-4.11.0/debian/patches/no_simplecov.patch 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/no_simplecov.patch 2021-01-27 22:00:50.000000000 +0000 @@ -18,3 +18,25 @@ require 'minitest/autorun' require 'mocha/setup' +--- a/common/spec/spec_helper_head_core.rb ++++ b/common/spec/spec_helper_head_core.rb +@@ -1,12 +1,12 @@ + # frozen_string_literal: true + +-require 'simplecov' +-SimpleCov.start +- +-require 'codecov' +-if ENV['CI'] == 'true' +- SimpleCov.formatter = SimpleCov::Formatter::Codecov +-end ++#require 'simplecov' ++#SimpleCov.start ++# ++#require 'codecov' ++#if ENV['CI'] == 'true' ++# SimpleCov.formatter = SimpleCov::Formatter::Codecov ++#end + + require 'fuubar' + require 'rspec/its' diff -Nru nanoc-4.11.0/debian/patches/no_vcr.patch nanoc-4.11.14/debian/patches/no_vcr.patch --- nanoc-4.11.0/debian/patches/no_vcr.patch 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/no_vcr.patch 2021-01-27 22:00:50.000000000 +0000 @@ -24,7 +24,7 @@ -end - require 'nanoc' - require 'nanoc/cli' + require 'nanoc/orig_cli' --- a/nanoc/test/checking/checks/test_css.rb +++ b/nanoc/test/checking/checks/test_css.rb diff -Nru nanoc-4.11.0/debian/patches/rspec_ambiguous_metadata.patch nanoc-4.11.14/debian/patches/rspec_ambiguous_metadata.patch --- nanoc-4.11.0/debian/patches/rspec_ambiguous_metadata.patch 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/rspec_ambiguous_metadata.patch 2021-01-27 22:00:50.000000000 +0000 @@ -5,7 +5,7 @@ --- a/nanoc/spec/nanoc/data_sources/filesystem_spec.rb +++ b/nanoc/spec/nanoc/data_sources/filesystem_spec.rb -@@ -121,7 +121,7 @@ +@@ -122,7 +122,7 @@ File.write('foo/a.yaml', 'title: Aaah') end @@ -14,7 +14,7 @@ expect { subject } .to raise_error( Nanoc::Int::Errors::AmbiguousMetadataAssociation, -@@ -165,7 +165,7 @@ +@@ -166,7 +166,7 @@ File.write('foo/a.yaml', 'title: Aaah') end diff -Nru nanoc-4.11.0/debian/patches/rspec_nanoc_cli.patch nanoc-4.11.14/debian/patches/rspec_nanoc_cli.patch --- nanoc-4.11.0/debian/patches/rspec_nanoc_cli.patch 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/rspec_nanoc_cli.patch 2021-01-27 22:00:50.000000000 +0000 @@ -2,9 +2,9 @@ Author: Cédric Boutillier Last-Update: 2018-12-10 ---- a/nanoc/spec/nanoc/cli/commands/compile_spec.rb -+++ b/nanoc/spec/nanoc/cli/commands/compile_spec.rb -@@ -43,7 +43,7 @@ +--- a/nanoc-cli/spec/nanoc/cli/commands/compile_spec.rb ++++ b/nanoc-cli/spec/nanoc/cli/commands/compile_spec.rb +@@ -56,7 +56,7 @@ end describe '--watch', fork: true do @@ -13,8 +13,8 @@ pipe_stdout_read, pipe_stdout_write = IO.pipe pid = fork do trap(:INT) { exit(0) } ---- a/nanoc/spec/nanoc/cli/error_handler_spec.rb -+++ b/nanoc/spec/nanoc/cli/error_handler_spec.rb +--- a/nanoc-cli/spec/nanoc/cli/error_handler_spec.rb ++++ b/nanoc-cli/spec/nanoc/cli/error_handler_spec.rb @@ -142,7 +142,7 @@ end end diff -Nru nanoc-4.11.0/debian/patches/rspec_readme_gem_manifest.patch nanoc-4.11.14/debian/patches/rspec_readme_gem_manifest.patch --- nanoc-4.11.0/debian/patches/rspec_readme_gem_manifest.patch 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/rspec_readme_gem_manifest.patch 2021-01-27 22:00:50.000000000 +0000 @@ -8,21 +8,21 @@ File.read('NEWS.md').scan(/\[[^\]]+\]$/).map { |s| s[1..-2].split(', ') }.flatten end -- it 'should include everyone mentioned in NEWS.md' do -+ xit 'should include everyone mentioned in NEWS.md' do +- it 'includes everyone mentioned in NEWS.md' do ++ xit 'includes everyone mentioned in NEWS.md' do diff = (contributors_in_release_notes - contributors_in_readme).uniq.sort expect(diff).to be_empty, "some contributors are missing from the README: #{diff.join(', ')}" end -- it 'should be sorted' do -+ xit 'should be sorted' do +- it 'is sorted' do ++ xit 'is sorted' do expect(contributors_in_readme).to be_humanly_sorted end end --- a/nanoc/spec/gem_spec.rb +++ b/nanoc/spec/gem_spec.rb -@@ -12,7 +12,7 @@ - piper.run(%w[gem build nanoc.gemspec], nil) +@@ -11,7 +11,7 @@ + Dir['*.gem'].each { |f| FileUtils.rm(f) } end - it 'builds gem' do diff -Nru nanoc-4.11.0/debian/patches/safe_level_erb.patch nanoc-4.11.14/debian/patches/safe_level_erb.patch --- nanoc-4.11.0/debian/patches/safe_level_erb.patch 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/safe_level_erb.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -Description: skip tests relying on SAFE level in ruby2.7 - this mechanism is dropped in ruby2.7 -Author: Cédric Boutillier -Last-Update: 2020-03-12 - ---- a/nanoc/spec/nanoc/filters/erb_spec.rb -+++ b/nanoc/spec/nanoc/filters/erb_spec.rb -@@ -163,5 +163,5 @@ - expect { subject }.to raise_error(SecurityError) - end - end -- end -+ end unless /ruby2\.7/ =~ RbConfig.ruby - end diff -Nru nanoc-4.11.0/debian/patches/series nanoc-4.11.14/debian/patches/series --- nanoc-4.11.0/debian/patches/series 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/series 2021-01-28 12:42:28.000000000 +0000 @@ -1,7 +1,5 @@ #deactivate_test_huge_site.patch no_privacy_breach.patch -skip_checksummer_tests_27.patch -safe_level_erb.patch no_vcr.patch #set-load_paths-for-sass-tests.patch filter_out_nil_gemspec.patch @@ -9,10 +7,14 @@ encoding.patch #skip_tests_autopkgtest.patch no_simplecov.patch -fix_892195.patch -skip-network-test.patch +#fix_892195.patch +#skip-network-test.patch rspec_readme_gem_manifest.patch rspec_ambiguous_metadata.patch rspec_nanoc_cli.patch -skip_failing_tests.patch -add_require_colored.patch +missing_pathname_require.patch +skip-failing-tests.patch +nanoc-live_missing_loader.patch +add-live-command.patch +failing-tests-ipv6-only.patch +skip-test-failing-in-ubuntu.patch diff -Nru nanoc-4.11.0/debian/patches/skip_checksummer_tests_27.patch nanoc-4.11.14/debian/patches/skip_checksummer_tests_27.patch --- nanoc-4.11.0/debian/patches/skip_checksummer_tests_27.patch 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/skip_checksummer_tests_27.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -Description: tests failing with ruby2.7 -Author: Cédric Boutillier -Last-Update: 2020-03-12 - ---- a/nanoc/spec/nanoc/base/checksummer_spec.rb -+++ b/nanoc/spec/nanoc/base/checksummer_spec.rb -@@ -84,7 +84,7 @@ - - context 'non-serializable' do - let(:obj) { [-> {}] } -- it { is_expected.to match(/\AArray>,>\z/) } -+ xit { is_expected.to match(/\AArray>,>\z/) } - end - end - -@@ -99,7 +99,7 @@ - - context 'non-serializable' do - let(:obj) { { 'a' => -> {} } } -- it { is_expected.to match(/\AHash=Proc<#>,>\z/) } -+ xit { is_expected.to match(/\AHash=Proc<#>,>\z/) } - end - - context 'recursive values' do -@@ -414,6 +414,6 @@ - - context 'other non-marshal-able classes' do - let(:obj) { proc {} } -- it { is_expected.to match(/\AProc<#>\z/) } -+ xit { is_expected.to match(/\AProc<#>\z/) } - end - end diff -Nru nanoc-4.11.0/debian/patches/skip_failing_tests.patch nanoc-4.11.14/debian/patches/skip_failing_tests.patch --- nanoc-4.11.0/debian/patches/skip_failing_tests.patch 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/skip_failing_tests.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -Description: skip tests failing with newer rouge gem - TO BE DROPPED after update -Last-Update: 2020-03-12 -Author: Cédric Boutillier - ---- a/nanoc/spec/nanoc/filters/colorize_syntax/rouge_spec.rb -+++ b/nanoc/spec/nanoc/filters/colorize_syntax/rouge_spec.rb -@@ -69,7 +69,7 @@ - EOS - end - -- it { is_expected.to eql output } -+ xit { is_expected.to eql output } - end - end - -@@ -148,7 +148,7 @@ - EOS - end - -- it { is_expected.to eql output } -+ xit { is_expected.to eql output } - end - end - end diff -Nru nanoc-4.11.0/debian/patches/skip-failing-tests.patch nanoc-4.11.14/debian/patches/skip-failing-tests.patch --- nanoc-4.11.0/debian/patches/skip-failing-tests.patch 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/debian/patches/skip-failing-tests.patch 2021-01-27 22:00:50.000000000 +0000 @@ -0,0 +1,205 @@ +Description: skip failing tests for now +Author: Cédric Boutillier +Last-Update: 2020-04-07 + +--- a/nanoc/test/filters/test_erubi.rb ++++ b/nanoc/test/filters/test_erubi.rb +@@ -21,7 +21,7 @@ + assert_equal('I was hiding in a cheap motel.', result) + end + +- def test_filter_syntax_error ++ def _test_filter_syntax_error + # Create filter + item = Nanoc::Core::Item.new('asdf', {}, '/about.md') + item_rep = Nanoc::Core::ItemRep.new(item, :xml) +--- a/nanoc/spec/nanoc/filters/erb_spec.rb ++++ b/nanoc/spec/nanoc/filters/erb_spec.rb +@@ -156,12 +156,13 @@ + end + end + +- context 'safe level set' do +- let(:params) { { safe_level: 1 } } ++ #Debian: safe levels are noop in ruby2.7 ++ #context 'safe level set' do ++ # let(:params) { { safe_level: 1 } } + +- it 'honors safe level' do +- expect { subject }.to raise_error(SecurityError) +- end +- end ++ # it 'honors safe level' do ++ # expect { subject }.to raise_error(SecurityError) ++ # end ++ #end + end + end +--- a/nanoc-core/spec/nanoc/core/checksummer_spec.rb ++++ b/nanoc-core/spec/nanoc/core/checksummer_spec.rb +@@ -93,7 +93,7 @@ + context 'non-serializable' do + let(:obj) { [-> {}] } + +- it { is_expected.to match(/\AArray>,>\z/) } ++ xit { is_expected.to match(/\AArray>,>\z/) } + end + end + +@@ -111,7 +111,7 @@ + context 'non-serializable' do + let(:obj) { { 'a' => -> {} } } + +- it { is_expected.to match(/\AHash=Proc<#>,>\z/) } ++ xit { is_expected.to match(/\AHash=Proc<#>,>\z/) } + end + + context 'recursive values' do +@@ -371,6 +371,6 @@ + context 'other non-marshal-able classes' do + let(:obj) { proc {} } + +- it { is_expected.to match(/\AProc<#>\z/) } ++ xit { is_expected.to match(/\AProc<#>\z/) } + end + end +--- a/nanoc-core/spec/manifest_spec.rb ++++ b/nanoc-core/spec/manifest_spec.rb +@@ -1,7 +1,7 @@ + # frozen_string_literal: true + +-describe 'manifest', chdir: false do +- example do +- expect('nanoc-core').to have_a_valid_manifest +- end +-end ++#describe 'manifest', chdir: false do ++# example do ++# expect('nanoc-core').to have_a_valid_manifest ++# end ++#end +--- a/nanoc-cli/spec/gem_spec.rb ++++ b/nanoc-cli/spec/gem_spec.rb +@@ -11,7 +11,7 @@ + Dir['*.gem'].each { |f| FileUtils.rm(f) } + end + +- it 'builds gem' do ++ xit 'builds gem' do + expect { subject } + .to change { Dir['*.gem'] } + .from([]) +--- a/nanoc-cli/spec/manifest_spec.rb ++++ b/nanoc-cli/spec/manifest_spec.rb +@@ -1,7 +1,7 @@ + # frozen_string_literal: true + +-describe 'manifest', chdir: false do +- example do +- expect('nanoc-cli').to have_a_valid_manifest +- end +-end ++#describe 'manifest', chdir: false do ++# example do ++# expect('nanoc-cli').to have_a_valid_manifest ++# end ++#end +--- a/nanoc-cli/spec/nanoc/cli/commands/view_spec.rb ++++ b/nanoc-cli/spec/nanoc/cli/commands/view_spec.rb +@@ -61,7 +61,7 @@ + end + end + +- it 'does not crash when output dir does not exist and --live-reload is given' do ++ xit 'does not crash when output dir does not exist and --live-reload is given' do + FileUtils.rm_rf('output') + run_nanoc_cmd(['view', '--port', '50385', '--live-reload']) do + expect(Net::HTTP.get('127.0.0.1', '/', 50_385)).to eql("File not found: /\n") +--- a/nanoc-core/spec/nanoc/core/feature_spec.rb ++++ b/nanoc-core/spec/nanoc/core/feature_spec.rb +@@ -79,24 +79,24 @@ + end + end + +- describe '.all_outdated' do +- it 'refuses outdated features' do +- # If this spec fails, there are features marked as experimental in the previous minor or major +- # release, but not in the current one. Either remove the feature, or mark it as experimental +- # in the current release. +- expect(described_class.all_outdated).to be_empty +- end ++ #describe '.all_outdated' do ++ # it 'refuses outdated features' do ++ # # If this spec fails, there are features marked as experimental in the previous minor or major ++ # # release, but not in the current one. Either remove the feature, or mark it as experimental ++ # # in the current release. ++ # expect(described_class.all_outdated).to be_empty ++ # end + +- describe 'fake outdated features' do +- before { described_class.define('abc', version: '4.2.x') } ++ # describe 'fake outdated features' do ++ # before { described_class.define('abc', version: '4.2.x') } + +- after { described_class.undefine('abc') } ++ # after { described_class.undefine('abc') } + +- it 'detects outdated features' do +- expect(described_class.all_outdated).to eq(['abc']) +- end +- end +- end ++ # it 'detects outdated features' do ++ # expect(described_class.all_outdated).to eq(['abc']) ++ # end ++ # end ++ #end + + describe '.define and .undefine' do + let(:feature_name) { 'testing123' } +--- a/nanoc-cli/spec/nanoc/cli/error_handler_spec.rb ++++ b/nanoc-cli/spec/nanoc/cli/error_handler_spec.rb +@@ -104,7 +104,7 @@ + context 'exit on error' do + let(:exit_on_error) { true } + +- it 'exits on error' do ++ xit 'exits on error' do + expect { subject }.to raise_error(SystemExit) + end + end +@@ -112,7 +112,7 @@ + context 'no exit on error' do + let(:exit_on_error) { false } + +- it 'does not exit on error' do ++ xit 'does not exit on error' do + expect { subject }.not_to raise_error + end + end +--- a/nanoc-live/spec/gem_spec.rb ++++ b/nanoc-live/spec/gem_spec.rb +@@ -11,7 +11,7 @@ + Dir['*.gem'].each { |f| FileUtils.rm(f) } + end + +- it 'builds gem' do ++ xit 'builds gem' do + expect { subject } + .to change { Dir['*.gem'] } + .from([]) +--- a/nanoc-live/spec/manifest_spec.rb ++++ b/nanoc-live/spec/manifest_spec.rb +@@ -1,7 +1,7 @@ + # frozen_string_literal: true + +-describe 'manifest', chdir: false do +- example do +- expect('nanoc-live').to have_a_valid_manifest +- end +-end ++#describe 'manifest', chdir: false do ++# example do ++# expect('nanoc-live').to have_a_valid_manifest ++# end ++#end diff -Nru nanoc-4.11.0/debian/patches/skip-network-test.patch nanoc-4.11.14/debian/patches/skip-network-test.patch --- nanoc-4.11.0/debian/patches/skip-network-test.patch 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/patches/skip-network-test.patch 2021-01-27 22:00:50.000000000 +0000 @@ -10,10 +10,11 @@ --- a/nanoc/spec/nanoc/cli/commands/view_spec.rb +++ b/nanoc/spec/nanoc/cli/commands/view_spec.rb -@@ -68,17 +68,5 @@ +@@ -67,23 +67,5 @@ + expect(Net::HTTP.get('127.0.0.1', '/', 50_385)).to eql("File not found: /\n") end end - +- - it 'does not listen on non-local interfaces' do - addresses = Socket.getifaddrs.map(&:addr).select(&:ipv4?).map(&:ip_address) - non_local_addresses = addresses - ['127.0.0.1'] @@ -23,7 +24,12 @@ - end - - run_nanoc_cmd(['view', '--port', '50385']) do -- expect { Net::HTTP.get(non_local_addresses[0], '/', 50_385) }.to raise_error(Errno::ECONNREFUSED) +- expect do +- Net::HTTP.start(non_local_addresses[0], 50_385, open_timeout: 0.2) do |http| +- request = Net::HTTP::Get.new('/') +- http.request(request) +- end +- end.to raise_error(/Failed to open TCP connection|execution expired/) - end - end end diff -Nru nanoc-4.11.0/debian/patches/skip-test-failing-in-ubuntu.patch nanoc-4.11.14/debian/patches/skip-test-failing-in-ubuntu.patch --- nanoc-4.11.0/debian/patches/skip-test-failing-in-ubuntu.patch 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/debian/patches/skip-test-failing-in-ubuntu.patch 2021-01-28 12:48:38.000000000 +0000 @@ -0,0 +1,21 @@ +Description: Skip test failing in Ubuntu autopkgtest environment + The "Nanoc::CLI::Commands::View#run does not listen on non-local interfaces" + test tries to make use of a non-localhost IPv4 address associated to the + runner machine. However, in Ubuntu infrastructure this address is not allowed + by the $no_proxy variable. Moreover, this IP address is not predictable (it + might vary depending on the runner setup), therefore it cannot be manually + added to the test command. +Author: Lucas Kanashiro +Forwarded: not-needed +Last-Updated: 2021-01-28 + +--- a/nanoc-cli/spec/nanoc/cli/commands/view_spec.rb ++++ b/nanoc-cli/spec/nanoc/cli/commands/view_spec.rb +@@ -84,6 +84,6 @@ + end + end.to raise_error(/Failed to open TCP connection|execution expired/) + end +- end ++ end unless ENV["AUTOPKGTEST_TMP"] + end + end diff -Nru nanoc-4.11.0/debian/ruby-tests.rake nanoc-4.11.14/debian/ruby-tests.rake --- nanoc-4.11.0/debian/ruby-tests.rake 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/ruby-tests.rake 2021-01-27 22:00:50.000000000 +0000 @@ -1,13 +1,12 @@ require 'gem2deb/rake/spectask' require 'gem2deb/rake/testtask' - EXCLUDED_TESTS=['nanoc/test/filters/test_markaby.rb', 'nanoc/test/filters/test_rainpress.rb'] -Gem2Deb::Rake::TestTask.new(:test_all) do |t| - t.libs = ['nanoc/test'] +Gem2Deb::Rake::TestTask.new(:test_nanoc) do |t| + t.libs = ['nanoc/test', 'nanoc/lib', 'nanoc-core/lib', 'nanoc-cli/lib'] t.test_files = FileList['nanoc/test/**/*_spec.rb'] + FileList['nanoc/test/**/test_*.rb']-EXCLUDED_TESTS end @@ -18,6 +17,19 @@ spec.rspec_opts = '-r ./nanoc/spec/spec_helper.rb --color' end +Gem2Deb::Rake::RSpecTask.new(:spec_core) do |spec| + spec.pattern = './nanoc-core/spec/**/*_spec.rb' + spec.rspec_opts = '-r ./nanoc-core/spec/spec_helper.rb --color' +end + +Gem2Deb::Rake::RSpecTask.new(:spec_cli) do |spec| + spec.pattern = './nanoc-cli/spec/**/*_spec.rb' + spec.rspec_opts = '-r ./nanoc-cli/spec/spec_helper.rb --color' +end + +Gem2Deb::Rake::RSpecTask.new(:spec_live) do |spec| + spec.pattern = './nanoc-live/spec/**/*_spec.rb' + spec.rspec_opts = '-r ./nanoc-live/spec/spec_helper.rb --color' +end -#task default: [:test_all, :spec] -task default: [:spec] +task default: [:test_nanoc, :spec, :spec_core, :spec_cli, :spec_live] diff -Nru nanoc-4.11.0/debian/rules nanoc-4.11.14/debian/rules --- nanoc-4.11.0/debian/rules 2020-04-06 23:53:43.000000000 +0000 +++ nanoc-4.11.14/debian/rules 2021-01-27 22:00:50.000000000 +0000 @@ -1,18 +1,12 @@ #!/usr/bin/make -f export DH_RUBY = --gem-install -#export GEM2DEB_TEST_RUNNER = --check-dependencies +export GEM2DEB_TEST_RUNNER = --check-dependencies export TZ = UTC %: dh $@ --buildsystem=ruby --with ruby -override_dh_auto_install: - dh_auto_install - #mkdir doc/yardoc_handlers - #ln -s ../../debian/identifier.rb doc/yardoc_handlers/identifier.rb - rake -f debian/doc.rake doc - override_dh_installman: mkdir man/ pod2man --center "" --release "" --name NANOC --utf8 debian/nanoc.1.pod man/nanoc.1 @@ -21,7 +15,5 @@ override_dh_clean: dh_clean rm -rf man/ - #rm -rf doc/yardoc_handlers/ - rm -rf doc/yardoc rm -rf .yardoc rm -rf coverage diff -Nru nanoc-4.11.0/debian/upstream/metadata nanoc-4.11.14/debian/upstream/metadata --- nanoc-4.11.0/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/debian/upstream/metadata 2021-01-27 22:00:50.000000000 +0000 @@ -0,0 +1,7 @@ +--- +Archive: GitHub +Bug-Database: https://github.com/nanoc/nanoc/issues +Bug-Submit: https://github.com/nanoc/nanoc/issues/new +Changelog: https://github.com/nanoc/nanoc/tags +Repository: https://github.com/nanoc/nanoc.git +Repository-Browse: https://github.com/nanoc/nanoc diff -Nru nanoc-4.11.0/Gemfile nanoc-4.11.14/Gemfile --- nanoc-4.11.0/Gemfile 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/Gemfile 2019-11-10 09:34:31.000000000 +0000 @@ -3,6 +3,8 @@ source 'https://rubygems.org' gemspec path: 'nanoc' +gemspec path: 'nanoc-core' +gemspec path: 'nanoc-cli' gemspec path: 'nanoc-external' gemspec path: 'nanoc-live' gemspec path: 'guard-nanoc' @@ -22,8 +24,11 @@ gem 'rspec' gem 'rspec-its', '~> 1.2' gem 'rspec-mocks' + gem 'rspec_junit_formatter', '~> 0.4.1' gem 'rubocop' + gem 'rubocop-rspec' gem 'timecop' + gem 'tty-command', '~> 0.8' gem 'vcr' gem 'webmock' gem 'yard' @@ -38,12 +43,13 @@ gem 'builder' gem 'coderay' gem 'coffee-script' + gem 'duktape', '~> 2.3' gem 'erubi' gem 'erubis' + gem 'execjs', '~> 2.7' gem 'fog-aws' gem 'fog-local', '~> 0.6' gem 'haml' - gem 'handlebars', platforms: :ruby gem 'kramdown' gem 'less', '~> 2.6', platforms: :ruby gem 'libv8', platforms: :ruby @@ -62,10 +68,10 @@ gem 'redcarpet', '~> 3.4', platforms: :ruby gem 'RedCloth', platforms: :ruby gem 'rouge', '~> 3.1' + gem 'ruby-handlebars' gem 'rubypants' gem 'sass' - gem 'slim', '~> 3.0' - gem 'therubyracer', '~> 0.12', platforms: :ruby + gem 'slim', '~> 4.0' gem 'typogruby' gem 'uglifier' gem 'w3c_validators' diff -Nru nanoc-4.11.0/.github/CONTRIBUTING.md nanoc-4.11.14/.github/CONTRIBUTING.md --- nanoc-4.11.0/.github/CONTRIBUTING.md 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/.github/CONTRIBUTING.md 2019-11-10 09:34:31.000000000 +0000 @@ -4,14 +4,14 @@ Reporting bugs -------------- -If you find a bug in Nanoc, you should report it! Some information that you should include in your bug report is the Nanoc version (`nanoc --version`) and, if relevant, the crash log (`crash.log`). For details, check the [*bug reporting* section of the development guide](http://nanoc.ws/development/#reporting-bugs). +If you find a bug in Nanoc, you should report it! Some information that you should include in your bug report is the Nanoc version (`nanoc --version`) and, if relevant, the crash log (`crash.log`). For details, check the [*bug reporting* section of the development guide](https://nanoc.ws/development/#reporting-bugs). Contributing code ----------------- -Pull requests are appreciated! When submitting a PR, make sure that your changes have covering tests, that the documentation remains up-to-date and that you retain backwards compatibility. For details, check the [*contributing code* section of the development guide](http://nanoc.ws/development/#contributing-code). +Pull requests are appreciated! When submitting a PR, make sure that your changes have covering tests, that the documentation remains up-to-date and that you retain backwards compatibility. For details, check the [*contributing code* section of the development guide](https://nanoc.ws/development/#contributing-code). Contributor code of conduct --------------------------- -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone. For details, see the contributor code of conduct at http://nanoc.ws/contributing/#contributor-code-of-conduct. +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone. For details, see the contributor code of conduct at https://nanoc.ws/contributing/#contributor-code-of-conduct. diff -Nru nanoc-4.11.0/.github/ISSUE_TEMPLATE.md nanoc-4.11.14/.github/ISSUE_TEMPLATE.md --- nanoc-4.11.0/.github/ISSUE_TEMPLATE.md 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/.github/ISSUE_TEMPLATE.md 2019-11-10 09:34:31.000000000 +0000 @@ -1,5 +1,3 @@ -(Summarise the bug in a single line.) - ### Steps to reproduce 1. [First step] diff -Nru nanoc-4.11.0/.github/PULL_REQUEST_TEMPLATE.md nanoc-4.11.14/.github/PULL_REQUEST_TEMPLATE.md --- nanoc-4.11.0/.github/PULL_REQUEST_TEMPLATE.md 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/.github/PULL_REQUEST_TEMPLATE.md 2019-11-10 09:34:31.000000000 +0000 @@ -1,5 +1,3 @@ -(Summarise the change in a single line.) - ### Detailed description (Describe the change in detail.) diff -Nru nanoc-4.11.0/guard-nanoc/guard-nanoc.gemspec nanoc-4.11.14/guard-nanoc/guard-nanoc.gemspec --- nanoc-4.11.0/guard-nanoc/guard-nanoc.gemspec 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/guard-nanoc/guard-nanoc.gemspec 2019-11-10 09:34:31.000000000 +0000 @@ -5,9 +5,9 @@ Gem::Specification.new do |s| s.name = 'guard-nanoc' s.version = Guard::GUARD_NANOC_VERSION - s.homepage = 'http://nanoc.ws/' - s.summary = 'guard gem for nanoc' - s.description = 'Automatically rebuilds nanoc sites' + s.homepage = 'https://nanoc.ws/' + s.summary = 'guard gem for Nanoc' + s.description = 'Automatically rebuilds Nanoc sites' s.license = 'MIT' s.author = 'Denis Defreyne' diff -Nru nanoc-4.11.0/guard-nanoc/lib/guard/nanoc/version.rb nanoc-4.11.14/guard-nanoc/lib/guard/nanoc/version.rb --- nanoc-4.11.0/guard-nanoc/lib/guard/nanoc/version.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/guard-nanoc/lib/guard/nanoc/version.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,5 +1,5 @@ # frozen_string_literal: true module Guard - GUARD_NANOC_VERSION = '2.1.4' + GUARD_NANOC_VERSION = '2.1.6' end diff -Nru nanoc-4.11.0/guard-nanoc/lib/guard/nanoc.rb nanoc-4.11.14/guard-nanoc/lib/guard/nanoc.rb --- nanoc-4.11.0/guard-nanoc/lib/guard/nanoc.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/guard-nanoc/lib/guard/nanoc.rb 2019-11-10 09:34:31.000000000 +0000 @@ -3,14 +3,14 @@ require 'guard/compat/plugin' require 'nanoc' -require 'nanoc/cli' +require 'nanoc/orig_cli' module Guard class Nanoc < Plugin def self.live_cmd @_live_cmd ||= begin - path = File.join(File.dirname(__FILE__), '..', 'nanoc', 'cli', 'commands', 'live.rb') - ::Nanoc::CLI.load_command_at(path) + path = File.join(File.dirname(__FILE__), '..', 'nanoc', 'orig_cli', 'commands', 'live.rb') + Cri::Command.load_file(path, infer_name: true) end end @@ -41,9 +41,9 @@ def setup_listeners ::Nanoc::CLI.setup - ::Nanoc::CLI::Commands::CompileListeners::FileActionPrinter + ::Nanoc::CLI::CompileListeners::FileActionPrinter .new(reps: []) - .start + .start_safely end def recompile_in_subprocess @@ -56,9 +56,12 @@ end def recompile + # Necessary, because forking and threading don’t work together. + ::Nanoc::Core::NotificationCenter.force_reset + Dir.chdir(@dir) do - site = ::Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile + site = ::Nanoc::Core::SiteLoader.new.new_from_cwd + ::Nanoc::Core::Compiler.compile(site) end notify_success rescue => e diff -Nru nanoc-4.11.0/guard-nanoc/lib/nanoc/cli/commands/live.rb nanoc-4.11.14/guard-nanoc/lib/nanoc/cli/commands/live.rb --- nanoc-4.11.0/guard-nanoc/lib/nanoc/cli/commands/live.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/guard-nanoc/lib/nanoc/cli/commands/live.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -# frozen_string_literal: true - -usage 'live [options]' -summary 'start the web server, and recompile the site when changed' -description <<~EOS - Start the static web server (like `nanoc view` would), and watch for changes - in the background (like `guard start` would). See the documentation of those - two commands for details. The options are forwarded to `nanoc view` only. -EOS - -required :H, :handler, 'specify the handler to use (webrick/mongrel/...)' -required :o, :host, 'specify the host to listen on (default: 0.0.0.0)', default: '127.0.0.1' -required :p, :port, 'specify the port to listen on (default: 3000)', transform: Nanoc::CLI::Transform::Port, default: 3000 -flag :L, :'live-reload', 'reload on changes' - -module Nanoc::CLI::Commands - class Live < ::Nanoc::CLI::CommandRunner - def run - require 'guard' - require 'guard/commander' - - Thread.new do - # Crash the entire process if the viewer dies for some reason (e.g. - # the port is already bound). - Thread.current.abort_on_exception = true - Nanoc::CLI::Commands::View.new(options, arguments, command).run - end - - Guard.start(no_interactions: true) - end - end -end - -runner Nanoc::CLI::Commands::Live diff -Nru nanoc-4.11.0/guard-nanoc/lib/nanoc/orig_cli/commands/live.rb nanoc-4.11.14/guard-nanoc/lib/nanoc/orig_cli/commands/live.rb --- nanoc-4.11.0/guard-nanoc/lib/nanoc/orig_cli/commands/live.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/guard-nanoc/lib/nanoc/orig_cli/commands/live.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +usage 'live [options]' +summary 'start the web server, and recompile the site when changed' +description <<~EOS + Start the static web server (like `nanoc view` would), and watch for changes + in the background (like `guard start` would). See the documentation of those + two commands for details. The options are forwarded to `nanoc view` only. +EOS + +required :H, :handler, 'specify the handler to use (webrick/mongrel/...)' +required :o, :host, 'specify the host to listen on (default: 0.0.0.0)', default: '127.0.0.1' +required :p, :port, 'specify the port to listen on (default: 3000)', transform: Nanoc::CLI::Transform::Port, default: 3000 +flag :L, :'live-reload', 'reload on changes' + +module Nanoc::CLI::Commands + class Live < ::Nanoc::CLI::CommandRunner + def run + require 'guard' + require 'guard/commander' + + Thread.new do + # Crash the entire process if the viewer dies for some reason (e.g. + # the port is already bound). + Thread.current.abort_on_exception = true + Nanoc::CLI::Commands::View.new(options, arguments, command).run + end + + Guard.start(no_interactions: true) + end + end +end + +runner Nanoc::CLI::Commands::Live diff -Nru nanoc-4.11.0/guard-nanoc/LICENSE nanoc-4.11.14/guard-nanoc/LICENSE --- nanoc-4.11.0/guard-nanoc/LICENSE 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/guard-nanoc/LICENSE 2019-11-10 09:34:31.000000000 +0000 @@ -1,4 +1,4 @@ -Copyright (c) 2013 Denis Defreyne +Copyright (c) 2013–… Denis Defreyne Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff -Nru nanoc-4.11.0/guard-nanoc/NEWS.md nanoc-4.11.14/guard-nanoc/NEWS.md --- nanoc-4.11.0/guard-nanoc/NEWS.md 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/guard-nanoc/NEWS.md 2019-11-10 09:34:31.000000000 +0000 @@ -1,5 +1,13 @@ # guard-nanoc Release Notes +## 2.1.6 (2019-02-16) + +* Fixed another incompatibility with Nanoc 4.11.1. + +## 2.1.5 (2019-02-14) + +* Fixed an incompatibility with Nanoc 4.11.1. + ## 2.1.4 (2018-09-15) * Fixed issue which caused `--host` and `--port` options to be mandatory. diff -Nru nanoc-4.11.0/guard-nanoc/README.md nanoc-4.11.14/guard-nanoc/README.md --- nanoc-4.11.0/guard-nanoc/README.md 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/guard-nanoc/README.md 2019-11-10 09:34:31.000000000 +0000 @@ -1,6 +1,6 @@ # Guard::Nanoc -This is a guard for [nanoc](http://nanoc.ws/). +This is a guard for [nanoc](https://nanoc.ws/). `Guard` is a framework for listening to filesystem changes and acting upon them. `Guard::Nanoc` is a plugin for Guard that recompiles Nanoc sites on changes. @@ -26,7 +26,7 @@ ## Usage -Enter the nanoc site directory for which you want to use guard-nanoc. Create a Guardfile using `guard init`: +Enter the Nanoc site directory for which you want to use guard-nanoc. Create a Guardfile using `guard init`: $ bundle exec guard init nanoc diff -Nru nanoc-4.11.0/guard-nanoc/spec/gem_spec.rb nanoc-4.11.14/guard-nanoc/spec/gem_spec.rb --- nanoc-4.11.0/guard-nanoc/spec/gem_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/guard-nanoc/spec/gem_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +describe 'guard-nanoc.gem', chdir: false, stdio: true do + subject do + TTY::Command.new.run('gem build guard-nanoc.gemspec') + end + + around do |ex| + Dir['*.gem'].each { |f| FileUtils.rm(f) } + ex.run + Dir['*.gem'].each { |f| FileUtils.rm(f) } + end + + it 'builds gem' do + STDOUT.puts `pwd` + expect { subject } + .to change { Dir['*.gem'] } + .from([]) + .to(include(match(/^guard-nanoc-.*\.gem$/))) + end +end diff -Nru nanoc-4.11.0/guard-nanoc/spec/lib/guard/nanoc_spec.rb nanoc-4.11.14/guard-nanoc/spec/lib/guard/nanoc_spec.rb --- nanoc-4.11.0/guard-nanoc/spec/lib/guard/nanoc_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/guard-nanoc/spec/lib/guard/nanoc_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -4,6 +4,17 @@ require 'guard/nanoc' RSpec.describe Guard::Nanoc do + around do |example| + Dir.mktmpdir('nanoc-test') do |dir| + __nanoc_core_chdir(dir) do + Nanoc::CLI.run(%w[create-site foo]) + __nanoc_core_chdir('foo') do + example.run + end + end + end + end + before do allow(Process).to receive(:fork) do |_args, &block| @_fork_block = block @@ -51,7 +62,7 @@ describe 'command' do it 'has an option set that is a superset of the view command’s options' do view_cmd = Nanoc::CLI.root_command.command_named('view') - live_cmd = Guard::Nanoc.live_cmd + live_cmd = described_class.live_cmd expect(live_cmd.option_definitions).not_to eq(view_cmd.option_definitions) end diff -Nru nanoc-4.11.0/guard-nanoc/spec/spec_helper.rb nanoc-4.11.14/guard-nanoc/spec/spec_helper.rb --- nanoc-4.11.0/guard-nanoc/spec/spec_helper.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/guard-nanoc/spec/spec_helper.rb 2019-11-10 09:34:31.000000000 +0000 @@ -8,7 +8,7 @@ RSpec.configure do |config| # Swallow stdout/stderr - config.around(:each) do |example| + config.around do |example| old_stdout = $stdout old_stderr = $stderr @@ -22,17 +22,4 @@ $stderr = old_stderr end end - - # In temporary site - config.around(:each) do |example| - Dir.mktmpdir('nanoc-test') do |dir| - FileUtils.cd(dir) do - Nanoc::CLI.run(%w[create-site foo]) - - FileUtils.cd('foo') do - example.run - end - end - end - end end diff -Nru nanoc-4.11.0/nanoc/bin/nanoc nanoc-4.11.14/nanoc/bin/nanoc --- nanoc-4.11.0/nanoc/bin/nanoc 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/bin/nanoc 2019-11-10 09:34:31.000000000 +0000 @@ -9,7 +9,7 @@ rescue LoadError end -require 'nanoc/cli' +require 'nanoc/orig_cli' if File.file?('Gemfile') && !defined?(Bundler) warn 'A Gemfile was detected, but Bundler is not loaded. This is probably not what you want. To run Nanoc with Bundler, use `bundle exec nanoc`.' diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/assertions.rb nanoc-4.11.14/nanoc/lib/nanoc/base/assertions.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/assertions.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/assertions.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - module Assertions - class AssertionFailure < Nanoc::Int::Errors::InternalInconsistency - end - - module Mixin - def assert(assertion) - return unless Nanoc::Int::ContractsSupport.enabled? - - unless assertion.call - raise AssertionFailure, "assertion failed: #{assertion.class}" - end - end - end - - class Base - def call - raise NotImplementedError - end - end - - class AllItemRepsHaveCompiledContent < Nanoc::Assertions::Base - def initialize(compiled_content_cache:, item_reps:) - @compiled_content_cache = compiled_content_cache - @item_reps = item_reps - end - - def call - @item_reps.all? do |rep| - @compiled_content_cache[rep] - end - end - end - - class PathIsAbsolute < Nanoc::Assertions::Base - def initialize(path:) - @path = path - end - - def call - Pathname.new(@path).absolute? - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/contracts_support.rb nanoc-4.11.14/nanoc/lib/nanoc/base/contracts_support.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/contracts_support.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/contracts_support.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,130 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - module ContractsSupport - class Ignorer - include Singleton - - def method_missing(*_args) # rubocop:disable Style/MethodMissingSuper - self - end - - def respond_to_missing?(*_args) - true - end - end - - module DisabledContracts - Any = Ignorer.instance - Bool = Ignorer.instance - Num = Ignorer.instance - KeywordArgs = Ignorer.instance - Args = Ignorer.instance - Optional = Ignorer.instance - Maybe = Ignorer.instance - None = Ignorer.instance - ArrayOf = Ignorer.instance - Or = Ignorer.instance - Func = Ignorer.instance - RespondTo = Ignorer.instance - Named = Ignorer.instance - IterOf = Ignorer.instance - HashOf = Ignorer.instance - AbsolutePathString = Ignorer.instance - - def contract(*args); end - end - - module EnabledContracts - class AbstractContract - def self.[](*vals) - new(*vals) - end - end - - class Named < AbstractContract - def initialize(name) - @name = name - end - - def valid?(val) - val.is_a?(Kernel.const_get(@name)) - end - - def inspect - "#{self.class}(#{@name})" - end - end - - class IterOf < AbstractContract - def initialize(contract) - @contract = contract - end - - def valid?(val) - val.respond_to?(:each) && val.all? { |v| Contract.valid?(v, @contract) } - end - - def inspect - "#{self.class}(#{@contract})" - end - end - - class AbsolutePathString < AbstractContract - def self.valid?(val) - val.is_a?(String) && Pathname.new(val).absolute? - end - end - - def contract(*args) - Contract(*args) - end - end - - def self.setup_once - @_contracts_support__setup ||= false - return @_contracts_support__should_enable if @_contracts_support__setup - - @_contracts_support__setup = true - - contracts_loadable = - begin - require 'contracts' - true - rescue LoadError - false - end - - @_contracts_support__should_enable = contracts_loadable && !ENV.key?('DISABLE_CONTRACTS') - - if @_contracts_support__should_enable - # FIXME: ugly - ::Contracts.const_set('Named', EnabledContracts::Named) - ::Contracts.const_set('IterOf', EnabledContracts::IterOf) - ::Contracts.const_set('AbsolutePathString', EnabledContracts::AbsolutePathString) - end - - @_contracts_support__should_enable - end - - def self.enabled? - setup_once - end - - def self.included(base) - should_enable = setup_once - - if should_enable - unless base.include?(::Contracts::Core) - base.include(::Contracts::Core) - base.extend(EnabledContracts) - base.const_set('C', ::Contracts) - end - else - base.extend(DisabledContracts) - base.const_set('C', DisabledContracts) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/core_ext/array.rb nanoc-4.11.14/nanoc/lib/nanoc/base/core_ext/array.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/core_ext/array.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/core_ext/array.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -# frozen_string_literal: true - -# @api private -module Nanoc::ArrayExtensions - # Returns a new array where all items' keys are recursively converted to - # symbols by calling {Nanoc::ArrayExtensions#__nanoc_symbolize_keys_recursively} or - # {Nanoc::HashExtensions#__nanoc_symbolize_keys_recursively}. - # - # @return [Array] The converted array - def __nanoc_symbolize_keys_recursively - array = [] - each do |element| - array << (element.respond_to?(:__nanoc_symbolize_keys_recursively) ? element.__nanoc_symbolize_keys_recursively : element) - end - array - end - - def __nanoc_stringify_keys_recursively - array = [] - each do |element| - array << (element.respond_to?(:__nanoc_stringify_keys_recursively) ? element.__nanoc_stringify_keys_recursively : element) - end - array - end - - # Freezes the contents of the array, as well as all array elements. The - # array elements will be frozen using {#__nanoc_freeze_recursively} if they respond - # to that message, or #freeze if they do not. - # - # @see Hash#__nanoc_freeze_recursively - # - # @return [void] - def __nanoc_freeze_recursively - return if frozen? - - freeze - each do |value| - if value.respond_to?(:__nanoc_freeze_recursively) - value.__nanoc_freeze_recursively - else - value.freeze - end - end - end -end - -# @api private -class Array - include Nanoc::ArrayExtensions -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/core_ext/hash.rb nanoc-4.11.14/nanoc/lib/nanoc/base/core_ext/hash.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/core_ext/hash.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/core_ext/hash.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -# frozen_string_literal: true - -# @api private -module Nanoc::HashExtensions - # Returns a new hash where all keys are recursively converted to symbols by - # calling {Nanoc::ArrayExtensions#__nanoc_symbolize_keys_recursively} or - # {Nanoc::HashExtensions#__nanoc_symbolize_keys_recursively}. - # - # @return [Hash] The converted hash - def __nanoc_symbolize_keys_recursively - hash = {} - each_pair do |key, value| - new_key = key.respond_to?(:to_sym) ? key.to_sym : key - new_value = value.respond_to?(:__nanoc_symbolize_keys_recursively) ? value.__nanoc_symbolize_keys_recursively : value - hash[new_key] = new_value - end - hash - end - - def __nanoc_stringify_keys_recursively - hash = {} - each_pair do |key, value| - new_key = key.is_a?(Symbol) ? key.to_s : key - new_value = value.respond_to?(:__nanoc_stringify_keys_recursively) ? value.__nanoc_stringify_keys_recursively : value - hash[new_key] = new_value - end - hash - end - - # Freezes the contents of the hash, as well as all hash values. The hash - # values will be frozen using {#__nanoc_freeze_recursively} if they respond to - # that message, or #freeze if they do not. - # - # @see Array#__nanoc_freeze_recursively - # - # @return [void] - def __nanoc_freeze_recursively - return if frozen? - - freeze - each_pair do |_key, value| - if value.respond_to?(:__nanoc_freeze_recursively) - value.__nanoc_freeze_recursively - else - value.freeze - end - end - end -end - -# @api private -class Hash - include Nanoc::HashExtensions -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/core_ext/string.rb nanoc-4.11.14/nanoc/lib/nanoc/base/core_ext/string.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/core_ext/string.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/core_ext/string.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -# @api private -module Nanoc::StringExtensions - # Transforms string into an actual identifier - # - # @return [String] The identifier generated from the receiver - def __nanoc_cleaned_identifier - "/#{self}/".gsub(/^\/+|\/+$/, '/') - end -end - -# @api private -class String - include Nanoc::StringExtensions -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/core_ext.rb nanoc-4.11.14/nanoc/lib/nanoc/base/core_ext.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/core_ext.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/core_ext.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -require 'nanoc/base/core_ext/array' -require 'nanoc/base/core_ext/hash' -require 'nanoc/base/core_ext/string' diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/action_sequence.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/action_sequence.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/action_sequence.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/action_sequence.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - class ActionSequence - include Nanoc::Int::ContractsSupport - include Enumerable - DDMemoize.activate(self) - - attr_reader :item_rep - attr_reader :actions - - def initialize(item_rep, actions: []) - @item_rep = item_rep - @actions = actions - end - - def self.build(rep) - builder = Nanoc::Int::ActionSequenceBuilder.new(rep) - yield(builder) - builder.action_sequence - end - - contract C::None => Numeric - def size - @actions.size - end - - contract Numeric => C::Maybe[Nanoc::Int::ProcessingAction] - def [](idx) - @actions[idx] - end - - contract C::None => C::ArrayOf[Nanoc::Int::ProcessingAction] - def snapshot_actions - @actions.select { |a| a.is_a?(Nanoc::Int::ProcessingActions::Snapshot) } - end - - contract C::None => Array - def paths - snapshot_actions.map { |a| [a.snapshot_names, a.paths] } - end - - memoized def serialize - serialize_uncached - end - - contract C::None => Array - def serialize_uncached - to_a.map(&:serialize) - end - - contract C::Func[Nanoc::Int::ProcessingAction => C::Any] => self - def each - @actions.each { |a| yield(a) } - self - end - - contract C::Func[Nanoc::Int::ProcessingAction => C::Any] => self - def map - self.class.new( - @item_rep, - actions: @actions.map { |a| yield(a) }, - ) - end - - def snapshots_defs - is_binary = @item_rep.item.content.binary? - snapshot_defs = [] - - each do |action| - case action - when Nanoc::Int::ProcessingActions::Snapshot - action.snapshot_names.each do |snapshot_name| - snapshot_defs << Nanoc::Int::SnapshotDef.new(snapshot_name, binary: is_binary) - end - when Nanoc::Int::ProcessingActions::Filter - is_binary = Nanoc::Filter.named!(action.filter_name).to_binary? - end - end - - snapshot_defs - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/checksum_collection.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/checksum_collection.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/checksum_collection.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/checksum_collection.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - class ChecksumCollection - include Nanoc::Int::ContractsSupport - - c_obj = C::Or[Nanoc::Int::Item, Nanoc::Int::Layout, Nanoc::Int::Configuration, Nanoc::Int::CodeSnippet] - - def initialize(checksums) - @checksums = checksums - end - - contract c_obj => C::Maybe[String] - def checksum_for(obj) - @checksums[obj.reference] - end - - contract c_obj => C::Maybe[String] - def content_checksum_for(obj) - @checksums[[obj.reference, :content]] - end - - contract c_obj => C::Maybe[C::HashOf[Symbol, String]] - def attributes_checksum_for(obj) - @checksums[[obj.reference, :each_attribute]] - end - - def to_h - @checksums - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/code_snippet.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/code_snippet.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/code_snippet.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/code_snippet.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Nanoc::Int::CodeSnippet represent a piece of custom code of a Nanoc site. - # - # @api private - class CodeSnippet - include Nanoc::Int::ContractsSupport - - # A string containing the actual code in this code snippet. - # - # @return [String] - attr_reader :data - - # The filename corresponding to this code snippet. - # - # @return [String] - attr_reader :filename - - contract String, String => C::Any - # Creates a new code snippet. - # - # @param [String] data The raw source code which will be executed before - # compilation - # - # @param [String] filename The filename corresponding to this code snippet - def initialize(data, filename) - @data = data - @filename = filename - end - - contract C::None => nil - # Loads the code by executing it. - # - # @return [void] - def load - eval('def self.use_helper(mod); Nanoc::Int::Context.instance_eval { include mod }; end', TOPLEVEL_BINDING) - eval(@data, TOPLEVEL_BINDING, @filename) - nil - end - - # Returns an object that can be used for uniquely identifying objects. - # - # @return [Object] An unique reference to this object - def reference - "code_snippet:#{filename}" - end - - def inspect - "<#{self.class} filename=\"#{filename}\">" - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/configuration.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/configuration.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/configuration.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/configuration.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,206 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Represents the site configuration. - # - # @api private - class Configuration - include Nanoc::Int::ContractsSupport - - NONE = Object.new.freeze - - # The default configuration for a data source. A data source's - # configuration overrides these options. - DEFAULT_DATA_SOURCE_CONFIG = { - type: 'filesystem', - items_root: '/', - layouts_root: '/', - config: {}, - identifier_type: 'full', - }.freeze - - # The default configuration for a site. A site's configuration overrides - # these options: when a {Nanoc::Int::Site} is created with a configuration - # that lacks some options, the default value will be taken from - # `DEFAULT_CONFIG`. - DEFAULT_CONFIG = { - text_extensions: %w[adoc asciidoc atom css erb haml htm html js less markdown md php rb sass scss tex txt xhtml xml coffee hb handlebars mustache ms slim rdoc].sort, - lib_dirs: %w[lib], - commands_dirs: %w[commands], - output_dir: 'output', - data_sources: [{}], - index_filenames: ['index.html'], - enable_output_diff: false, - prune: { auto_prune: false, exclude: ['.git', '.hg', '.svn', 'CVS'] }, - string_pattern_type: 'glob', - action_provider: 'rule_dsl', - }.freeze - - # @return [String, nil] The active environment for the configuration - attr_reader :env_name - - contract C::None => C::AbsolutePathString - attr_reader :dir - - # Configuration environments property key - ENVIRONMENTS_CONFIG_KEY = :environments - NANOC_ENV = 'NANOC_ENV' - NANOC_ENV_DEFAULT = 'default' - - contract C::KeywordArgs[hash: C::Optional[Hash], env_name: C::Maybe[String], dir: C::AbsolutePathString] => C::Any - def initialize(hash: {}, dir:, env_name: nil) - @env_name = env_name - @wrapped = hash.__nanoc_symbolize_keys_recursively - @dir = dir - - validate - end - - contract C::None => self - def with_defaults - new_wrapped = DEFAULT_CONFIG.merge(@wrapped) - new_wrapped[:data_sources] = new_wrapped[:data_sources].map do |ds| - DEFAULT_DATA_SOURCE_CONFIG.merge(ds) - end - - self.class.new(hash: new_wrapped, dir: @dir, env_name: @env_name) - end - - def with_environment - return self unless @wrapped.key?(ENVIRONMENTS_CONFIG_KEY) - - # Set active environment - env_name = @env_name || ENV.fetch(NANOC_ENV, NANOC_ENV_DEFAULT) - - # Load given environment configuration - env_config = @wrapped[ENVIRONMENTS_CONFIG_KEY].fetch(env_name.to_sym, {}) - - self.class.new(hash: @wrapped, dir: @dir, env_name: env_name).merge(env_config) - end - - contract C::None => Hash - def to_h - @wrapped - end - - # For compat - contract C::None => Hash - def attributes - to_h - end - - contract C::Any => C::Bool - def key?(key) - @wrapped.key?(key) - end - - contract C::Any => C::Any - def [](key) - @wrapped[key] - end - - contract C::Args[C::Any] => C::Any - def dig(*keys) - @wrapped.dig(*keys) - end - - contract C::Any, C::Maybe[C::Any], C::Maybe[C::Func[C::None => C::Any]] => C::Any - def fetch(key, fallback = NONE, &_block) - @wrapped.fetch(key) do - if !fallback.equal?(NONE) - fallback - elsif block_given? - yield(key) - else - raise KeyError, "key not found: #{key.inspect}" - end - end - end - - contract C::Any, C::Any => C::Any - def []=(key, value) - @wrapped[key] = value - end - - contract C::Or[Hash, self] => self - def merge(hash) - self.class.new(hash: merge_recursively(@wrapped, hash.to_h), dir: @dir, env_name: @env_name) - end - - contract C::Any => self - def without(key) - self.class.new(hash: @wrapped.reject { |k, _v| k == key }, dir: @dir, env_name: @env_name) - end - - contract C::Any => self - def update(hash) - @wrapped.update(hash) - self - end - - contract C::Func[C::Any, C::Any => C::Any] => self - def each - @wrapped.each { |k, v| yield(k, v) } - self - end - - contract C::None => self - def freeze - super - @wrapped.__nanoc_freeze_recursively - self - end - - contract C::None => C::AbsolutePathString - def output_dir - make_absolute(self[:output_dir]).freeze - end - - contract C::None => Symbol - def action_provider - self[:action_provider].to_sym - end - - contract C::None => C::IterOf[C::AbsolutePathString] - def output_dirs - envs = @wrapped.fetch(ENVIRONMENTS_CONFIG_KEY, {}) - res = [output_dir] + envs.values.map { |v| make_absolute(v[:output_dir]) } - res.uniq.compact - end - - # Returns an object that can be used for uniquely identifying objects. - # - # @return [Object] An unique reference to this object - def reference - 'configuration' - end - - def inspect - "<#{self.class}>" - end - - private - - def make_absolute(path) - path && @dir && File.absolute_path(path, @dir).encode('UTF-8') - end - - def merge_recursively(config1, config2) - config1.merge(config2) do |_, value1, value2| - if value1.is_a?(Hash) && value2.is_a?(Hash) - merge_recursively(value1, value2) - else - value2 - end - end - end - - def validate - dir = File.dirname(__FILE__) - schema_data = JSON.parse(File.read(dir + '/configuration-schema.json')) - schema = JsonSchema.parse!(schema_data) - schema.expand_references! - schema.validate!(@wrapped.__nanoc_stringify_keys_recursively) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/configuration-schema.json nanoc-4.11.14/nanoc/lib/nanoc/base/entities/configuration-schema.json --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/configuration-schema.json 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/configuration-schema.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,122 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Nanoc configuration schema", - "type": "object", - "properties": { - "text_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "output_dir": { - "type": "string" - }, - "index_filenames": { - "type": "array", - "items": { - "type": "string" - } - }, - "enable_output_diff": { - "type": "boolean" - }, - "prune": { - "type": "object", - "additionalProperties": false, - "properties": { - "auto_prune": { - "type": "boolean" - }, - "exclude": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "commands_dirs": { - "type": "array", - "items": { - "type": "string" - } - }, - "lib_dirs": { - "type": "array", - "items": { - "type": "string" - } - }, - "data_sources": { - "type": "array", - "items": { - "type": "object", - "properties": { - "type": { - "type": "string" - }, - "items_root": { - "anyOf": [ - { "type": "string" }, - { "type": "null" } - ] - }, - "layouts_root": { - "anyOf": [ - { "type": "string" }, - { "type": "null" } - ] - } - } - } - }, - "string_pattern_type": { - "type": "string", - "enum": ["glob", "legacy"] - }, - "checks": { - "type": "object", - "properties": { - "internal_links": { - "type": "object", - "additionalProperties": false, - "properties": { - "exclude": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "external_links": { - "type": "object", - "additionalProperties": false, - "properties": { - "exclude": { - "type": "array", - "items": { - "type": "string" - } - }, - "exclude_files": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - } - }, - "environments": { - "type": "object", - "patternProperties": { - "^.*$": { - "type": "object" - } - } - } - } -} diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/content.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/content.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/content.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/content.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - module Int - # Abstract content. - # - # The filename is the full filename on the default filesystem. It can be - # nil. It is used by filters such as Sass, which look up items on the - # filesystem. - # - # @abstract - # - # @api private - class Content - include Nanoc::Int::ContractsSupport - - # @return [String, nil] - attr_reader :filename - - contract C::Maybe[String] => C::Any - # @param [String, nil] filename - def initialize(filename) - if filename && Pathname.new(filename).relative? - raise ArgumentError, 'Content filename is not absolute' - end - - @filename = filename - end - - contract C::None => self - def freeze - super - @filename.freeze - self - end - - contract C::Or[Nanoc::Int::Content, String, Proc], C::KeywordArgs[binary: C::Optional[C::Bool], filename: C::Optional[C::Maybe[String]]] => self - # @param [Nanoc::Int::Content, String, Proc] content The uncompiled item - # content (if it is textual content) or the path to the filename - # containing the content (if this is binary content). - # - # @param [Boolean] binary Whether or not this item is binary - # - # @param [String] filename Absolute path to the file containing this - # content (if any) - def self.create(content, binary: false, filename: nil) - if content.nil? - raise ArgumentError, 'Cannot create nil content' - elsif content.is_a?(Nanoc::Int::Content) - content - elsif binary - Nanoc::Int::BinaryContent.new(content) - else - Nanoc::Int::TextualContent.new(content, filename: filename) - end - end - - # @abstract - # - # @return [Boolean] - def binary? - raise NotImplementedError - end - end - - # @api private - class TextualContent < Content - contract C::None => String - # @return [String] - def string - @string.value - end - - contract C::Or[String, Proc], C::KeywordArgs[filename: C::Optional[C::Maybe[String]]] => C::Any - def initialize(string, filename: nil) - super(filename) - @string = Nanoc::Int::LazyValue.new(string) - end - - contract C::None => self - def freeze - super - @string.freeze - self - end - - contract C::None => C::Bool - def binary? - false - end - - contract C::None => Array - def marshal_dump - [filename, string] - end - - contract Array => C::Any - def marshal_load(array) - @filename = array[0] - @string = Nanoc::Int::LazyValue.new(array[1]) - end - end - - # @api private - class BinaryContent < Content - contract C::None => C::Bool - def binary? - true - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/context.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/context.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/context.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/context.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Provides a context and a binding for use in filters such as the ERB and - # Haml ones. - # - # @api private - class Context - # Creates a new context based off the contents of the hash. - # - # Each pair in the hash will be converted to an instance variable and an - # instance method. For example, passing the hash `{ :foo => 'bar' }` will - # cause `@foo` to have the value `"bar"`, and the instance method `#foo` - # to return the same value `"bar"`. - # - # @param [Hash] hash A list of key-value pairs to make available - # - # @example Defining a context and accessing values - # - # context = Nanoc::Int::Context.new( - # :name => 'Max Payne', - # :location => 'in a cheap motel' - # ) - # context.instance_eval do - # "I am #{name} and I am hiding #{@location}." - # end - # # => "I am Max Payne and I am hiding in a cheap motel." - def initialize(hash) - hash.each_pair do |key, value| - instance_variable_set('@' + key.to_s, value) - end - end - - # Returns a binding for this instance. - # - # @return [Binding] A binding for this instance - # rubocop:disable Naming/AccessorMethodName - def get_binding - binding - end - # rubocop:enable Naming/AccessorMethodName - - def method_missing(method, *args, &blk) - ivar_name = '@' + method.to_s - if instance_variable_defined?(ivar_name) - instance_variable_get(ivar_name) - else - super - end - end - - def respond_to_missing?(method, include_all) - ivar_name = '@' + method.to_s - - valid_ivar_name = - if defined?(Contracts) - ivar_name =~ /\A@[A-Za-z_]+\z/ - else - true # probably good enough - end - - (valid_ivar_name && instance_variable_defined?(ivar_name)) || super - end - - def include(mod) - metaclass = class << self; self; end - metaclass.instance_eval { include(mod) } - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/dependency.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/dependency.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/dependency.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/dependency.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - # A dependency between two items/layouts. - class Dependency - include Nanoc::Int::ContractsSupport - - C_OBJ_FROM = C::Or[Nanoc::Int::Item, Nanoc::Int::Layout, Nanoc::Int::Configuration, Nanoc::Int::IdentifiableCollection] - C_OBJ_TO = Nanoc::Int::Item - - contract C::None => C::Maybe[C_OBJ_FROM] - attr_reader :from - - contract C::None => C::Maybe[C_OBJ_TO] - attr_reader :to - - contract C::None => Nanoc::Int::Props - attr_reader :props - - contract C::Maybe[C_OBJ_FROM], C::Maybe[C_OBJ_TO], Nanoc::Int::Props => C::Any - def initialize(from, to, props) - @from = from - @to = to - @props = props - end - - contract C::None => String - def inspect - "Dependency(#{@from.inspect} -> #{@to.inspect}, #{@props.inspect})" - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/directed_graph.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/directed_graph.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/directed_graph.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/directed_graph.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,195 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Represents a directed graph. It is used by the dependency tracker for - # storing and querying dependencies between items. - # - # @example Creating and using a directed graph - # - # # Create a graph with three vertices - # graph = Nanoc::Int::DirectedGraph.new(%w( a b c d e f g )) - # - # # Add edges - # graph.add_edge('a', 'b') - # graph.add_edge('b', 'c') - # graph.add_edge('b', 'f') - # graph.add_edge('b', 'g') - # graph.add_edge('c', 'd') - # graph.add_edge('d', 'e') - # - # # Get (direct) predecessors - # graph.direct_predecessors_of('b').sort - # # => %w( a ) - # graph.predecessors_of('e').sort - # # => %w( a b c d ) - # - # # Modify edges - # graph.delete_edges_to('c') - # - # # Get (direct) predecessors again - # graph.direct_predecessors_of('e').sort - # # => %w( d ) - # graph.predecessors_of('e').sort - # # => %w( c d ) - # - # @api private - class DirectedGraph - # @group Creating a graph - - # Creates a new directed graph with the given vertices. - def initialize(vertices) - @vertices = {} - @next_vertex_idx = 0 - vertices.each do |v| - @vertices[v] = @next_vertex_idx.tap { @next_vertex_idx += 1 } - end - - @to_graph = {} - - @edge_props = {} - - invalidate_caches - end - - def inspect - s = [] - - @vertices.each_pair do |v2, _| - direct_predecessors_of(v2).each do |v1| - s << [v1.inspect + ' -> ' + v2.inspect + ' props=' + @edge_props[[v1, v2]].inspect] - end - end - - self.class.to_s + '(' + s.join(', ') + ')' - end - - # @group Modifying the graph - - # Adds an edge from the first vertex to the second vertex. - # - # @param from Vertex where the edge should start - # - # @param to Vertex where the edge should end - # - # @return [void] - def add_edge(from, to, props: nil) - add_vertex(from) - add_vertex(to) - - @to_graph[to] ||= Set.new - @to_graph[to] << from - - if props - @edge_props[[from, to]] = props - end - - invalidate_caches - end - - # Adds the given vertex to the graph. - # - # @param vertex The vertex to add to the graph - # - # @return [void] - def add_vertex(vertex) - return if @vertices.key?(vertex) - - @vertices[vertex] = @next_vertex_idx.tap { @next_vertex_idx += 1 } - end - - # Deletes all edges going to the given vertex. - # - # @param to Vertex to which all edges should be removed - # - # @return [void] - def delete_edges_to(to) - return if @to_graph[to].nil? - - @to_graph[to].each do |from| - @edge_props.delete([from, to]) - end - @to_graph.delete(to) - - invalidate_caches - end - - # @group Querying the graph - - # Returns the direct predecessors of the given vertex, i.e. the vertices - # x where there is an edge from x to the given vertex y. - # - # @param to The vertex of which the predecessors should be calculated - # - # @return [Array] Direct predecessors of the given vertex - def direct_predecessors_of(to) - @to_graph.fetch(to, Set.new) - end - - # Returns the predecessors of the given vertex, i.e. the vertices x for - # which there is a path from x to the given vertex y. - # - # @param to The vertex of which the predecessors should be calculated - # - # @return [Array] Predecessors of the given vertex - def predecessors_of(to) - @predecessors[to] ||= recursively_find_vertices(to, :direct_predecessors_of) - end - - def props_for(from, to) - @edge_props[[from, to]] - end - - # @return [Array] The list of all vertices in this graph. - def vertices - @vertices.keys.sort_by { |v| @vertices[v] } - end - - # Returns an array of tuples representing the edges. The result of this - # method may take a while to compute and should be cached if possible. - # - # @return [Array] The list of all edges in this graph. - def edges - result = [] - @vertices.each_pair do |v2, i2| - direct_predecessors_of(v2).map { |v1| [@vertices[v1], v1] }.each do |i1, v1| - result << [i1, i2, @edge_props[[v1, v2]]] - end - end - result - end - - private - - # Invalidates cached data. This method should be called when the internal - # graph representation is changed. - def invalidate_caches - @predecessors = {} - end - - # Recursively finds vertices, starting at the vertex start, using the - # given method, which should be a symbol to a method that takes a vertex - # and returns related vertices (e.g. predecessors, successors). - def recursively_find_vertices(start, method) - all_vertices = Set.new - - processed_vertices = Set.new - unprocessed_vertices = [start] - - until unprocessed_vertices.empty? - # Get next unprocessed vertex - vertex = unprocessed_vertices.pop - next if processed_vertices.include?(vertex) - - processed_vertices << vertex - - # Add predecessors of this vertex - send(method, vertex).each do |v| - all_vertices << v unless all_vertices.include?(v) - unprocessed_vertices << v - end - end - - all_vertices - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/document.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/document.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/document.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/document.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - module Int - # @api private - class Document - include Nanoc::Int::ContractsSupport - - # @return [Nanoc::Int::Content] - attr_reader :content - - # @return [Hash] - def attributes - @attributes.value - end - - # @return [Nanoc::Identifier] - attr_reader :identifier - - # @return [String, nil] - attr_accessor :checksum_data - - # @return [String, nil] - attr_accessor :content_checksum_data - - # @return [String, nil] - attr_accessor :attributes_checksum_data - - c_content = C::Or[String, Nanoc::Int::Content] - c_attributes = C::Or[Hash, Proc] - c_identifier = C::Or[String, Nanoc::Identifier] - c_checksum_data = C::KeywordArgs[ - checksum_data: C::Optional[C::Maybe[String]], - content_checksum_data: C::Optional[C::Maybe[String]], - attributes_checksum_data: C::Optional[C::Maybe[String]], - ] - - contract c_content, c_attributes, c_identifier, c_checksum_data => C::Any - # @param [String, Nanoc::Int::Content] content - # - # @param [Hash, Proc] attributes - # - # @param [String, Nanoc::Identifier] identifier - # - # @param [String, nil] checksum_data - # - # @param [String, nil] content_checksum_data - # - # @param [String, nil] attributes_checksum_data - def initialize(content, attributes, identifier, checksum_data: nil, content_checksum_data: nil, attributes_checksum_data: nil) - @content = Nanoc::Int::Content.create(content) - @attributes = Nanoc::Int::LazyValue.new(attributes).map(&:__nanoc_symbolize_keys_recursively) - @identifier = Nanoc::Identifier.from(identifier) - - @checksum_data = checksum_data - @content_checksum_data = content_checksum_data - @attributes_checksum_data = attributes_checksum_data - end - - contract C::None => self - # @return [void] - def freeze - super - @content.freeze - @attributes.freeze - self - end - - contract String => self - def with_identifier_prefix(prefix) - other = dup - other.identifier = @identifier.prefix(prefix) - other - end - - contract C::None => String - # @abstract - # - # @return Unique reference to this object - def reference - raise NotImplementedError - end - - contract C::Or[Nanoc::Identifier, String] => Nanoc::Identifier - def identifier=(new_identifier) - @identifier = Nanoc::Identifier.from(new_identifier) - end - - contract Nanoc::Int::Content => C::Any - def content=(new_content) - @content = new_content - - @checksum_data = nil - @content_checksum_data = nil - end - - def set_attribute(key, value) - attributes[key] = value - - @checksum_data = nil - @attributes_checksum_data = nil - end - - contract C::None => String - def inspect - "<#{self.class} identifier=\"#{identifier}\">" - end - - contract C::None => C::Num - def hash - self.class.hash ^ identifier.hash - end - - contract C::Any => C::Bool - def ==(other) - other.respond_to?(:identifier) && identifier == other.identifier - end - - contract C::Any => C::Bool - def eql?(other) - other.is_a?(self.class) && identifier == other.identifier - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/identifiable_collection.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/identifiable_collection.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/identifiable_collection.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/identifiable_collection.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,141 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class IdentifiableCollection - DDMemoize.activate(self) - - include Nanoc::Int::ContractsSupport - include Enumerable - - extend Forwardable - - def_delegator :@objects, :each - def_delegator :@objects, :size - - def initialize(*) - raise 'IdentifiableCollection is abstract and cannot be instantiated' - end - - contract C::Or[Hash, C::Named['Nanoc::Int::Configuration']], C::IterOf[C::RespondTo[:identifier]], C::Maybe[String] => C::Any - def initialize_basic(config, objects = [], name = nil) - @config = config - @objects = Hamster::Vector.new(objects) - @name = name - end - - contract C::None => String - def inspect - "<#{self.class}>" - end - - contract C::None => self - def freeze - @objects.freeze - @objects.each(&:freeze) - build_mapping - super - end - - contract C::Any => C::Maybe[C::RespondTo[:identifier]] - def [](arg) - if frozen? - get_memoized(arg) - else - get_unmemoized(arg) - end - end - - contract C::Any => C::IterOf[C::RespondTo[:identifier]] - def find_all(arg) - if frozen? - find_all_memoized(arg) - else - find_all_unmemoized(arg) - end - end - - contract C::None => C::ArrayOf[C::RespondTo[:identifier]] - def to_a - @objects.to_a - end - - contract C::None => C::Bool - def empty? - @objects.empty? - end - - contract C::RespondTo[:identifier] => self - def add(obj) - self.class.new(@config, @objects.add(obj)) - end - - contract C::Func[C::RespondTo[:identifier] => C::Any] => self - def reject(&block) - self.class.new(@config, @objects.reject(&block)) - end - - contract C::Any => C::Maybe[C::RespondTo[:identifier]] - def object_with_identifier(identifier) - if frozen? - @mapping[identifier.to_s] - else - @objects.find { |i| i.identifier == identifier } - end - end - - protected - - contract C::Any => C::Maybe[C::RespondTo[:identifier]] - def get_unmemoized(arg) - case arg - when Nanoc::Identifier - object_with_identifier(arg) - when String - object_with_identifier(arg) || object_matching_glob(arg) - when Regexp - @objects.find { |i| i.identifier.to_s =~ arg } - else - raise ArgumentError, "don’t know how to fetch objects by #{arg.inspect}" - end - end - - contract C::Any => C::Maybe[C::RespondTo[:identifier]] - memoized def get_memoized(arg) - get_unmemoized(arg) - end - - contract C::Any => C::IterOf[C::RespondTo[:identifier]] - def find_all_unmemoized(arg) - pat = Nanoc::Int::Pattern.from(arg) - select { |i| pat.match?(i.identifier) } - end - - contract C::Any => C::IterOf[C::RespondTo[:identifier]] - memoized def find_all_memoized(arg) - find_all_unmemoized(arg) - end - - def object_matching_glob(glob) - if use_globs? - pat = Nanoc::Int::Pattern.from(glob) - @objects.find { |i| pat.match?(i.identifier) } - else - nil - end - end - - def build_mapping - @mapping = {} - @objects.each do |object| - @mapping[object.identifier.to_s] = object - end - @mapping.freeze - end - - contract C::None => C::Bool - def use_globs? - @config[:string_pattern_type] == 'glob' - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/identifier.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/identifier.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/identifier.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/identifier.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,222 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class Identifier - include Comparable - include Nanoc::Int::ContractsSupport - - # @api private - class InvalidIdentifierError < ::Nanoc::Error - def initialize(string) - super("Invalid identifier (does not start with a slash): #{string.inspect}") - end - end - - # @api private - class InvalidFullIdentifierError < ::Nanoc::Error - def initialize(string) - super("Invalid full identifier (ends with a slash): #{string.inspect}") - end - end - - # @api private - class InvalidTypeError < ::Nanoc::Error - def initialize(type) - super("Invalid type for identifier: #{type.inspect} (can be :full or :legacy)") - end - end - - # @api private - class InvalidPrefixError < ::Nanoc::Error - def initialize(string) - super("Invalid prefix (does not start with a slash): #{string.inspect}") - end - end - - # @api private - class UnsupportedLegacyOperationError < ::Nanoc::Error - def initialize - super('Cannot use this method on legacy identifiers') - end - end - - # @api private - class NonCoercibleObjectError < ::Nanoc::Error - def initialize(obj) - super("#{obj.inspect} cannot be converted into a Nanoc::Identifier") - end - end - - contract C::Any => self - def self.from(obj) - case obj - when Nanoc::Identifier - obj - when String - Nanoc::Identifier.new(obj) - else - raise NonCoercibleObjectError.new(obj) - end - end - - contract String, C::KeywordArgs[type: C::Optional[Symbol]] => C::Any - def initialize(string, type: :full) - @type = type - - case @type - when :legacy - @string = "/#{string}/".gsub(/^\/+|\/+$/, '/').freeze - when :full - raise InvalidIdentifierError.new(string) if string !~ /\A\// - raise InvalidFullIdentifierError.new(string) if string =~ /\/\z/ - - @string = string.dup.freeze - else - raise InvalidTypeError.new(@type) - end - end - - contract C::Any => C::Bool - def ==(other) - case other - when Nanoc::Identifier, String - to_s == other.to_s - else - false - end - end - - contract C::Any => C::Bool - def eql?(other) - other.is_a?(self.class) && to_s == other.to_s - end - - contract C::None => C::Num - def hash - self.class.hash ^ to_s.hash - end - - contract C::Any => C::Maybe[C::Num] - def =~(other) - Nanoc::Int::Pattern.from(other).match?(to_s) ? 0 : nil - end - - contract C::Any => C::Bool - def match?(other) - Nanoc::Int::Pattern.from(other).match?(to_s) - end - - contract C::Any => C::Num - def <=>(other) - to_s <=> other.to_s - end - - contract C::None => C::Bool - # Whether or not this is a full identifier (i.e.includes the extension). - def full? - @type == :full - end - - contract C::None => C::Bool - # Whether or not this is a legacy identifier (i.e. does not include the extension). - def legacy? - @type == :legacy - end - - contract C::None => String - # @return [String] - def chop - to_s.chop - end - - contract String => String - # @return [String] - def +(other) - to_s + other - end - - contract String => self - # @return [Nanoc::Identifier] - def prefix(string) - unless /\A\//.match?(string) - raise InvalidPrefixError.new(string) - end - - Nanoc::Identifier.new(string.sub(/\/+\z/, '') + @string, type: @type) - end - - contract C::None => String - # The identifier, as string, with the last extension removed - def without_ext - unless full? - raise UnsupportedLegacyOperationError - end - - extname = File.extname(@string) - - if !extname.empty? - @string[0..-extname.size - 1] - else - @string - end - end - - contract C::None => C::Maybe[String] - # The extension, without a leading dot - def ext - unless full? - raise UnsupportedLegacyOperationError - end - - s = File.extname(@string) - s && s[1..-1] - end - - contract C::None => String - # The identifier, as string, with all extensions removed - def without_exts - extname = exts.join('.') - if !extname.empty? - @string[0..-extname.size - 2] - else - @string - end - end - - contract C::None => C::ArrayOf[String] - # The list of extensions, without a leading dot - def exts - unless full? - raise UnsupportedLegacyOperationError - end - - s = File.basename(@string) - s ? s.split('.', -1).drop(1) : [] - end - - contract C::None => C::ArrayOf[String] - def components - res = to_s.split('/') - if res.empty? - [] - else - res[1..-1] - end - end - - contract C::None => String - def to_s - @string - end - - contract C::None => String - def to_str - @string - end - - contract C::None => String - def inspect - "" - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/item_collection.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/item_collection.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/item_collection.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/item_collection.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class ItemCollection < IdentifiableCollection - def initialize(config, objects = []) - initialize_basic(config, objects, 'items') - end - - def reference - 'items' - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/item.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/item.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/item.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/item.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class Item < ::Nanoc::Int::Document - def reference - "item:#{identifier}" - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/item_rep.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/item_rep.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/item_rep.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/item_rep.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class ItemRep - include Nanoc::Int::ContractsSupport - - contract C::None => C::Bool - attr_accessor :compiled - alias compiled? compiled - - contract C::None => C::HashOf[Symbol => C::IterOf[String]] - attr_reader :raw_paths - - contract C::None => C::HashOf[Symbol => C::IterOf[String]] - attr_reader :paths - - contract C::None => Nanoc::Int::Item - attr_reader :item - - contract C::None => Symbol - attr_reader :name - - contract C::None => C::IterOf[C::Named['Nanoc::Int::SnapshotDef']] - attr_accessor :snapshot_defs - - contract C::None => C::Bool - attr_accessor :modified - alias modified? modified - - contract Nanoc::Int::Item, Symbol => C::Any - def initialize(item, name) - # Set primary attributes - @item = item - @name = name - - # Set default attributes - @raw_paths = {} - @paths = {} - @snapshot_defs = [] - - # Reset flags - @compiled = false - @modified = false - end - - contract C::HashOf[Symbol => C::IterOf[C::AbsolutePathString]] => C::HashOf[Symbol => C::IterOf[C::AbsolutePathString]] - def raw_paths=(val) - @raw_paths = val - end - - contract C::HashOf[Symbol => C::IterOf[String]] => C::HashOf[Symbol => C::IterOf[String]] - def paths=(val) - @paths = val - end - - contract Symbol => C::Bool - def snapshot?(name) - snapshot_defs.any? { |sd| sd.name == name } - end - - contract C::KeywordArgs[snapshot: C::Optional[Symbol]] => C::Maybe[String] - # Returns the item rep’s raw path. It includes the path to the output - # directory and the full filename. - def raw_path(snapshot: :last) - @raw_paths.fetch(snapshot, []).first - end - - contract C::KeywordArgs[snapshot: C::Optional[Symbol]] => C::Maybe[String] - # Returns the item rep’s path, as used when being linked to. It starts - # with a slash and it is relative to the output directory. It does not - # include the path to the output directory. It will not include the - # filename if the filename is an index filename. - def path(snapshot: :last) - @paths.fetch(snapshot, []).first - end - - # Returns an object that can be used for uniquely identifying objects. - def reference - "item_rep:#{item.identifier}:#{name}" - end - - def to_s - "#{item.identifier} (rep name #{name.inspect})" - end - - def inspect - "<#{self.class} name=\"#{name}\" raw_path=\"#{raw_path}\" item.identifier=\"#{item.identifier}\">" - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/layout_collection.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/layout_collection.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/layout_collection.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/layout_collection.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class LayoutCollection < IdentifiableCollection - def initialize(config, objects = []) - initialize_basic(config, objects, 'layouts') - end - - def reference - 'layouts' - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/layout.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/layout.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/layout.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/layout.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class Layout < ::Nanoc::Int::Document - def reference - "layout:#{identifier}" - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/lazy_value.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/lazy_value.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/lazy_value.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/lazy_value.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Holds a value that might be generated lazily. - # - # @api private - class LazyValue - include Nanoc::Int::ContractsSupport - - # @param [Object, Proc] value_or_proc A value or a proc to generate the value - def initialize(value_or_proc) - @value = { raw: value_or_proc } - end - - # @return [Object] The value, generated when needed - def value - if @value.key?(:raw) - value = @value.delete(:raw) - @value[:final] = value.respond_to?(:call) ? value.call : value - @value.__nanoc_freeze_recursively if frozen? - end - @value[:final] - end - - contract C::Func[C::Any => C::Any] => self - # Returns a new lazy value that will apply the given transformation when the value is requested. - # - # @yield resolved value - # - # @return [Nanoc::Int::LazyValue] - def map - Nanoc::Int::LazyValue.new(-> { yield(value) }) - end - - contract C::None => self - # @return [void] - def freeze - super - @value.__nanoc_freeze_recursively unless @value[:raw] - self - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/outdatedness_reasons.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/outdatedness_reasons.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/outdatedness_reasons.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/outdatedness_reasons.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Module that contains all outdatedness reasons. - # - # @api private - module OutdatednessReasons - # A generic outdatedness reason. An outdatedness reason is basically a - # descriptive message that explains why a given object is outdated. - class Generic - # @return [String] A descriptive message for this outdatedness reason - attr_reader :message - - # @return [Nanoc::Int::Props] - attr_reader :props - - # @param [String] message The descriptive message for this outdatedness - # reason - def initialize(message, props = Nanoc::Int::Props.new) - @message = message - @props = props - end - end - - CodeSnippetsModified = Generic.new( - 'The code snippets have been modified since the last time the site was compiled.', - Props.new(raw_content: true, attributes: true, compiled_content: true, path: true), - ) - - DependenciesOutdated = Generic.new( - 'This item uses content or attributes that have changed since the last time the site was compiled.', - ) - - NotWritten = Generic.new( - 'This item representation has not yet been written to the output directory (but it does have a path).', - Props.new(raw_content: true, attributes: true, compiled_content: true, path: true), - ) - - RulesModified = Generic.new( - 'The rules file has been modified since the last time the site was compiled.', - Props.new(compiled_content: true, path: true), - ) - - ContentModified = Generic.new( - 'The content of this item has been modified since the last time the site was compiled.', - Props.new(raw_content: true, compiled_content: true), - ) - - class DocumentCollectionExtended < Generic - attr_reader :objects - - def initialize(objects) - super( - 'New items/layouts have been added to the site.', - Props.new(raw_content: true), - ) - - @objects = objects - end - end - - class ItemCollectionExtended < DocumentCollectionExtended - end - - class LayoutCollectionExtended < DocumentCollectionExtended - end - - class AttributesModified < Generic - attr_reader :attributes - - def initialize(attributes) - super( - 'The attributes of this item have been modified since the last time the site was compiled.', - Props.new(attributes: true, compiled_content: true), - ) - - @attributes = attributes - end - end - - UsesAlwaysOutdatedFilter = Generic.new( - 'This item rep uses one or more filters that cannot track dependencies, and will thus always be considered as outdated.', - Props.new(raw_content: true, attributes: true, compiled_content: true), - ) - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/outdatedness_status.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/outdatedness_status.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/outdatedness_status.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/outdatedness_status.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class OutdatednessStatus - attr_reader :reasons - attr_reader :props - - def initialize(reasons: [], props: Props.new) - @reasons = reasons - @props = props - end - - def useful_to_apply?(rule) - (rule.affected_props - @props.active).any? - end - - def update(reason) - self.class.new( - reasons: @reasons + [reason], - props: @props.merge(reason.props), - ) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/pattern.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/pattern.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/pattern.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/pattern.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class Pattern - include Nanoc::Int::ContractsSupport - - contract C::Any => self - def self.from(obj) - case obj - when Nanoc::Int::StringPattern, Nanoc::Int::RegexpPattern - obj - when String - Nanoc::Int::StringPattern.new(obj) - when Regexp - Nanoc::Int::RegexpPattern.new(obj) - when Symbol - Nanoc::Int::StringPattern.new(obj.to_s) - else - raise ArgumentError, "Do not know how to convert `#{obj.inspect}` into a Nanoc::Pattern" - end - end - - def initialize(_obj) - raise NotImplementedError - end - - def match?(_identifier) - raise NotImplementedError - end - - def captures(_identifier) - raise NotImplementedError - end - end - - # @api private - class StringPattern < Pattern - MATCH_OPTS = File::FNM_PATHNAME | File::FNM_EXTGLOB - - contract String => C::Any - def initialize(string) - @string = string - end - - contract C::Or[Nanoc::Identifier, String] => C::Bool - def match?(identifier) - File.fnmatch(@string, identifier.to_s, MATCH_OPTS) - end - - contract C::Or[Nanoc::Identifier, String] => nil - def captures(_identifier) - nil - end - - contract C::None => String - def to_s - @string - end - end - - # @api private - class RegexpPattern < Pattern - contract Regexp => C::Any - def initialize(regexp) - @regexp = regexp - end - - contract C::Or[Nanoc::Identifier, String] => C::Bool - def match?(identifier) - (identifier.to_s =~ @regexp) != nil - end - - contract C::Or[Nanoc::Identifier, String] => C::Maybe[C::ArrayOf[String]] - def captures(identifier) - matches = @regexp.match(identifier.to_s) - matches&.captures - end - - contract C::None => String - def to_s - @regexp.to_s - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/processing_action.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/processing_action.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/processing_action.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/processing_action.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - class ProcessingAction - def serialize - raise NotImplementedError.new('Nanoc::ProcessingAction subclasses must implement #serialize and #to_s') - end - - def to_s - raise NotImplementedError.new('Nanoc::ProcessingAction subclasses must implement #serialize and #to_s') - end - - def inspect - format( - '<%s %s>', - self.class.to_s, - serialize[1..-1].map(&:inspect).join(', '), - ) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/processing_actions/filter.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/processing_actions/filter.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/processing_actions/filter.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/processing_actions/filter.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::ProcessingActions - class Filter < Nanoc::Int::ProcessingAction - # filter :foo - # filter :foo, params - - attr_reader :filter_name - attr_reader :params - - def initialize(filter_name, params) - @filter_name = filter_name - @params = params - end - - def serialize - [:filter, @filter_name, Nanoc::Int::Checksummer.calc(@params)] - end - - def to_s - "filter #{@filter_name.inspect}, #{@params.inspect}" - end - - def hash - self.class.hash ^ filter_name.hash ^ params.hash - end - - def ==(other) - self.class == other.class && filter_name == other.filter_name && params == other.params - end - - def eql?(other) - self == other - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/processing_actions/layout.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/processing_actions/layout.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/processing_actions/layout.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/processing_actions/layout.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::ProcessingActions - class Layout < Nanoc::Int::ProcessingAction - # layout '/foo.erb' - # layout '/foo.erb', params - - attr_reader :layout_identifier - attr_reader :params - - def initialize(layout_identifier, params) - @layout_identifier = layout_identifier - @params = params - end - - def serialize - [:layout, @layout_identifier, Nanoc::Int::Checksummer.calc(@params)] - end - - def to_s - "layout #{@layout_identifier.inspect}, #{@params.inspect}" - end - - def hash - self.class.hash ^ layout_identifier.hash ^ params.hash - end - - def ==(other) - self.class == other.class && layout_identifier == other.layout_identifier && params == other.params - end - - def eql?(other) - self == other - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/processing_actions/snapshot.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/processing_actions/snapshot.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/processing_actions/snapshot.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/processing_actions/snapshot.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::ProcessingActions - class Snapshot < Nanoc::Int::ProcessingAction - # snapshot :before_layout - # snapshot :before_layout, path: '/about.md' - - include Nanoc::Int::ContractsSupport - - attr_reader :snapshot_names - attr_reader :paths - - contract C::IterOf[Symbol], C::IterOf[String] => C::Any - def initialize(snapshot_names, paths) - @snapshot_names = snapshot_names - @paths = paths - end - - contract C::None => Array - def serialize - [:snapshot, @snapshot_names, true, @paths] - end - - contract C::KeywordArgs[snapshot_names: C::Optional[C::IterOf[Symbol]], paths: C::Optional[C::IterOf[String]]] => self - def update(snapshot_names: [], paths: []) - self.class.new(@snapshot_names + snapshot_names.to_a, @paths + paths.to_a) - end - - contract C::None => String - def to_s - "snapshot #{@snapshot_names.inspect}, paths: #{@paths.inspect}" - end - - def hash - self.class.hash ^ snapshot_names.hash ^ paths.hash - end - - def ==(other) - self.class == other.class && snapshot_names == other.snapshot_names && paths == other.paths - end - - def eql?(other) - self == other - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/processing_actions.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/processing_actions.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/processing_actions.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/processing_actions.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -require_relative 'processing_actions/filter' -require_relative 'processing_actions/layout' -require_relative 'processing_actions/snapshot' diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/props.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/props.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/props.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/props.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,148 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class Props - include Nanoc::Int::ContractsSupport - - attr_reader :attributes - attr_reader :raw_content - - # TODO: Split raw_content for documents and collections - C_RAW_CONTENT = C::Or[C::IterOf[C::Or[String, Regexp]], C::Bool] - C_ATTRS = C::Or[C::IterOf[Symbol], C::Bool] - contract C::KeywordArgs[raw_content: C::Optional[C_RAW_CONTENT], attributes: C::Optional[C_ATTRS], compiled_content: C::Optional[C::Bool], path: C::Optional[C::Bool]] => C::Any - def initialize(raw_content: false, attributes: false, compiled_content: false, path: false) - @compiled_content = compiled_content - @path = path - - @attributes = - case attributes - when Set - attributes - when Enumerable - Set.new(attributes) - else - attributes - end - - @raw_content = - case raw_content - when Set - raw_content - when Enumerable - Set.new(raw_content) - else - raw_content - end - end - - contract C::None => String - def inspect - (+'').tap do |s| - s << 'Props(' - s << (raw_content? ? 'r' : '_') - s << (attributes? ? 'a' : '_') - s << (compiled_content? ? 'c' : '_') - s << (path? ? 'p' : '_') - s << ')' - end - end - - contract C::None => String - def to_s - (+'').tap do |s| - s << (raw_content? ? 'r' : '_') - s << (attributes? ? 'a' : '_') - s << (compiled_content? ? 'c' : '_') - s << (path? ? 'p' : '_') - end - end - - contract C::None => C::Bool - def raw_content? - case @raw_content - when Enumerable - @raw_content.any? - else - @raw_content - end - end - - contract C::None => C::Bool - def attributes? - case @attributes - when Enumerable - @attributes.any? - else - @attributes - end - end - - contract C::None => C::Bool - def compiled_content? - @compiled_content - end - - contract C::None => C::Bool - def path? - @path - end - - contract Nanoc::Int::Props => Nanoc::Int::Props - def merge(other) - Props.new( - raw_content: merge_raw_content(other), - attributes: merge_attributes(other), - compiled_content: compiled_content? || other.compiled_content?, - path: path? || other.path?, - ) - end - - def merge_raw_content(other) - merge_prop(raw_content, other.raw_content) - end - - def merge_attributes(other) - merge_prop(attributes, other.attributes) - end - - def merge_prop(own, other) - case own - when true - true - when false - other - else - case other - when true - true - when false - own - else - own + other - end - end - end - - contract C::None => Set - def active - Set.new.tap do |pr| - pr << :raw_content if raw_content? - pr << :attributes if attributes? - pr << :compiled_content if compiled_content? - pr << :path if path? - end - end - - contract C::None => Hash - def to_h - { - raw_content: raw_content, - attributes: attributes, - compiled_content: compiled_content?, - path: path?, - } - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/site.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/site.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/site.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/site.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class Site - include Nanoc::Int::ContractsSupport - - attr_reader :code_snippets - attr_reader :config - attr_accessor :data_source - - contract C::KeywordArgs[config: Nanoc::Int::Configuration, code_snippets: C::IterOf[Nanoc::Int::CodeSnippet], data_source: C::Named['Nanoc::DataSource']] => C::Any - def initialize(config:, code_snippets:, data_source:) - @config = config - @code_snippets = code_snippets - @data_source = data_source - - @preprocessed = false - - ensure_identifier_uniqueness(@data_source.items, 'item') - ensure_identifier_uniqueness(@data_source.layouts, 'layout') - end - - contract C::None => self - def compile - Nanoc::Int::Compiler.new_for(self).run_until_end - self - end - - def mark_as_preprocessed - @preprocessed = true - end - - def preprocessed? - @preprocessed - end - - def items - @data_source.items - end - - def layouts - @data_source.layouts - end - - contract C::None => self - def freeze - config.freeze - items.freeze - layouts.freeze - code_snippets.__nanoc_freeze_recursively - self - end - - contract C::IterOf[C::Or[Nanoc::Int::Item, Nanoc::Int::Layout]], String => self - def ensure_identifier_uniqueness(objects, type) - seen = Set.new - objects.each do |obj| - if seen.include?(obj.identifier) - raise Nanoc::Int::Errors::DuplicateIdentifier.new(obj.identifier, type) - end - - seen << obj.identifier - end - self - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities/snapshot_def.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities/snapshot_def.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities/snapshot_def.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities/snapshot_def.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - module Int - class SnapshotDef - include Nanoc::Int::ContractsSupport - - attr_reader :name - attr_reader :binary - - contract Symbol, C::KeywordArgs[binary: C::Optional[C::Bool]] => C::Any - def initialize(name, binary:) - @name = name - @binary = binary - end - - def binary? - @binary - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/entities.rb nanoc-4.11.14/nanoc/lib/nanoc/base/entities.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/entities.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/entities.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -require_relative 'entities/context' -require_relative 'entities/directed_graph' - -require_relative 'entities/identifier' -require_relative 'entities/content' -require_relative 'entities/processing_action' -require_relative 'entities/processing_actions' - -require_relative 'entities/identifiable_collection' -require_relative 'entities/item_collection' -require_relative 'entities/layout_collection' - -require_relative 'entities/code_snippet' -require_relative 'entities/configuration' -require_relative 'entities/lazy_value' -require_relative 'entities/document' -require_relative 'entities/item' -require_relative 'entities/item_rep' -require_relative 'entities/layout' -require_relative 'entities/pattern' -require_relative 'entities/props' -require_relative 'entities/action_sequence' -require_relative 'entities/site' -require_relative 'entities/snapshot_def' - -require_relative 'entities/checksum_collection' -require_relative 'entities/outdatedness_status' -require_relative 'entities/outdatedness_reasons' -require_relative 'entities/dependency' diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/error.rb nanoc-4.11.14/nanoc/lib/nanoc/base/error.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/error.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/error.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - # Generic error. Superclass for all Nanoc-specific errors. - class Error < ::StandardError - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/errors.rb nanoc-4.11.14/nanoc/lib/nanoc/base/errors.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/errors.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/errors.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,248 +1,65 @@ # frozen_string_literal: true -module Nanoc::Int - # Module that contains all Nanoc-specific errors. - # - # @api private - module Errors - Generic = ::Nanoc::Error - - # Generic trivial error. Superclass for all Nanoc-specific errors that are - # considered "trivial", i.e. errors that do not require a full crash report. - class GenericTrivial < Generic - end - - # Error that is raised when compilation of an item rep fails. The - # underlying error is available by calling `#unwrap`. - class CompilationError < Generic - attr_reader :item_rep - - def initialize(wrapped, item_rep) - @wrapped = wrapped - @item_rep = item_rep - end - - def unwrap - @wrapped - end - end - - # Error that is raised when a site is loaded that uses a data source with - # an unknown identifier. - class UnknownDataSource < Generic - # @param [String] data_source_name The data source name for which no - # data source could be found - def initialize(data_source_name) - super("The data source specified in the site’s configuration file, “#{data_source_name}”, does not exist.") - end - end - - # Error that is raised during site compilation when an item uses a layout - # that is not present in the site. - class UnknownLayout < Generic - # @param [String] layout_identifier The layout identifier for which no - # layout could be found - def initialize(layout_identifier) - super("The site does not have a layout with identifier “#{layout_identifier}”.") - end - end - - # Error that is raised during site compilation when an item uses a filter - # that is not known. - class UnknownFilter < Generic - # @param [Symbol] filter_name The filter name for which no filter could - # be found - def initialize(filter_name) - super("The requested filter, “#{filter_name}”, does not exist.") - end - end - - # Error that is raised during site compilation when a layout is compiled - # for which the filter cannot be determined. This is similar to the - # {UnknownFilter} error, but specific for filters for layouts. - class CannotDetermineFilter < Generic - # @param [String] layout_identifier The identifier of the layout for - # which the filter could not be determined - def initialize(layout_identifier) - super("The filter to be used for the “#{layout_identifier}” layout could not be determined. Make sure the layout does have a filter.") - end - end - - # Error that is raised during site compilation when an item (directly or - # indirectly) includes its own item content, leading to endless recursion. - class DependencyCycle < Generic - def initialize(stack) - start_idx = stack.index(stack.last) - cycle = stack[start_idx..-2] - - msg_bits = [] - msg_bits << 'The site cannot be compiled because there is a dependency cycle:' - msg_bits << '' - cycle.each.with_index do |r, i| - msg_bits << " (#{i + 1}) item #{r.item.identifier}, rep #{r.name.inspect}, uses compiled content of" +module Nanoc + module Int + # Module that contains all Nanoc-specific errors. + # + # @api private + module Errors + Generic = ::Nanoc::Core::Error + + NoSuchSnapshot = ::Nanoc::Core::Errors::NoSuchSnapshot + CannotGetCompiledContentOfBinaryItem = ::Nanoc::Core::Errors::CannotGetCompiledContentOfBinaryItem + CannotGetParentOrChildrenOfNonLegacyItem = ::Nanoc::Core::Errors::CannotGetParentOrChildrenOfNonLegacyItem + CannotLayoutBinaryItem = ::Nanoc::Core::Errors::CannotLayoutBinaryItem + UnknownLayout = ::Nanoc::Core::Errors::UnknownLayout + CannotUseBinaryFilter = ::Nanoc::Core::Errors::CannotUseBinaryFilter + CannotUseTextualFilter = ::Nanoc::Core::Errors::CannotUseTextualFilter + + # Error that is raised during site compilation when a layout is compiled + # for which the filter cannot be determined. This is similar to the + # {UnknownFilter} error, but specific for filters for layouts. + class CannotDetermineFilter < Generic + # @param [String] layout_identifier The identifier of the layout for + # which the filter could not be determined + def initialize(layout_identifier) + super("The filter to be used for the “#{layout_identifier}” layout could not be determined. Make sure the layout does have a filter.") end - msg_bits << msg_bits.pop + ' (1)' - - super(msg_bits.map { |x| x + "\n" }.join('')) - end - end - - # Error that is raised when no rules file can be found in the current - # working directory. - class NoRulesFileFound < Generic - def initialize - super('This site does not have a rules file, which is required for Nanoc sites.') - end - end - - # Error that is raised when no compilation rule that can be applied to the - # current item can be found. - class NoMatchingCompilationRuleFound < Generic - # @param [Nanoc::Int::Item] item The item for which no compilation rule - # could be found - def initialize(item) - super("No compilation rules were found for the “#{item.identifier}” item.") - end - end - - # Error that is raised when no routing rule that can be applied to the - # current item can be found. - class NoMatchingRoutingRuleFound < Generic - # @param [Nanoc::Int::ItemRep] rep The item repiresentation for which no - # routing rule could be found - def initialize(rep) - super("No routing rules were found for the “#{rep.item.identifier}” item (rep “#{rep.name}”).") - end - end - - # Error that is raised when an rep cannot be compiled because it depends - # on other representations. - class UnmetDependency < Generic - # @return [Nanoc::Int::ItemRep] The item representation that cannot yet be - # compiled - attr_reader :rep - - # @param [Nanoc::Int::ItemRep] rep The item representation that cannot yet be - # compiled - def initialize(rep) - @rep = rep - super("The current item cannot be compiled yet because of an unmet dependency on the “#{rep.item.identifier}” item (rep “#{rep.name}”).") - end - end - - # Error that is raised when a binary item is attempted to be laid out. - class CannotLayoutBinaryItem < Generic - # @param [Nanoc::Int::ItemRep] rep The item representation that was attempted - # to be laid out - def initialize(rep) - super("The “#{rep.item.identifier}” item (rep “#{rep.name}”) cannot be laid out because it is a binary item. If you are getting this error for an item that should be textual instead of binary, make sure that its extension is included in the text_extensions array in the site configuration.") - end - end - - # Error that is raised when a textual filter is attempted to be applied to - # a binary item representation. - class CannotUseTextualFilter < Generic - # @param [Nanoc::Int::ItemRep] rep The item representation that was - # attempted to be filtered - # - # @param [Class] filter_class The filter class that was used - def initialize(rep, filter_class) - super("The “#{filter_class.inspect}” filter cannot be used to filter the “#{rep.item.identifier}” item (rep “#{rep.name}”), because textual filters cannot be used on binary items.") end - end - - # Error that is raised when a binary filter is attempted to be applied to - # a textual item representation. - class CannotUseBinaryFilter < Generic - # @param [Nanoc::Int::ItemRep] rep The item representation that was - # attempted to be filtered - # - # @param [Class] filter_class The filter class that was used - def initialize(rep, filter_class) - super("The “#{filter_class.inspect}” filter cannot be used to filter the “#{rep.item.identifier}” item (rep “#{rep.name}”), because binary filters cannot be used on textual items. If you are getting this error for an item that should be textual instead of binary, make sure that its extension is included in the text_extensions array in the site configuration.") - end - end - # Error that is raised when the compiled content at a non-existing snapshot - # is requested. - class NoSuchSnapshot < Generic - # @return [Nanoc::Int::ItemRep] The item rep from which the compiled content - # was requested - attr_reader :item_rep - - # @return [Symbol] The requested snapshot - attr_reader :snapshot - - # @param [Nanoc::Int::ItemRep] item_rep The item rep from which the compiled - # content was requested - # - # @param [Symbol] snapshot The requested snapshot - def initialize(item_rep, snapshot) - @item_rep = item_rep - @snapshot = snapshot - super("The “#{item_rep.inspect}” item rep does not have a snapshot “#{snapshot.inspect}”") - end - end - - # Error that is raised when a snapshot with an existing name is made. - class CannotCreateMultipleSnapshotsWithSameName < Generic - # @param [Nanoc::Int::ItemRep] rep The item representation for which a - # snapshot was attempted to be made - # - # @param [Symbol] snapshot The name of the snapshot that was attempted to - # be made - def initialize(rep, snapshot) - super("Attempted to create a snapshot with a duplicate name #{snapshot.inspect} for the item rep #{rep}") - end - end - - # Error that is raised when the compiled content of a binary item is attempted to be accessed. - class CannotGetCompiledContentOfBinaryItem < Generic - # @param [Nanoc::Int::ItemRep] rep The binary item representation whose compiled content was attempted to be accessed - def initialize(rep) - super("You cannot access the compiled content of a binary item representation (but you can access the path). The offending item rep is #{rep}.") - end - end - - # Error that is raised when multiple items or layouts with the same identifier exist. - class DuplicateIdentifier < Generic - def initialize(identifier, type) - super("There are multiple #{type}s with the #{identifier} identifier.") - end - end - - # Error that is raised when attempting to call #parent or #children on an item with a legacy identifier. - class CannotGetParentOrChildrenOfNonLegacyItem < Generic - def initialize(identifier) - super("You cannot get the parent or children of an item that has a “full” identifier (#{identifier}). Getting the parent or children of an item is only possible for items that have a legacy identifier.") - end - end - - class UndefinedFilterForLayout < Generic - def initialize(layout) - super("There is no filter defined for the layout #{layout.identifier}") + # Error that is raised when no rules file can be found in the current + # working directory. + class NoRulesFileFound < Generic + def initialize + super('This site does not have a rules file, which is required for Nanoc sites.') + end end - end - class OutputNotWritten < Generic - def initialize(filter_name, output_filename) - super("The #{filter_name.inspect} filter did not write anything to the required output file, #{output_filename}.") + # Error that is raised when no compilation rule that can be applied to the + # current item can be found. + class NoMatchingCompilationRuleFound < Generic + # @param [Nanoc::Core::Item] item The item for which no compilation rule + # could be found + def initialize(item) + super("No compilation rules were found for the “#{item.identifier}” item.") + end end - end - class FilterReturnedNil < Generic - def initialize(filter_name) - super("The #{filter_name.inspect} filter returned nil, but is required to return a String.") + # Error that is raised when no routing rule that can be applied to the + # current item can be found. + class NoMatchingRoutingRuleFound < Generic + # @param [Nanoc::Core::ItemRep] rep The item repiresentation for which no + # routing rule could be found + def initialize(rep) + super("No routing rules were found for the “#{rep.item.identifier}” item (rep “#{rep.name}”).") + end end - end - class AmbiguousMetadataAssociation < Generic - def initialize(content_filenames, meta_filename) - super("There are multiple content files (#{content_filenames.join(', ')}) that could match the file containing metadata (#{meta_filename}).") + class AmbiguousMetadataAssociation < Generic + def initialize(content_filenames, meta_filename) + super("There are multiple content files (#{content_filenames.sort.join(', ')}) that could match the file containing metadata (#{meta_filename}).") + end end end - - class InternalInconsistency < Generic - end end end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/feature.rb nanoc-4.11.14/nanoc/lib/nanoc/base/feature.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/feature.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/feature.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - # @api private - # - # @example Defining a feature and checking its enabledness - # - # Nanoc::Feature.define('environments', version: '4.3') - # Nanoc::Feature.enabled?(Nanoc::Feature::ENVIRONMENTS) - # - module Feature - # Defines a new feature with the given name, experimental in the given - # version. The feature will be made available as a constant with the same - # name, in uppercase, on the Nanoc::Feature module. - # - # @example Defining Nanoc::Feature::ENVIRONMENTS - # - # Nanoc::Feature.define('environments', version: '4.3') - # - # @param name The name of the feature - # - # @param version The minor version in which the feature is considered - # experimental. - # - # @return [void] - def self.define(name, version:) - repo[name] = version - const_set(name.upcase, name) - end - - # Undefines the feature with the given name. For testing purposes only. - # - # @param name The name of the feature - # - # @return [void] - # - # @private - def self.undefine(name) - repo.delete(name) - remove_const(name.upcase) - end - - # @param [String] feature_name - # - # @return [Boolean] Whether or not the feature with the given name is enabled - def self.enabled?(feature_name) - enabled_features.include?(feature_name) || - enabled_features.include?('all') - end - - # @api private - def self.enable(feature_name) - raise ArgumentError, 'no block given' unless block_given? - - if enabled?(feature_name) - yield - else - begin - enabled_features << feature_name - yield - ensure - enabled_features.delete(feature_name) - end - end - end - - # @api private - def self.reset_caches - @enabled_features = nil - end - - # @api private - def self.enabled_features - @enabled_features ||= Set.new(ENV.fetch('NANOC_FEATURES', '').split(',')) - end - - # @api private - def self.repo - @repo ||= {} - end - - # @return [Enumerable] Names of features that still exist, but - # should not be considered as experimental in the current version of - # Nanoc. - def self.all_outdated - repo.keys.reject do |name| - version = repo[name] - Nanoc::VERSION.start_with?(version) - end - end - end -end - -# Tracking issue: -# https://github.com/nanoc/features/issues/24 -Nanoc::Feature.define('live_cmd', version: '4.11') - -# Tracking issue: -# https://github.com/nanoc/features/issues/40 -Nanoc::Feature.define('toml', version: '4.11') diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/action_sequence_store.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/action_sequence_store.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/action_sequence_store.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/action_sequence_store.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Stores action sequences for objects that can be run through a rule (item - # representations and layouts). - # - # @api private - class ActionSequenceStore < ::Nanoc::Int::Store - include Nanoc::Int::ContractsSupport - - contract C::KeywordArgs[config: Nanoc::Int::Configuration] => C::Any - def initialize(config:) - super(Nanoc::Int::Store.tmp_path_for(config: config, store_name: 'rule_memory'), 1) - - @action_sequences = {} - end - - # @param [Nanoc::Int::ItemRep, Nanoc::Int::Layout] obj The item representation or - # the layout to get the action sequence for - # - # @return [Array] The action sequence for the given object - def [](obj) - @action_sequences[obj.reference] - end - - # @param [Nanoc::Int::ItemRep, Nanoc::Int::Layout] obj The item representation or - # the layout to set the action sequence for - # - # @param [Array] action_sequence The new action sequence to be stored - # - # @return [void] - def []=(obj, action_sequence) - @action_sequences[obj.reference] = action_sequence - end - - protected - - # @see Nanoc::Int::Store#data - def data - @action_sequences - end - - # @see Nanoc::Int::Store#data= - def data=(new_data) - @action_sequences = new_data - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/aggregate_data_source.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/aggregate_data_source.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/aggregate_data_source.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/aggregate_data_source.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - class AggregateDataSource < Nanoc::DataSource - def initialize(data_sources, config) - super({}, '/', '/', {}) - - @data_sources = data_sources - @config = config - end - - def items - @_items ||= begin - objs = @data_sources.flat_map(&:items) - Nanoc::Int::ItemCollection.new(@config, objs) - end - end - - def layouts - @_layouts ||= begin - objs = @data_sources.flat_map(&:layouts) - Nanoc::Int::LayoutCollection.new(@config, objs) - end - end - - def item_changes - SlowEnumeratorTools.merge(@data_sources.map(&:item_changes)) - end - - def layout_changes - SlowEnumeratorTools.merge(@data_sources.map(&:layout_changes)) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/checksum_store.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/checksum_store.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/checksum_store.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/checksum_store.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Stores checksums for objects in order to be able to detect whether a file - # has changed since the last site compilation. - # - # @api private - class ChecksumStore < ::Nanoc::Int::Store - include Nanoc::Int::ContractsSupport - - attr_writer :checksums - attr_accessor :objects - - c_obj = C::Or[Nanoc::Int::Item, Nanoc::Int::Layout, Nanoc::Int::Configuration, Nanoc::Int::CodeSnippet] - - contract C::KeywordArgs[config: Nanoc::Int::Configuration, objects: C::IterOf[c_obj]] => C::Any - def initialize(config:, objects:) - super(Nanoc::Int::Store.tmp_path_for(config: config, store_name: 'checksums'), 2) - - @objects = objects - - @checksums = {} - end - - contract c_obj => C::Maybe[String] - def [](obj) - @checksums[obj.reference] - end - - contract c_obj => self - def add(obj) - if obj.is_a?(Nanoc::Int::Document) - @checksums[[obj.reference, :content]] = Nanoc::Int::Checksummer.calc_for_content_of(obj) - end - - if obj.is_a?(Nanoc::Int::Document) || obj.is_a?(Nanoc::Int::Configuration) - @checksums[[obj.reference, :each_attribute]] = Nanoc::Int::Checksummer.calc_for_each_attribute_of(obj) - end - - @checksums[obj.reference] = Nanoc::Int::Checksummer.calc(obj) - - self - end - - contract c_obj => C::Maybe[String] - def content_checksum_for(obj) - @checksums[[obj.reference, :content]] - end - - contract c_obj => C::Maybe[C::HashOf[Symbol, String]] - def attributes_checksum_for(obj) - @checksums[[obj.reference, :each_attribute]] - end - - protected - - def data - @checksums - end - - def data=(new_data) - references = Set.new(@objects.map(&:reference)) - - @checksums = {} - new_data.each_pair do |key, checksum| - if references.include?(key) || references.include?(key.first) - @checksums[key] = checksum - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/compiled_content_cache.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/compiled_content_cache.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/compiled_content_cache.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/compiled_content_cache.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Represents a cache than can be used to store already compiled content, - # to prevent it from being needlessly recompiled. - # - # @api private - class CompiledContentCache < ::Nanoc::Int::Store - include Nanoc::Int::ContractsSupport - - contract C::KeywordArgs[config: Nanoc::Int::Configuration] => C::Any - def initialize(config:) - super(Nanoc::Int::Store.tmp_path_for(config: config, store_name: 'compiled_content'), 2) - - @cache = {} - end - - contract Nanoc::Int::ItemRep => C::Maybe[C::HashOf[Symbol => Nanoc::Int::Content]] - # Returns the cached compiled content for the given item representation. - # - # This cached compiled content is a hash where the keys are the snapshot - # names. and the values the compiled content at the given snapshot. - def [](rep) - item_cache = @cache[rep.item.identifier] || {} - item_cache[rep.name] - end - - contract Nanoc::Int::ItemRep, C::HashOf[Symbol => Nanoc::Int::Content] => C::HashOf[Symbol => Nanoc::Int::Content] - # Sets the compiled content for the given representation. - # - # This cached compiled content is a hash where the keys are the snapshot - # names. and the values the compiled content at the given snapshot. - def []=(rep, content) - @cache[rep.item.identifier] ||= {} - @cache[rep.item.identifier][rep.name] = content - end - - def prune(items:) - item_identifiers = Set.new(items.map(&:identifier)) - - @cache.keys.each do |key| - @cache.delete(key) unless item_identifiers.include?(key) - end - end - - protected - - def data - @cache - end - - def data=(new_data) - @cache = {} - - new_data.each_pair do |item_identifier, content_per_rep| - @cache[item_identifier] ||= content_per_rep - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/config_loader.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/config_loader.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/config_loader.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/config_loader.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class ConfigLoader - class NoConfigFileFoundError < ::Nanoc::Error - def initialize - super('No configuration file found') - end - end - - class NoParentConfigFileFoundError < ::Nanoc::Error - def initialize(filename) - super("There is no parent configuration file at #{filename}") - end - end - - class CyclicalConfigFileError < ::Nanoc::Error - def initialize(filename) - super("The parent configuration file at #{filename} includes one of its descendants") - end - end - - # @return [Boolean] - def self.cwd_is_nanoc_site? - !config_filename_for_cwd.nil? - end - - # @return [String] - def self.config_filename_for_cwd - filenames = - if Nanoc::Feature.enabled?(Nanoc::Feature::TOML) - %w[nanoc.yaml config.yaml nanoc.toml] - else - %w[nanoc.yaml config.yaml] - end - candidate = filenames.find { |f| File.file?(f) } - candidate && File.expand_path(candidate) - end - - def new_from_cwd - # Determine path - filename = self.class.config_filename_for_cwd - raise NoConfigFileFoundError if filename.nil? - - # Read - config = - apply_parent_config( - Nanoc::Int::Configuration.new( - hash: load_file(filename), - dir: File.dirname(filename), - ), - [filename], - ).with_defaults - - # Load environment - config.with_environment - end - - def load_file(filename) - case File.extname(filename) - when '.yaml' - YAML.load_file(filename) - when '.toml' - Tomlrb.load_file(filename) - else - raise Nanoc::Int::Errors::InternalInconsistency, 'Unhandled config file extension' - end - end - - # @api private - def apply_parent_config(config, processed_paths = []) - parent_path = config[:parent_config_file] - return config if parent_path.nil? - - # Get absolute path - parent_path = File.absolute_path(parent_path, File.dirname(processed_paths.last)) - unless File.file?(parent_path) - raise NoParentConfigFileFoundError.new(parent_path) - end - - # Check recursion - if processed_paths.include?(parent_path) - raise CyclicalConfigFileError.new(parent_path) - end - - # Load - parent_config = Nanoc::Int::Configuration.new(hash: load_file(parent_path), dir: config.dir) - full_parent_config = apply_parent_config(parent_config, processed_paths + [parent_path]) - full_parent_config.merge(config.without(:parent_config_file)) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/data_source.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/data_source.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/data_source.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/data_source.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,168 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - # Responsible for loading site data. It is the (abstract) superclass for all - # data sources. Subclasses must at least implement the data reading methods - # ({#items} and {#layouts}). - # - # Apart from the methods for loading and storing data, there are the {#up} - # and {#down} methods for bringing up and tearing down the connection to the - # data source. These should be overridden in subclasses. The {#loading} - # method wraps {#up} and {#down}. {#loading} is a convenience method for the - # more low-level methods {#use} and {#unuse}, which respectively increment - # and decrement the reference count; when the reference count goes from 0 to - # 1, the data source will be loaded ({#up} will be called) and when the - # reference count goes from 1 to 0, the data source will be unloaded - # ({#down} will be called). - # - # @abstract Subclasses should at least implement {#items} and {#layouts}. - class DataSource - # @return [String] The root path where items returned by this data source - # should be mounted. - attr_reader :items_root - - # @return [String] The root path where layouts returned by this data - # source should be mounted. - attr_reader :layouts_root - - # @return [Hash] The configuration for this data source. For example, - # online data sources could contain authentication details. - attr_reader :config - - extend DDPlugin::Plugin - - def initialize(site_config, items_root, layouts_root, config) - @site_config = site_config - @items_root = items_root - @layouts_root = layouts_root - @config = config || {} - - @references = 0 - end - - # Marks the data source as used by the caller. - # - # Calling this method increases the internal reference count. When the - # data source is used for the first time (first {#use} call), the data - # source will be loaded ({#up} will be called). - # - # @return [void] - def use - up if @references.zero? - @references += 1 - end - - # Marks the data source as unused by the caller. - # - # Calling this method decreases the internal reference count. When the - # reference count reaches zero, i.e. when the data source is not used any - # more, the data source will be unloaded ({#down} will be called). - # - # @return [void] - def unuse - @references -= 1 - down if @references.zero? - end - - # Brings up the connection to the data. Depending on the way data is - # stored, this may not be necessary. This is the ideal place to connect to - # the database, for example. - # - # Subclasses may override this method, but are not required to do so; the - # default implementation simply does nothing. - # - # @return [void] - def up; end - - # Brings down the connection to the data. This method should undo the - # effects of the {#up} method. For example, a database connection - # established in {#up} should be closed in this method. - # - # Subclasses may override this method, but are not required to do so; the - # default implementation simply does nothing. - # - # @return [void] - def down; end - - # Returns the collection of items (represented by {Nanoc::Int::Item}) in - # this site. The default implementation simply returns an empty array. - # - # Subclasses should not prepend `items_root` to the item's identifiers, as - # this will be done automatically. - # - # Subclasses may override this method, but are not required to do so; the - # default implementation simply does nothing. - # - # @return [Enumerable] The collection of items - def items - [] - end - - # @api private - def item_changes - warn "Caution: Data source #{self.class.identifier.inspect} does not implement #item_changes; live compilation will not pick up changes in this data source." - Enumerator.new { |_y| sleep } - end - - # @api private - def layout_changes - warn "Caution: Data source #{self.class.identifier.inspect} does not implement #layout_changes; live compilation will not pick up changes in this data source." - Enumerator.new { |_y| sleep } - end - - # Returns the collection of layouts (represented by {Nanoc::Int::Layout}) in - # this site. The default implementation simply returns an empty array. - # - # Subclasses should prepend `layout_root` to the layout's identifiers, - # since this is not done automatically. - # - # Subclasses may override this method, but are not required to do so; the - # default implementation simply does nothing. - # - # @return [Enumerable] The collection of layouts - def layouts - [] - end - - # Creates a new in-memory item instance. This is intended for use within - # the {#items} method. - # - # @param [String, Proc] content The uncompiled item content - # (if it is a textual item) or the path to the filename containing the - # content (if it is a binary item). - # - # @param [Hash, Proc] attributes A hash containing this item's attributes. - # - # @param [String] identifier This item's identifier. - # - # @param [Boolean] binary Whether or not this item is binary - # - # @param [String, nil] checksum_data - # - # @param [String, nil] content_checksum_data - # - # @param [String, nil] attributes_checksum_data - def new_item(content, attributes, identifier, binary: false, checksum_data: nil, content_checksum_data: nil, attributes_checksum_data: nil) - content = Nanoc::Int::Content.create(content, binary: binary) - Nanoc::Int::Item.new(content, attributes, identifier, checksum_data: checksum_data, content_checksum_data: content_checksum_data, attributes_checksum_data: attributes_checksum_data) - end - - # Creates a new in-memory layout instance. This is intended for use within - # the {#layouts} method. - # - # @param [String] raw_content The raw content of this layout. - # - # @param [Hash] attributes A hash containing this layout's attributes. - # - # @param [String] identifier This layout's identifier. - # - # @param [String, nil] checksum_data - # - # @param [String, nil] content_checksum_data - # - # @param [String, nil] attributes_checksum_data - def new_layout(raw_content, attributes, identifier, checksum_data: nil, content_checksum_data: nil, attributes_checksum_data: nil) - Nanoc::Int::Layout.new(raw_content, attributes, identifier, checksum_data: checksum_data, content_checksum_data: content_checksum_data, attributes_checksum_data: attributes_checksum_data) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/dependency_store.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/dependency_store.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/dependency_store.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/dependency_store.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,202 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class DependencyStore < ::Nanoc::Int::Store - include Nanoc::Int::ContractsSupport - - attr_reader :items - attr_reader :layouts - - contract Nanoc::Int::ItemCollection, Nanoc::Int::LayoutCollection, Nanoc::Int::Configuration => C::Any - def initialize(items, layouts, config) - super(Nanoc::Int::Store.tmp_path_for(config: config, store_name: 'dependencies'), 5) - - @items = items - @layouts = layouts - - @refs2objs = {} - items.each { |o| add_vertex_for(o) } - layouts.each { |o| add_vertex_for(o) } - add_vertex_for(config) - add_vertex_for(items) - add_vertex_for(layouts) - - @new_objects = [] - @graph = Nanoc::Int::DirectedGraph.new([nil] + objs2refs(@items) + objs2refs(@layouts)) - end - - C_OBJ_SRC = Nanoc::Int::Item - C_OBJ_DST = C::Or[Nanoc::Int::Item, Nanoc::Int::Layout, Nanoc::Int::Configuration, Nanoc::Int::IdentifiableCollection] - - contract C_OBJ_SRC => C::ArrayOf[Nanoc::Int::Dependency] - def dependencies_causing_outdatedness_of(object) - objects_causing_outdatedness_of(object).map do |other_object| - props = props_for(other_object, object) - - Nanoc::Int::Dependency.new( - other_object, - object, - Nanoc::Int::Props.new( - raw_content: props.fetch(:raw_content, false), - attributes: props.fetch(:attributes, false), - compiled_content: props.fetch(:compiled_content, false), - path: props.fetch(:path, false), - ), - ) - end - end - - def items=(items) - @items = items - items.each { |o| @refs2objs[obj2ref(o)] = o } - add_vertex_for(items) - end - - def layouts=(layouts) - @layouts = layouts - layouts.each { |o| @refs2objs[obj2ref(o)] = o } - add_vertex_for(layouts) - end - - def new_items - @new_objects.select { |o| o.is_a?(Nanoc::Int::Item) } - end - - def new_layouts - @new_objects.select { |o| o.is_a?(Nanoc::Int::Layout) } - end - - # Returns the direct dependencies for the given object. - # - # The direct dependencies of the given object include the items and - # layouts that, when outdated will cause the given object to be marked as - # outdated. Indirect dependencies will not be returned (e.g. if A depends - # on B which depends on C, then the direct dependencies of A do not - # include C). - # - # The direct predecessors can include nil, which indicates an item that is - # no longer present in the site. - # - # @param [Nanoc::Int::Item, Nanoc::Int::Layout] object The object for - # which to fetch the direct predecessors - # - # @return [Array] The direct - # predecessors of - # the given object - def objects_causing_outdatedness_of(object) - refs2objs(@graph.direct_predecessors_of(obj2ref(object))) - end - - C_RAW_CONTENT = C::Or[C::IterOf[C::Or[String, Regexp]], C::Bool] - C_ATTR = C::Or[C::IterOf[Symbol], C::Bool] - C_KEYWORD_PROPS = C::KeywordArgs[raw_content: C::Optional[C_RAW_CONTENT], attributes: C::Optional[C_ATTR], compiled_content: C::Optional[C::Bool], path: C::Optional[C::Bool]] - - contract C::Maybe[C_OBJ_SRC], C::Maybe[C_OBJ_DST], C_KEYWORD_PROPS => C::Any - # Records a dependency from `src` to `dst` in the dependency graph. When - # `dst` is oudated, `src` will also become outdated. - # - # @param [Nanoc::Int::Item, Nanoc::Int::Layout] src The source of the dependency, - # i.e. the object that will become outdated if dst is outdated - # - # @param [Nanoc::Int::Item, Nanoc::Int::Layout] dst The destination of the - # dependency, i.e. the object that will cause the source to become - # outdated if the destination is outdated - # - # @return [void] - def record_dependency(src, dst, raw_content: false, attributes: false, compiled_content: false, path: false) - return if src == dst - - add_vertex_for(src) - add_vertex_for(dst) - - src_ref = obj2ref(src) - dst_ref = obj2ref(dst) - - existing_props = Nanoc::Int::Props.new(@graph.props_for(dst_ref, src_ref) || {}) - new_props = Nanoc::Int::Props.new(raw_content: raw_content, attributes: attributes, compiled_content: compiled_content, path: path) - props = existing_props.merge(new_props) - - @graph.add_edge(dst_ref, src_ref, props: props.to_h) - end - - def add_vertex_for(obj) - @refs2objs[obj2ref(obj)] = obj - end - - # Empties the list of dependencies for the given object. This is necessary - # before recompiling the given object, because otherwise old dependencies - # will stick around and new dependencies will appear twice. This function - # removes all incoming edges for the given vertex. - # - # @param [Nanoc::Int::Item, Nanoc::Int::Layout] object The object for which to - # forget all dependencies - # - # @return [void] - def forget_dependencies_for(object) - @graph.delete_edges_to(obj2ref(object)) - end - - protected - - def obj2ref(obj) - obj&.reference - end - - def ref2obj(reference) - if reference - @refs2objs[reference] - else - nil - end - end - - def objs2refs(objs) - objs.map { |o| obj2ref(o) } - end - - def refs2objs(refs) - refs.map { |r| ref2obj(r) } - end - - def props_for(from, to) - props = @graph.props_for(obj2ref(from), obj2ref(to)) || {} - - if props.values.any? { |v| v } - props - else - { raw_content: true, attributes: true, compiled_content: true, path: true } - end - end - - def data - { - edges: @graph.edges, - vertices: @graph.vertices, - } - end - - def data=(new_data) - objects = Set.new(@items.to_a + @layouts.to_a) - refs = objs2refs(objects) - - # Create new graph - @graph = Nanoc::Int::DirectedGraph.new([nil] + refs) - - # Load vertices - previous_refs = new_data[:vertices] - previous_objects = Set.new(refs2objs(previous_refs)) - - # Load edges - new_data[:edges].each do |edge| - from_index, to_index, props = *edge - from = from_index && previous_refs[from_index] - to = to_index && previous_refs[to_index] - @graph.add_edge(from, to, props: props) - end - - # Record dependency from all items on new items - @new_objects = objects - previous_objects - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/in_mem_data_source.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/in_mem_data_source.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/in_mem_data_source.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/in_mem_data_source.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - class InMemDataSource < Nanoc::DataSource - attr_reader :items - attr_reader :layouts - - def initialize(items, layouts, orig_data_source = nil) - super({}, '/', '/', {}) - - @items = items - @layouts = layouts - @orig_data_source = orig_data_source - end - - def item_changes - @orig_data_source ? @orig_data_source.item_changes : super - end - - def layout_changes - @orig_data_source ? @orig_data_source.layout_changes : super - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/item_rep_repo.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/item_rep_repo.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/item_rep_repo.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/item_rep_repo.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Stores item reps (in memory). - # - # @api private - class ItemRepRepo - include Enumerable - - def initialize - @reps = [] - @reps_by_item = {} - end - - def <<(rep) - @reps << rep - - @reps_by_item[rep.item] ||= [] - @reps_by_item[rep.item] << rep - end - - def to_a - @reps - end - - def each(&block) - @reps.each(&block) - self - end - - def [](item) - @reps_by_item.fetch(item, []) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/outdatedness_store.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/outdatedness_store.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/outdatedness_store.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/outdatedness_store.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class OutdatednessStore < ::Nanoc::Int::Store - include Nanoc::Int::ContractsSupport - - contract C::KeywordArgs[config: Nanoc::Int::Configuration] => C::Any - def initialize(config:) - super(Nanoc::Int::Store.tmp_path_for(config: config, store_name: 'outdatedness'), 1) - - @outdated_refs = Set.new - end - - contract Nanoc::Int::ItemRep => C::Bool - def include?(obj) - @outdated_refs.include?(obj.reference) - end - - contract Nanoc::Int::ItemRep => self - def add(obj) - @outdated_refs << obj.reference - self - end - - contract Nanoc::Int::ItemRep => self - def remove(obj) - @outdated_refs.delete(obj.reference) - self - end - - contract C::None => C::Bool - def empty? - @outdated_refs.empty? - end - - contract C::None => self - def clear - @outdated_refs = Set.new - self - end - - protected - - def data - @outdated_refs - end - - def data=(new_data) - @outdated_refs = Set.new(new_data) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/prefixed_data_source.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/prefixed_data_source.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/prefixed_data_source.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/prefixed_data_source.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - class PrefixedDataSource < Nanoc::DataSource - def initialize(data_source, items_prefix, layouts_prefix) - super({}, '/', '/', {}) - - @data_source = data_source - @items_prefix = items_prefix - @layouts_prefix = layouts_prefix - end - - def items - @data_source.items.map { |d| d.with_identifier_prefix(@items_prefix) } - end - - def layouts - @data_source.layouts.map { |d| d.with_identifier_prefix(@layouts_prefix) } - end - - def item_changes - @data_source.item_changes - end - - def layout_changes - @data_source.layout_changes - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/site_loader.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/site_loader.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/site_loader.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/site_loader.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - class SiteLoader - def new_from_cwd - site_from_config(Nanoc::Int::ConfigLoader.new.new_from_cwd) - end - - # @return [Boolean] - def self.cwd_is_nanoc_site? - Nanoc::Int::ConfigLoader.cwd_is_nanoc_site? - end - - def gen_data_source_for_config(config) - data_sources_to_aggregate = - with_data_sources(config) do |data_sources| - data_sources.map do |ds| - Nanoc::Int::PrefixedDataSource.new(ds, ds.items_root, ds.layouts_root) - end - end - - Nanoc::Int::AggregateDataSource.new(data_sources_to_aggregate, config) - end - - private - - def site_from_config(config) - code_snippets = code_snippets_from_config(config) - code_snippets.each(&:load) - - data_source = gen_data_source_for_config(config) - - Nanoc::Int::Site.new( - config: config, - code_snippets: code_snippets, - data_source: data_source, - ) - end - - def with_data_sources(config, &_block) - data_sources = create_data_sources(config) - - begin - data_sources.each(&:use) - yield(data_sources) - ensure - data_sources.each(&:unuse) - end - end - - def create_data_sources(config) - config[:data_sources].map do |data_source_hash| - # Get data source class - data_source_class = Nanoc::DataSource.named(data_source_hash[:type].to_sym) - if data_source_class.nil? - raise Nanoc::Int::Errors::UnknownDataSource.new(data_source_hash[:type]) - end - - # Create data source - data_source_class.new( - config, - data_source_hash[:items_root], - data_source_hash[:layouts_root], - data_source_hash.merge(data_source_hash[:config] || {}), - ) - end - end - - def code_snippets_from_config(config) - config[:lib_dirs].flat_map do |lib| - Dir["#{lib}/**/*.rb"].sort.map do |filename| - Nanoc::Int::CodeSnippet.new( - read_code_snippet_contents(filename), - filename, - ) - end - end - end - - ENCODING_REGEX = /\A#\s+(-\*-\s+)?(en)?coding: (?[^\s]+)(\s+-\*-\s*)?\n{0,2}/.freeze - - def encoding_from_magic_comment(raw) - match = ENCODING_REGEX.match(raw) - match ? match['encoding'] : nil - end - - def read_code_snippet_contents(filename) - raw = File.read(filename, encoding: 'ASCII-8BIT') - - enc = encoding_from_magic_comment(raw) - if enc - raw = raw.force_encoding(enc).encode('UTF-8').sub(ENCODING_REGEX, '') - else - raw.force_encoding('UTF-8') - end - - raw - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/snapshot_repo.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/snapshot_repo.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/snapshot_repo.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/snapshot_repo.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class SnapshotRepo - include Nanoc::Int::ContractsSupport - - def initialize - @contents = {} - end - - contract Nanoc::Int::ItemRep, Symbol => C::Maybe[Nanoc::Int::Content] - def get(rep, snapshot_name) - @contents[rep] ||= {} - @contents[rep][snapshot_name] - end - - contract Nanoc::Int::ItemRep, Symbol, Nanoc::Int::Content => C::Any - def set(rep, snapshot_name, contents) - @contents[rep] ||= {} - @contents[rep][snapshot_name] = contents - end - - contract Nanoc::Int::ItemRep => C::HashOf[Symbol => Nanoc::Int::Content] - def get_all(rep) - @contents[rep] || {} - end - - contract Nanoc::Int::ItemRep, C::HashOf[Symbol => Nanoc::Int::Content] => C::Any - def set_all(rep, contents_per_snapshot) - @contents[rep] = contents_per_snapshot - end - - contract C::KeywordArgs[rep: Nanoc::Int::ItemRep, snapshot: C::Optional[C::Maybe[Symbol]]] => Nanoc::Int::Content - def raw_compiled_content(rep:, snapshot: nil) - # Get name of last pre-layout snapshot - snapshot_name = snapshot || (get(rep, :pre) ? :pre : :last) - - # Check existance of snapshot - snapshot_def = rep.snapshot_defs.reverse.find { |sd| sd.name == snapshot_name } - unless snapshot_def - raise Nanoc::Int::Errors::NoSuchSnapshot.new(rep, snapshot_name) - end - - # Verify snapshot is usable - stopped_moving = snapshot_name != :last || rep.compiled? - is_usable_snapshot = get(rep, snapshot_name) && stopped_moving - unless is_usable_snapshot - Fiber.yield(Nanoc::Int::Errors::UnmetDependency.new(rep)) - return raw_compiled_content(rep: rep, snapshot: snapshot) - end - - get(rep, snapshot_name) - end - - contract C::KeywordArgs[rep: Nanoc::Int::ItemRep, snapshot: C::Optional[C::Maybe[Symbol]]] => String - def compiled_content(rep:, snapshot: nil) - snapshot_content = raw_compiled_content(rep: rep, snapshot: snapshot) - - if snapshot_content.binary? - raise Nanoc::Int::Errors::CannotGetCompiledContentOfBinaryItem.new(rep) - end - - snapshot_content.string - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos/store.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos/store.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos/store.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos/store.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # An abstract superclass for classes that need to store data to the - # filesystem, such as checksums, cached compiled content and dependency - # graphs. - # - # Each store has a version number. When attempting to load data from a store - # that has an incompatible version number, no data will be loaded, but - # {#version_mismatch_detected} will be called. - # - # @abstract Subclasses must implement {#data} and {#data=}, and may - # implement {#no_data_found} and {#version_mismatch_detected}. - # - # @api private - class Store - include Nanoc::Int::ContractsSupport - - # @return [String] The name of the file where data will be loaded from and - # stored to. - attr_reader :filename - - # @return [Numeric] The version number corresponding to the file format - # the data is in. When the file format changes, the version number - # should be incremented. - attr_reader :version - - # Creates a new store for the given filename. - # - # @param [String] filename The name of the file where data will be loaded - # from and stored to. - # - # @param [Numeric] version The version number corresponding to the file - # format the data is in. When the file format changes, the version - # number should be incremented. - def initialize(filename, version) - @filename = filename - @version = version - end - - # Logic for building tmp path from active environment and store name - # @api private - contract C::KeywordArgs[config: Nanoc::Int::Configuration, store_name: String] => C::AbsolutePathString - def self.tmp_path_for(store_name:, config:) - File.absolute_path( - File.join(tmp_path_prefix(config.output_dir), store_name), - config.dir, - ) - end - - def self.tmp_path_prefix(output_dir) - dir = Digest::SHA1.hexdigest(output_dir)[0..12] - File.join('tmp', 'nanoc', dir) - end - - # @group Loading and storing data - - # @return The data that should be written to the disk - # - # @abstract This method must be implemented by the subclass. - def data - raise NotImplementedError.new('Nanoc::Int::Store subclasses must implement #data and #data=') - end - - # @param new_data The data that has been loaded from the disk - # - # @abstract This method must be implemented by the subclass. - # - # @return [void] - def data=(new_data) # rubocop:disable Lint/UnusedMethodArgument - raise NotImplementedError.new('Nanoc::Int::Store subclasses must implement #data and #data=') - end - - # Loads the data from the filesystem into memory. This method will set the - # loaded data using the {#data=} method. - # - # @return [void] - def load - return unless File.file?(filename) - - begin - pstore.transaction do - return if pstore[:version] != version - - self.data = pstore[:data] - end - rescue - FileUtils.rm_f(filename) - load - end - end - - # Stores the data contained in memory to the filesystem. This method will - # use the {#data} method to fetch the data that should be written. - # - # @return [void] - def store - FileUtils.mkdir_p(File.dirname(filename)) - - pstore.transaction do - pstore[:data] = data - pstore[:version] = version - end - end - - private - - def pstore - @pstore ||= PStore.new(filename) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/repos.rb nanoc-4.11.14/nanoc/lib/nanoc/base/repos.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/repos.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/repos.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require_relative 'repos/store' - -require_relative 'repos/checksum_store' -require_relative 'repos/compiled_content_cache' -require_relative 'repos/config_loader' -require_relative 'repos/data_source' -require_relative 'repos/dependency_store' -require_relative 'repos/item_rep_repo' -require_relative 'repos/outdatedness_store' -require_relative 'repos/action_sequence_store' -require_relative 'repos/site_loader' -require_relative 'repos/snapshot_repo' -require_relative 'repos/in_mem_data_source' -require_relative 'repos/aggregate_data_source' -require_relative 'repos/prefixed_data_source' diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/action_provider.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/action_provider.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/action_provider.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/action_provider.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @private - class ActionProvider - extend DDPlugin::Plugin - - def self.for(_site) - raise NotImplementedError - end - - def rep_names_for(_item) - raise NotImplementedError - end - - def action_sequence_for(_obj) - raise NotImplementedError - end - - def need_preprocessing? - raise NotImplementedError - end - - def preprocess(_site) - raise NotImplementedError - end - - def postprocess(_site, _reps) - raise NotImplementedError - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/action_sequence_builder.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/action_sequence_builder.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/action_sequence_builder.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/action_sequence_builder.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - class ActionSequenceBuilder - include Nanoc::Int::ContractsSupport - - def initialize(item_rep) - @item_rep = item_rep - @actions = [] - end - - contract Symbol, Hash => self - def add_filter(filter_name, params) - @actions << Nanoc::Int::ProcessingActions::Filter.new(filter_name, params) - self - end - - contract String, C::Maybe[Hash] => self - def add_layout(layout_identifier, params) - @actions << Nanoc::Int::ProcessingActions::Layout.new(layout_identifier, params) - self - end - - contract Symbol, C::Maybe[String] => self - def add_snapshot(snapshot_name, path) - will_add_snapshot(snapshot_name) - @actions << Nanoc::Int::ProcessingActions::Snapshot.new([snapshot_name], path ? [path] : []) - self - end - - contract C::None => Nanoc::Int::ActionSequence - def action_sequence - Nanoc::Int::ActionSequence.new(@item_rep, actions: @actions) - end - - private - - def will_add_snapshot(name) - @_snapshot_names ||= Set.new - if @_snapshot_names.include?(name) - raise Nanoc::Int::Errors::CannotCreateMultipleSnapshotsWithSameName.new(@item_rep, name) - else - @_snapshot_names << name - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/checksummer.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/checksummer.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/checksummer.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/checksummer.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,274 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Creates checksums for given objects. - # - # A checksum is a string, such as “mL+TaqNsEeiPkWloPgCtAofT1yg=”, that is used - # to determine whether a piece of data has changed. - # - # @api private - class Checksummer - class VerboseDigest - def initialize - @str = +'' - end - - def update(str) - @str << str - end - - def to_s - @str - end - end - - class CompactDigest - def initialize - @digest = Digest::SHA1.new - end - - def update(str) - @digest.update(str) - end - - def to_s - @digest.base64digest - end - end - - class << self - # @param obj The object to create a checksum for - # - # @return [String] The digest - def calc(obj, digest_class = CompactDigest) - digest = digest_class.new - update(obj, digest) - digest.to_s - end - - def calc_for_content_of(obj) - obj.content_checksum_data || obj.checksum_data || Nanoc::Int::Checksummer.calc(obj.content) - end - - def calc_for_each_attribute_of(obj, digest_class = CompactDigest) - obj.attributes.each_with_object({}) do |(key, value), memo| - memo[key] = Nanoc::Int::Checksummer.calc(value, digest_class) - end - end - - private - - def update(obj, digest, visited = Hamster::Set.new) - digest.update(obj.class.to_s) - - if visited.include?(obj) - digest.update('') - else - digest.update('<') - behavior_for(obj).update(obj, digest) { |o| update(o, digest, visited.add(obj)) } - digest.update('>') - end - end - - def behavior_for(obj) - case obj - when String, Symbol, Numeric - RawUpdateBehavior - when Pathname - PathnameUpdateBehavior - when Nanoc::Int::BinaryContent - BinaryContentUpdateBehavior - when Array, Nanoc::Int::IdentifiableCollection - ArrayUpdateBehavior - when Hash, Nanoc::Int::Configuration - HashUpdateBehavior - when Nanoc::Int::Item, Nanoc::Int::Layout - DocumentUpdateBehavior - when Nanoc::Int::ItemRep - ItemRepUpdateBehavior - when NilClass, TrueClass, FalseClass - NoUpdateBehavior - when Time - ToIToSUpdateBehavior - when Nanoc::Identifier - ToSUpdateBehavior - when Nanoc::RuleDSL::RulesCollection, Nanoc::Int::CodeSnippet - DataUpdateBehavior - when Nanoc::Int::TextualContent - StringUpdateBehavior - when Nanoc::View - UnwrapUpdateBehavior - when Nanoc::RuleDSL::CompilationRuleContext - RuleContextUpdateBehavior - when Nanoc::Int::Context - ContextUpdateBehavior - else - RescueUpdateBehavior - end - end - end - - class UpdateBehavior - def self.update(_obj, _digest) - raise NotImpementedError - end - end - - class RuleContextUpdateBehavior < UpdateBehavior - def self.update(obj, digest) - digest.update('item=') - yield(obj.item) - digest.update(',rep=') - yield(obj.rep) - digest.update(',items=') - yield(obj.items) - digest.update(',layouts=') - yield(obj.layouts) - digest.update(',config=') - yield(obj.config) - end - end - - class ContextUpdateBehavior < UpdateBehavior - def self.update(obj, digest) - obj.instance_variables.each do |var| - digest.update(var.to_s) - digest.update('=') - yield(obj.instance_variable_get(var)) - digest.update(',') - end - end - end - - class RawUpdateBehavior < UpdateBehavior - def self.update(obj, digest) - digest.update(obj.to_s) - end - end - - class ToSUpdateBehavior < UpdateBehavior - def self.update(obj, _digest) - yield(obj.to_s) - end - end - - class ToIToSUpdateBehavior < UpdateBehavior - def self.update(obj, digest) - digest.update(obj.to_i.to_s) - end - end - - class StringUpdateBehavior < UpdateBehavior - def self.update(obj, _digest) - yield(obj.string) - end - end - - class DataUpdateBehavior < UpdateBehavior - def self.update(obj, _digest) - yield(obj.data) - end - end - - class NoUpdateBehavior < UpdateBehavior - def self.update(_obj, _digest); end - end - - class UnwrapUpdateBehavior < UpdateBehavior - def self.update(obj, _digest) - yield(obj._unwrap) - end - end - - class ArrayUpdateBehavior < UpdateBehavior - def self.update(obj, digest) - obj.each do |el| - yield(el) - digest.update(',') - end - end - end - - class HashUpdateBehavior < UpdateBehavior - def self.update(obj, digest) - obj.each do |key, value| - yield(key) - digest.update('=') - yield(value) - digest.update(',') - end - end - end - - class DocumentUpdateBehavior < UpdateBehavior - def self.update(obj, digest) - if obj.checksum_data - digest.update('checksum_data=' + obj.checksum_data) - else - if obj.content_checksum_data - digest.update('content_checksum_data=' + obj.content_checksum_data) - else - digest.update('content=') - yield(obj.content) - end - - if obj.attributes_checksum_data - digest.update(',attributes_checksum_data=' + obj.attributes_checksum_data) - else - digest.update(',attributes=') - yield(obj.attributes) - end - - digest.update(',identifier=') - yield(obj.identifier) - end - end - end - - class ItemRepUpdateBehavior < UpdateBehavior - def self.update(obj, digest) - digest.update('item=') - yield(obj.item) - digest.update(',name=') - yield(obj.name) - end - end - - class PathnameUpdateBehavior < UpdateBehavior - def self.update(obj, digest) - filename = obj.to_s - if File.exist?(filename) - stat = File.stat(filename) - digest.update(stat.size.to_s + '-' + stat.mtime.to_i.to_s) - else - digest.update('???') - end - end - end - - class BinaryContentUpdateBehavior < UpdateBehavior - def self.update(obj, _digest) - yield(Pathname.new(obj.filename)) - end - end - - class RescueUpdateBehavior < UpdateBehavior - def self.update(obj, digest) - if obj.class.to_s == 'Sass::Importers::Filesystem' - digest.update('root=') - digest.update(obj.root) - return - end - - data = - begin - Marshal.dump(obj) - rescue - obj.inspect - end - - digest.update(data) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compilation_context.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compilation_context.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compilation_context.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compilation_context.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - class CompilationContext - attr_reader :site - attr_reader :compiled_content_cache - attr_reader :snapshot_repo - - def initialize(action_provider:, reps:, site:, compiled_content_cache:, snapshot_repo:) - @action_provider = action_provider - @reps = reps - @site = site - @compiled_content_cache = compiled_content_cache - @snapshot_repo = snapshot_repo - end - - def filter_name_and_args_for_layout(layout) - seq = @action_provider.action_sequence_for(layout) - if seq.nil? || seq.size != 1 || !seq[0].is_a?(Nanoc::Int::ProcessingActions::Filter) - raise Nanoc::Int::Errors::UndefinedFilterForLayout.new(layout) - end - - [seq[0].filter_name, seq[0].params] - end - - def create_view_context(dependency_tracker) - Nanoc::ViewContextForCompilation.new( - reps: @reps, - items: @site.items, - dependency_tracker: dependency_tracker, - compilation_context: self, - snapshot_repo: @snapshot_repo, - ) - end - - def assigns_for(rep, dependency_tracker) - last_content = @snapshot_repo.get(rep, :last) - content_or_filename_assigns = - if last_content.binary? - { filename: last_content.filename } - else - { content: last_content.string } - end - - view_context = create_view_context(dependency_tracker) - - content_or_filename_assigns.merge( - item: Nanoc::CompilationItemView.new(rep.item, view_context), - rep: Nanoc::CompilationItemRepView.new(rep, view_context), - item_rep: Nanoc::CompilationItemRepView.new(rep, view_context), - items: Nanoc::ItemCollectionWithRepsView.new(@site.items, view_context), - layouts: Nanoc::LayoutCollectionView.new(@site.layouts, view_context), - config: Nanoc::ConfigView.new(@site.config, view_context), - ) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases/abstract.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases/abstract.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases/abstract.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases/abstract.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Phases - class Abstract - include Nanoc::Int::ContractsSupport - - def initialize(wrapped:) - @wrapped = wrapped - end - - def start - @wrapped&.start - end - - def stop - @wrapped&.stop - end - - def call(rep, is_outdated:) - notify(:phase_started, rep) - run(rep, is_outdated: is_outdated) do - notify(:phase_yielded, rep) - @wrapped.call(rep, is_outdated: is_outdated) - notify(:phase_resumed, rep) - end - notify(:phase_ended, rep) - rescue - notify(:phase_aborted, rep) - raise - end - - contract Nanoc::Int::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => C::Any - def run(_rep, is_outdated:) # rubocop:disable Lint/UnusedMethodArgument - raise NotImplementedError - end - - private - - def notify(sym, rep) - name = self.class.to_s.sub(/^.*::/, '') - Nanoc::Int::NotificationCenter.post(sym, name, rep) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases/cache.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases/cache.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases/cache.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases/cache.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Phases - # Provides functionality for (re)calculating the content of an item rep, with caching or - # outdatedness checking. Delegates to s::Recalculate if outdated or no cache available. - class Cache < Abstract - include Nanoc::Int::ContractsSupport - - def initialize(wrapped:, compiled_content_cache:, snapshot_repo:) - super(wrapped: wrapped) - - @compiled_content_cache = compiled_content_cache - @snapshot_repo = snapshot_repo - end - - contract Nanoc::Int::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => C::Any - def run(rep, is_outdated:) - if can_reuse_content_for_rep?(rep, is_outdated: is_outdated) - Nanoc::Int::NotificationCenter.post(:cached_content_used, rep) - - @snapshot_repo.set_all(rep, @compiled_content_cache[rep]) - else - yield - end - - rep.compiled = true - @compiled_content_cache[rep] = @snapshot_repo.get_all(rep) - end - - contract Nanoc::Int::ItemRep, C::KeywordArgs[is_outdated: C::Bool] => C::Bool - def can_reuse_content_for_rep?(rep, is_outdated:) - if is_outdated - false - else - cache = @compiled_content_cache[rep] - cache ? cache.none? { |_snapshot_name, content| content.binary? } : false - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases/mark_done.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases/mark_done.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases/mark_done.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases/mark_done.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Phases - class MarkDone < Abstract - include Nanoc::Int::ContractsSupport - - def initialize(wrapped:, outdatedness_store:) - super(wrapped: wrapped) - - @outdatedness_store = outdatedness_store - end - - contract Nanoc::Int::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => C::Any - def run(rep, is_outdated:) # rubocop:disable Lint/UnusedMethodArgument - yield - @outdatedness_store.remove(rep) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases/recalculate.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases/recalculate.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases/recalculate.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases/recalculate.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Phases - # Provides functionality for (re)calculating the content of an item rep, without caching or - # outdatedness checking. - class Recalculate < Abstract - include Nanoc::Int::ContractsSupport - - def initialize(action_sequences:, dependency_store:, compilation_context:) - super(wrapped: nil) - - @action_sequences = action_sequences - @dependency_store = dependency_store - @compilation_context = compilation_context - end - - contract Nanoc::Int::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => C::Any - def run(rep, is_outdated:) # rubocop:disable Lint/UnusedMethodArgument - dependency_tracker = Nanoc::Int::DependencyTracker.new(@dependency_store) - dependency_tracker.enter(rep.item) - - executor = Nanoc::Int::Executor.new(rep, @compilation_context, dependency_tracker) - - @compilation_context.snapshot_repo.set(rep, :last, rep.item.content) - - actions = @action_sequences[rep] - actions.each do |action| - case action - when Nanoc::Int::ProcessingActions::Filter - executor.filter(action.filter_name, action.params) - when Nanoc::Int::ProcessingActions::Layout - executor.layout(action.layout_identifier, action.params) - when Nanoc::Int::ProcessingActions::Snapshot - action.snapshot_names.each do |snapshot_name| - executor.snapshot(snapshot_name) - end - else - raise Nanoc::Int::Errors::InternalInconsistency, "unknown action #{action.inspect}" - end - end - ensure - dependency_tracker.exit - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases/resume.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases/resume.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases/resume.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases/resume.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Phases - # Provides functionality for suspending and resuming item rep compilation (using fibers). - class Resume < Abstract - include Nanoc::Int::ContractsSupport - - DONE = Object.new - - def initialize(wrapped:) - super(wrapped: wrapped) - end - - contract Nanoc::Int::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => C::Any - def run(rep, is_outdated:) - fiber = fiber_for(rep, is_outdated: is_outdated) { yield } - while fiber.alive? - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - res = fiber.resume - - case res - when Nanoc::Int::Errors::UnmetDependency - Nanoc::Int::NotificationCenter.post(:compilation_suspended, rep, res) - raise(res) - when Proc - fiber.resume(res.call) - when DONE # rubocop:disable Lint/EmptyWhen - # ignore - else - raise Nanoc::Int::Errors::InternalInconsistency.new( - "Fiber yielded object of unexpected type #{res.class}", - ) - end - end - - Nanoc::Int::NotificationCenter.post(:compilation_ended, rep) - end - - private - - contract Nanoc::Int::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => Fiber - def fiber_for(rep, is_outdated:) # rubocop:disable Lint/UnusedMethodArgument - @fibers ||= {} - - @fibers[rep] ||= - Fiber.new do - yield - @fibers.delete(rep) - DONE - end - - @fibers[rep] - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases/write.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases/write.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases/write.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases/write.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Phases - class Write < Abstract - include Nanoc::Int::ContractsSupport - - class Worker - def initialize(queue:, snapshot_repo:) - @queue = queue - @snapshot_repo = snapshot_repo - end - - def start - @thread = Thread.new do - Thread.current.abort_on_exception = true - Thread.current.priority = -1 # schedule I/O work ASAP - - writer = Nanoc::Int::ItemRepWriter.new - - while rep = @queue.pop # rubocop:disable Lint/AssignmentInCondition - writer.write_all(rep, @snapshot_repo) - end - end - end - - def join - @thread.join - end - end - - class WorkerPool - def initialize(queue:, size:, snapshot_repo:) - @workers = Array.new(size) { Worker.new(queue: queue, snapshot_repo: snapshot_repo) } - end - - def start - @workers.each(&:start) - end - - def join - @workers.each(&:join) - end - end - - QUEUE_SIZE = 40 - WORKER_POOL_SIZE = 5 - - def initialize(snapshot_repo:, wrapped:) - super(wrapped: wrapped) - - @snapshot_repo = snapshot_repo - - @queue = SizedQueue.new(QUEUE_SIZE) - @worker_pool = WorkerPool.new(queue: @queue, size: WORKER_POOL_SIZE, snapshot_repo: @snapshot_repo) - end - - def start - super - @worker_pool.start - end - - def stop - super - @queue.close - @worker_pool.join - end - - contract Nanoc::Int::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => C::Any - def run(rep, is_outdated:) # rubocop:disable Lint/UnusedMethodArgument - yield - - @queue << rep - - Nanoc::Int::NotificationCenter.post(:rep_write_enqueued, rep) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/phases.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/phases.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Phases -end - -require_relative 'phases/abstract' - -require_relative 'phases/recalculate' -require_relative 'phases/cache' -require_relative 'phases/resume' -require_relative 'phases/write' -require_relative 'phases/mark_done' diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stage.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stage.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stage.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stage.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -class Nanoc::Int::Compiler::Stage - def call(*args) - Nanoc::Int::Instrumentor.call(:stage_ran, self.class) do - run(*args) - end - end - - def run(*) - raise NotImplementedError - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/build_reps.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/build_reps.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/build_reps.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/build_reps.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Stages - class BuildReps < Nanoc::Int::Compiler::Stage - def initialize(site:, action_provider:) - @site = site - @action_provider = action_provider - end - - def run - reps = Nanoc::Int::ItemRepRepo.new - - builder = Nanoc::Int::ItemRepBuilder.new( - @site, @action_provider, reps - ) - - action_sequences = builder.run - - @site.layouts.each do |layout| - action_sequences[layout] = @action_provider.action_sequence_for(layout) - end - - { - reps: reps, - action_sequences: action_sequences, - } - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/calculate_checksums.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/calculate_checksums.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/calculate_checksums.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/calculate_checksums.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Stages - class CalculateChecksums < Nanoc::Int::Compiler::Stage - def initialize(items:, layouts:, code_snippets:, config:) - @items = items - @layouts = layouts - @code_snippets = code_snippets - @config = config - end - - def run - checksums = {} - - [@items, @layouts].each do |documents| - documents.each do |document| - checksums[[document.reference, :content]] = - Nanoc::Int::Checksummer.calc_for_content_of(document) - checksums[[document.reference, :each_attribute]] = - Nanoc::Int::Checksummer.calc_for_each_attribute_of(document) - end - end - - [@items, @layouts, @code_snippets].each do |objs| - objs.each do |obj| - checksums[obj.reference] = Nanoc::Int::Checksummer.calc(obj) - end - end - - checksums[@config.reference] = - Nanoc::Int::Checksummer.calc(@config) - checksums[[@config.reference, :each_attribute]] = - Nanoc::Int::Checksummer.calc_for_each_attribute_of(@config) - - Nanoc::Int::ChecksumCollection.new(checksums) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/cleanup.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/cleanup.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/cleanup.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/cleanup.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Stages - class Cleanup < Nanoc::Int::Compiler::Stage - def initialize(output_dirs) - @output_dirs = output_dirs - end - - def run - cleanup_temps(Nanoc::Filter::TMP_BINARY_ITEMS_DIR) - cleanup_temps(Nanoc::Int::ItemRepWriter::TMP_TEXT_ITEMS_DIR) - cleanup_unused_stores - cleanup_old_stores - end - - private - - def cleanup_temps(dir) - Nanoc::Int::TempFilenameFactory.instance.cleanup(dir) - end - - def cleanup_unused_stores - used_paths = @output_dirs.map { |d| Nanoc::Int::Store.tmp_path_prefix(d) } - all_paths = Dir.glob('tmp/nanoc/*') - (all_paths - used_paths).each do |obsolete_path| - FileUtils.rm_rf(obsolete_path) - end - end - - def cleanup_old_stores - %w[checksums compiled_content dependencies outdatedness action_sequence].each do |fn| - full_fn = File.join('tmp', fn) - if File.file?(full_fn) - FileUtils.rm_f(full_fn) - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/compile_reps.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/compile_reps.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/compile_reps.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/compile_reps.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Stages - class CompileReps < Nanoc::Int::Compiler::Stage - include Nanoc::Int::ContractsSupport - include Nanoc::Assertions::Mixin - - def initialize(reps:, outdatedness_store:, dependency_store:, action_sequences:, compilation_context:, compiled_content_cache:) - @reps = reps - @outdatedness_store = outdatedness_store - @dependency_store = dependency_store - @action_sequences = action_sequences - @compilation_context = compilation_context - @compiled_content_cache = compiled_content_cache - end - - def run - outdated_reps = @reps.select { |r| @outdatedness_store.include?(r) } - selector = Nanoc::Int::ItemRepSelector.new(outdated_reps) - run_phase_stack do |phase_stack| - selector.each do |rep| - handle_errors_while(rep) do - compile_rep(rep, phase_stack: phase_stack, is_outdated: @outdatedness_store.include?(rep)) - end - end - end - - assert Nanoc::Assertions::AllItemRepsHaveCompiledContent.new( - compiled_content_cache: @compiled_content_cache, - item_reps: @reps, - ) - ensure - @outdatedness_store.store - @compiled_content_cache.prune(items: @reps.map(&:item).uniq) - @compiled_content_cache.store - end - - private - - def handle_errors_while(item_rep) - yield - rescue Exception => e # rubocop:disable Lint/RescueException - raise Nanoc::Int::Errors::CompilationError.new(e, item_rep) - end - - def compile_rep(rep, phase_stack:, is_outdated:) - phase_stack.call(rep, is_outdated: is_outdated) - end - - def run_phase_stack - phase_stack = build_phase_stack - phase_stack.start - yield(phase_stack) - ensure - phase_stack.stop - end - - def build_phase_stack - recalculate_phase = Nanoc::Int::Compiler::Phases::Recalculate.new( - action_sequences: @action_sequences, - dependency_store: @dependency_store, - compilation_context: @compilation_context, - ) - - cache_phase = Nanoc::Int::Compiler::Phases::Cache.new( - compiled_content_cache: @compiled_content_cache, - snapshot_repo: @compilation_context.snapshot_repo, - wrapped: recalculate_phase, - ) - - resume_phase = Nanoc::Int::Compiler::Phases::Resume.new( - wrapped: cache_phase, - ) - - write_phase = Nanoc::Int::Compiler::Phases::Write.new( - snapshot_repo: @compilation_context.snapshot_repo, - wrapped: resume_phase, - ) - - mark_done_phase = Nanoc::Int::Compiler::Phases::MarkDone.new( - wrapped: write_phase, - outdatedness_store: @outdatedness_store, - ) - - mark_done_phase - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/determine_outdatedness.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/determine_outdatedness.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/determine_outdatedness.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/determine_outdatedness.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Stages - class DetermineOutdatedness < Nanoc::Int::Compiler::Stage - include Nanoc::Int::ContractsSupport - - def initialize(reps:, outdatedness_checker:, outdatedness_store:) - @reps = reps - @outdatedness_checker = outdatedness_checker - @outdatedness_store = outdatedness_store - end - - contract C::None => C::Any - def run - outdated_items = select_outdated_items - outdated_reps = reps_of_items(outdated_items) - - store_outdated_reps(outdated_reps) - - outdated_items - end - - private - - def store_outdated_reps(reps) - @outdatedness_store.clear - reps.each { |r| @outdatedness_store.add(r) } - end - - def select_outdated_items - @reps - .select { |r| outdated?(r) } - .map(&:item) - .uniq - end - - def reps_of_items(items) - Set.new(items.flat_map { |i| @reps[i] }) - end - - def outdated?(rep) - @outdatedness_store.include?(rep) || @outdatedness_checker.outdated?(rep) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/forget_outdated_dependencies.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/forget_outdated_dependencies.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/forget_outdated_dependencies.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/forget_outdated_dependencies.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Stages - class ForgetOutdatedDependencies < Nanoc::Int::Compiler::Stage - include Nanoc::Int::ContractsSupport - - def initialize(dependency_store:) - @dependency_store = dependency_store - end - - contract C::IterOf[Nanoc::Int::Item] => C::Any - def run(outdated_items) - outdated_items.each { |i| @dependency_store.forget_dependencies_for(i) } - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/load_stores.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/load_stores.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/load_stores.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/load_stores.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Stages - class LoadStores < Nanoc::Int::Compiler::Stage - include Nanoc::Int::ContractsSupport - - def initialize(checksum_store:, compiled_content_cache:, dependency_store:, action_sequence_store:, outdatedness_store:) - @checksum_store = checksum_store - @compiled_content_cache = compiled_content_cache - @dependency_store = dependency_store - @action_sequence_store = action_sequence_store - @outdatedness_store = outdatedness_store - end - - contract C::None => C::Any - def run - load_store(@checksum_store) - load_store(@compiled_content_cache) - load_store(@dependency_store) - load_store(@action_sequence_store) - load_store(@outdatedness_store) - end - - contract Nanoc::Int::Store => C::Any - def load_store(store) - Nanoc::Int::Instrumentor.call(:store_loaded, store.class) do - store.load - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/postprocess.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/postprocess.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/postprocess.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/postprocess.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Stages - class Postprocess < Nanoc::Int::Compiler::Stage - include Nanoc::Int::ContractsSupport - - def initialize(action_provider:, site:) - @action_provider = action_provider - @site = site - end - - contract Nanoc::Int::Compiler => C::Any - def run(compiler) - @action_provider.postprocess(@site, compiler) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/preprocess.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/preprocess.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/preprocess.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/preprocess.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Stages - class Preprocess < Nanoc::Int::Compiler::Stage - def initialize(action_provider:, site:, dependency_store:, checksum_store:) - @action_provider = action_provider - @site = site - @dependency_store = dependency_store - @checksum_store = checksum_store - end - - def run - return if @site.preprocessed? - - if @action_provider.need_preprocessing? - @site.data_source = Nanoc::Int::InMemDataSource.new(@site.items, @site.layouts, @site.data_source) - @action_provider.preprocess(@site) - - @dependency_store.items = @site.items - @dependency_store.layouts = @site.layouts - @checksum_store.objects = @site.items.to_a + @site.layouts.to_a + @site.code_snippets + [@site.config] - end - - @site.mark_as_preprocessed - @site.freeze - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/prune.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/prune.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/prune.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/prune.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Stages - class Prune < Nanoc::Int::Compiler::Stage - def initialize(config:, reps:) - @config = config - @reps = reps - end - - def run - if @config[:prune][:auto_prune] - Nanoc::Pruner.new(@config, @reps, exclude: prune_config_exclude).run - end - end - - private - - def prune_config - @config[:prune] || {} - end - - def prune_config_exclude - prune_config[:exclude] || {} - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/store_post_compilation_state.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/store_post_compilation_state.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/store_post_compilation_state.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/store_post_compilation_state.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Stages - class StorePostCompilationState < Nanoc::Int::Compiler::Stage - include Nanoc::Int::ContractsSupport - - def initialize(dependency_store:) - @dependency_store = dependency_store - end - - contract C::None => C::Any - def run - @dependency_store.store - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/store_pre_compilation_state.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/store_pre_compilation_state.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages/store_pre_compilation_state.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages/store_pre_compilation_state.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Stages - class StorePreCompilationState < Nanoc::Int::Compiler::Stage - include Nanoc::Int::ContractsSupport - - def initialize(reps:, layouts:, checksum_store:, action_sequence_store:, action_sequences:) - @reps = reps - @layouts = layouts - @checksum_store = checksum_store - @action_sequence_store = action_sequence_store - @action_sequences = action_sequences - end - - contract Nanoc::Int::ChecksumCollection => C::Any - def run(checksums) - # Calculate action sequence - (@reps.to_a + @layouts.to_a).each do |obj| - @action_sequence_store[obj] = @action_sequences[obj].serialize - end - @action_sequence_store.store - - # Set checksums - @checksum_store.checksums = checksums.to_h - @checksum_store.store - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler/stages.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler/stages.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::Compiler::Stages -end - -require_relative 'stage' - -require_relative 'stages/calculate_checksums' -require_relative 'stages/cleanup' -require_relative 'stages/compile_reps' -require_relative 'stages/determine_outdatedness' -require_relative 'stages/prune' -require_relative 'stages/preprocess' -require_relative 'stages/load_stores' -require_relative 'stages/forget_outdated_dependencies' -require_relative 'stages/store_pre_compilation_state' -require_relative 'stages/store_post_compilation_state' -require_relative 'stages/postprocess' -require_relative 'stages/build_reps' diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler_loader.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler_loader.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler_loader.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler_loader.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class CompilerLoader - def load(site, action_provider: nil) - action_sequence_store = Nanoc::Int::ActionSequenceStore.new(config: site.config) - - dependency_store = - Nanoc::Int::DependencyStore.new(site.items, site.layouts, site.config) - - objects = site.items.to_a + site.layouts.to_a + site.code_snippets + [site.config] - - checksum_store = - Nanoc::Int::ChecksumStore.new(config: site.config, objects: objects) - - action_provider ||= Nanoc::Int::ActionProvider.named(site.config.action_provider).for(site) - - outdatedness_store = - Nanoc::Int::OutdatednessStore.new(config: site.config) - - compiled_content_cache = - Nanoc::Int::CompiledContentCache.new(config: site.config) - - params = { - compiled_content_cache: compiled_content_cache, - checksum_store: checksum_store, - action_sequence_store: action_sequence_store, - dependency_store: dependency_store, - action_provider: action_provider, - outdatedness_store: outdatedness_store, - } - - Nanoc::Int::Compiler.new(site, params) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/compiler.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/compiler.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,207 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - class Compiler - include Nanoc::Int::ContractsSupport - - def initialize(site, compiled_content_cache:, checksum_store:, action_sequence_store:, action_provider:, dependency_store:, outdatedness_store:) - @site = site - - # Needed because configuration is mutable :( - @output_dirs = @site.config.output_dirs - - @compiled_content_cache = compiled_content_cache - @checksum_store = checksum_store - @action_sequence_store = action_sequence_store - @dependency_store = dependency_store - @action_provider = action_provider - @outdatedness_store = outdatedness_store - - @snapshot_repo = Nanoc::Int::SnapshotRepo.new - end - - contract Nanoc::Int::Site => Nanoc::Int::Compiler - def self.new_for(site) - Nanoc::Int::CompilerLoader.new.load(site) - end - - def run_until_preprocessed - @_res_preprocessed ||= begin - preprocess_stage.call - {} - end - end - - def run_until_reps_built - @_res_reps_built ||= begin - prev = run_until_preprocessed - - res = build_reps_stage.call - - prev.merge( - reps: res.fetch(:reps), - action_sequences: res.fetch(:action_sequences), - ) - end - end - - def run_until_precompiled - @_res_precompiled ||= begin - prev = run_until_reps_built - action_sequences = prev.fetch(:action_sequences) - reps = prev.fetch(:reps) - - load_stores_stage.call - checksums = calculate_checksums_stage.call - outdatedness_checker = create_outdatedness_checker( - checksums: checksums, - action_sequences: action_sequences, - reps: reps, - ) - outdated_items = determine_outdatedness_stage(outdatedness_checker, reps).call - - prev.merge( - checksums: checksums, - dependency_store: @dependency_store, - outdatedness_checker: outdatedness_checker, - outdated_items: outdated_items, - ) - end - end - - def run_until_end - res = run_until_precompiled - action_sequences = res.fetch(:action_sequences) - reps = res.fetch(:reps) - checksums = res.fetch(:checksums) - outdated_items = res.fetch(:outdated_items) - - forget_outdated_dependencies_stage.call(outdated_items) - store_pre_compilation_state_stage(action_sequences, reps).call(checksums) - prune_stage(reps).call - compile_reps_stage(action_sequences, reps).call - store_post_compilation_state_stage.call - postprocess_stage.call(self) - ensure - cleanup_stage.call - end - - def compilation_context(reps:) - Nanoc::Int::CompilationContext.new( - action_provider: @action_provider, - reps: reps, - site: @site, - compiled_content_cache: @compiled_content_cache, - snapshot_repo: @snapshot_repo, - ) - end - - private - - def create_outdatedness_checker(checksums:, action_sequences:, reps:) - Nanoc::Int::OutdatednessChecker.new( - site: @site, - checksum_store: @checksum_store, - dependency_store: @dependency_store, - action_sequence_store: @action_sequence_store, - action_sequences: action_sequences, - checksums: checksums, - reps: reps, - ) - end - - def preprocess_stage - @_preprocess_stage ||= Stages::Preprocess.new( - action_provider: @action_provider, - site: @site, - dependency_store: @dependency_store, - checksum_store: @checksum_store, - ) - end - - def build_reps_stage - @_build_reps_stage ||= Stages::BuildReps.new( - site: @site, - action_provider: @action_provider, - ) - end - - def prune_stage(reps) - @_prune_stage ||= Stages::Prune.new( - config: @site.config, - reps: reps, - ) - end - - def load_stores_stage - @_load_stores_stage ||= Stages::LoadStores.new( - checksum_store: @checksum_store, - compiled_content_cache: @compiled_content_cache, - dependency_store: @dependency_store, - action_sequence_store: @action_sequence_store, - outdatedness_store: @outdatedness_store, - ) - end - - def calculate_checksums_stage - @_calculate_checksums_stage ||= Stages::CalculateChecksums.new( - items: @site.items, - layouts: @site.layouts, - code_snippets: @site.code_snippets, - config: @site.config, - ) - end - - def determine_outdatedness_stage(outdatedness_checker, reps) - @_determine_outdatedness_stage ||= Stages::DetermineOutdatedness.new( - reps: reps, - outdatedness_checker: outdatedness_checker, - outdatedness_store: @outdatedness_store, - ) - end - - def store_pre_compilation_state_stage(action_sequences, reps) - @_store_pre_compilation_state_stage ||= Stages::StorePreCompilationState.new( - reps: reps, - layouts: @site.layouts, - checksum_store: @checksum_store, - action_sequence_store: @action_sequence_store, - action_sequences: action_sequences, - ) - end - - def compile_reps_stage(action_sequences, reps) - @_compile_reps_stage ||= Stages::CompileReps.new( - reps: reps, - outdatedness_store: @outdatedness_store, - dependency_store: @dependency_store, - action_sequences: action_sequences, - compilation_context: compilation_context(reps: reps), - compiled_content_cache: @compiled_content_cache, - ) - end - - def store_post_compilation_state_stage - @_store_post_compilation_state_stage ||= Stages::StorePostCompilationState.new( - dependency_store: @dependency_store, - ) - end - - def postprocess_stage - @_postprocess_stage ||= Stages::Postprocess.new( - action_provider: @action_provider, - site: @site, - ) - end - - def cleanup_stage - @_cleanup_stage ||= Stages::Cleanup.new(@output_dirs) - end - - def forget_outdated_dependencies_stage - @_forget_outdated_dependencies_stage ||= Stages::ForgetOutdatedDependencies.new( - dependency_store: @dependency_store, - ) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/dependency_tracker.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/dependency_tracker.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/dependency_tracker.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/dependency_tracker.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class DependencyTracker - include Nanoc::Int::ContractsSupport - - C_OBJ = C::Or[Nanoc::Int::Item, Nanoc::Int::Layout, Nanoc::Int::Configuration, Nanoc::Int::IdentifiableCollection] - C_RAW_CONTENT = C::Or[C::IterOf[C::Or[String, Regexp]], C::Bool] - C_ATTR = C::Or[C::IterOf[Symbol], C::Bool] - C_ARGS = C::KeywordArgs[raw_content: C::Optional[C_RAW_CONTENT], attributes: C::Optional[C_ATTR], compiled_content: C::Optional[C::Bool], path: C::Optional[C::Bool]] - - class Null - include Nanoc::Int::ContractsSupport - - contract C_OBJ, C_ARGS => C::Any - def enter(_obj, raw_content: false, attributes: false, compiled_content: false, path: false); end - - contract C_OBJ => C::Any - def exit; end - - contract C_OBJ, C_ARGS => C::Any - def bounce(_obj, raw_content: false, attributes: false, compiled_content: false, path: false); end - end - - attr_reader :dependency_store - - def initialize(dependency_store) - @dependency_store = dependency_store - @stack = [] - end - - contract C_OBJ, C_ARGS => C::Any - def enter(obj, raw_content: false, attributes: false, compiled_content: false, path: false) - unless @stack.empty? - Nanoc::Int::NotificationCenter.post(:dependency_created, @stack.last, obj) - @dependency_store.record_dependency( - @stack.last, - obj, - raw_content: raw_content, - attributes: attributes, - compiled_content: compiled_content, - path: path, - ) - end - - @stack.push(obj) - end - - contract C_OBJ => C::Any - def exit - @stack.pop - end - - contract C_OBJ, C_ARGS => C::Any - def bounce(obj, raw_content: false, attributes: false, compiled_content: false, path: false) - enter(obj, raw_content: raw_content, attributes: attributes, compiled_content: compiled_content, path: path) - exit - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/executor.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/executor.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/executor.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/executor.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - module Int - class Executor - def initialize(rep, compilation_context, dependency_tracker) - @rep = rep - @compilation_context = compilation_context - @dependency_tracker = dependency_tracker - end - - def filter(filter_name, filter_args = {}) - filter = filter_for_filtering(@rep, filter_name) - - begin - Nanoc::Int::NotificationCenter.post(:filtering_started, @rep, filter_name) - - # Run filter - last = @compilation_context.snapshot_repo.get(@rep, :last) - source = last.binary? ? last.filename : last.string - filter_args.freeze - result = filter.setup_and_run(source, filter_args) - last = - if filter.class.to_binary? - Nanoc::Int::BinaryContent.new(filter.output_filename).tap(&:freeze) - else - Nanoc::Int::TextualContent.new(result).tap(&:freeze) - end - - # Store - @compilation_context.snapshot_repo.set(@rep, :last, last) - ensure - Nanoc::Int::NotificationCenter.post(:filtering_ended, @rep, filter_name) - end - end - - def layout(layout_identifier, extra_filter_args = nil) - layout = find_layout(layout_identifier) - filter_name, filter_args = *@compilation_context.filter_name_and_args_for_layout(layout) - if filter_name.nil? - raise Nanoc::Int::Errors::Generic, "Cannot find rule for layout matching #{layout_identifier}" - end - - filter_args = filter_args.merge(extra_filter_args || {}) - filter_args.freeze - - # Check whether item can be laid out - last = @compilation_context.snapshot_repo.get(@rep, :last) - raise Nanoc::Int::Errors::CannotLayoutBinaryItem.new(@rep) if last.binary? - - # Create filter - klass = Nanoc::Filter.named!(filter_name) - view_context = @compilation_context.create_view_context(@dependency_tracker) - layout_view = Nanoc::LayoutView.new(layout, view_context) - filter = klass.new(assigns_for(@rep).merge(layout: layout_view)) - - # Visit - @dependency_tracker.bounce(layout, raw_content: true) - - begin - Nanoc::Int::NotificationCenter.post(:filtering_started, @rep, filter_name) - - # Layout - content = layout.content - arg = content.binary? ? content.filename : content.string - res = filter.setup_and_run(arg, filter_args) - - # Store - last = Nanoc::Int::TextualContent.new(res).tap(&:freeze) - @compilation_context.snapshot_repo.set(@rep, :last, last) - ensure - Nanoc::Int::NotificationCenter.post(:filtering_ended, @rep, filter_name) - end - end - - def snapshot(snapshot_name) - last = @compilation_context.snapshot_repo.get(@rep, :last) - @compilation_context.snapshot_repo.set(@rep, snapshot_name, last) - end - - def assigns_for(rep) - @compilation_context.assigns_for(rep, @dependency_tracker) - end - - def layouts - @compilation_context.site.layouts - end - - def find_layout(arg) - req_id = arg.__nanoc_cleaned_identifier - layout = layouts.find { |l| l.identifier == req_id } - return layout if layout - - if use_globs? - pat = Nanoc::Int::Pattern.from(arg) - layout = layouts.find { |l| pat.match?(l.identifier) } - return layout if layout - end - - raise Nanoc::Int::Errors::UnknownLayout.new(arg) - end - - def filter_for_filtering(rep, filter_name) - klass = Nanoc::Filter.named!(filter_name) - - last = @compilation_context.snapshot_repo.get(@rep, :last) - if klass.from_binary? && !last.binary? - raise Nanoc::Int::Errors::CannotUseBinaryFilter.new(rep, klass) - elsif !klass.from_binary? && last.binary? - raise Nanoc::Int::Errors::CannotUseTextualFilter.new(rep, klass) - end - - klass.new(assigns_for(rep)) - end - - def use_globs? - @compilation_context.site.config[:string_pattern_type] == 'glob' - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/filter.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/filter.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/filter.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/filter.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,235 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - # Nanoc::Filter is responsible for filtering items. It is the superclass - # for all textual filters. - # - # A filter instance should only be used once. Filters should not be reused - # since they store state. - # - # When creating a filter with a hash containing assigned variables, those - # variables will be made available in the `@assigns` instance variable and - # the {#assigns} method. The assigns itself will also be available as - # instance variables and instance methods. - # - # @example Accessing assigns in different ways - # - # filter = SomeFilter.new({ :foo => 'bar' }) - # filter.instance_eval { @assigns[:foo] } - # # => 'bar' - # filter.instance_eval { assigns[:foo] } - # # => 'bar' - # filter.instance_eval { @foo } - # # => 'bar' - # filter.instance_eval { foo } - # # => 'bar' - # - # @abstract Subclass and override {#run} to implement a custom filter. - class Filter < Nanoc::Int::Context - # @api private - TMP_BINARY_ITEMS_DIR = 'binary_items' - - extend DDPlugin::Plugin - - class << self - def define(ident, &block) - filter_class = Class.new(::Nanoc::Filter) { identifier(ident) } - filter_class.send(:define_method, :run) do |content, params = {}| - instance_exec(content, params, &block) - end - end - - def named!(name) - klass = named(name) - raise Nanoc::Int::Errors::UnknownFilter.new(name) if klass.nil? - - klass - end - - # Sets the new type for the filter. The type can be `:binary` (default) - # or `:text`. The given argument can either be a symbol indicating both - # “from” and “to” types, or a hash where the only key is the “from” type - # and the only value is the “to” type. - # - # @example Specifying a text-to-text filter - # - # type :text - # - # @example Specifying a text-to-binary filter - # - # type :text => :binary - # - # @param [Symbol, Hash] arg The new type of this filter - # - # @return [void] - def type(arg) - if arg.is_a?(Hash) - @from = arg.keys[0] - @to = arg.values[0] - else - @from = arg - @to = arg - end - end - - # @return [Boolean] True if this filter can be applied to binary item - # representations, false otherwise - # - # @api private - def from_binary? - (@from || :text) == :binary - end - - # @return [Boolean] True if this filter results in a binary item - # representation, false otherwise - # - # @api private - def to_binary? - (@to || :text) == :binary - end - - # @api private - def to_text? - (@to || :text) == :text - end - - # @return [Boolean] - # - # @api private - def always_outdated? - @always_outdated || false - end - - # Marks this filter as always causing the item rep to be outdated. This is useful for filters - # that cannot do dependency tracking properly. - # - # @return [void] - def always_outdated - @always_outdated = true - end - - # @overload requires(*requires) - # Sets the required libraries for this filter. - # @param [Array] requires A list of library names that are required - # @return [void] - # @overload requires - # Returns the required libraries for this filter. - # @return [Enumerable] This filter’s list of library names that are required - def requires(*requires) - if requires.any? - @requires = requires - else - @requires || [] - end - end - - # Requires the filter’s required library if necessary. - # - # @return [void] - # - # @api private - def setup - @setup ||= begin - requires.each { |r| require r } - true - end - end - end - - # Creates a new filter that has access to the given assigns. - # - # @param [Hash] hash A hash containing variables that should be made - # available during filtering. - # - # @api private - def initialize(hash = {}) - @assigns = hash - super - end - - # Sets up the filter and runs the filter. This method passes its arguments - # to {#run} unchanged and returns the return value from {#run}. - # - # @see #run - # - # @api private - def setup_and_run(*args) - self.class.setup - run(*args).tap { |res| verify(res) } - end - - # Runs the filter on the given content or filename. - # - # @abstract - # - # @param [String] content_or_filename The unprocessed content that should - # be filtered (if the item is a textual item) or the path to the file - # that should be filtered (if the item is a binary item) - # - # @param [Hash] params A hash containing parameters. Filter subclasses can - # use these parameters to allow modifying the filter's behaviour. - # - # @return [String, void] If the filter output binary content, the return - # value is undefined; if the filter outputs textual content, the return - # value will be the filtered content. - def run(content_or_filename, params = {}) # rubocop:disable Lint/UnusedMethodArgument - raise NotImplementedError.new('Nanoc::Filter subclasses must implement #run') - end - - def verify(res) - if self.class.to_binary? - unless File.file?(output_filename) - raise Nanoc::Int::Errors::OutputNotWritten.new(self.class.identifier, output_filename) - end - elsif self.class.to_text? - unless res - raise Nanoc::Int::Errors::FilterReturnedNil.new(self.class.identifier) - end - end - end - - # Returns a filename that is used to write data to. This method is only - # used on binary items. When running a binary filter on a file, the - # resulting file must end up in the location returned by this method. - # - # The returned filename will be absolute, so it is safe to change to - # another directory inside the filter. - # - # @return [String] The output filename - def output_filename - @output_filename ||= - Nanoc::Int::TempFilenameFactory.instance.create(TMP_BINARY_ITEMS_DIR) - end - - # Returns the filename associated with the item that is being filtered. - # It is in the format `item (rep )`. - # - # @return [String] The filename - # - # @api private - def filename - if @layout - "layout #{@layout.identifier}" - elsif @item - "item #{@item.identifier} (rep #{@item_rep.name})" - else - '?' - end - end - - # @api private - def on_main_fiber(&block) - Fiber.yield(block) - end - - # Creates a dependency from the item that is currently being filtered onto - # the given collection of items. In other words, require the given items - # to be compiled first before this items is processed. - # - # @return [void] - def depend_on(items) - items.flat_map(&:reps).flat_map(&:raw_path) - items.each(&:raw_filename) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/instrumentor.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/instrumentor.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/instrumentor.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/instrumentor.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class Instrumentor - def self.call(key, *args) - stopwatch = DDMetrics::Stopwatch.new - stopwatch.start - yield - ensure - stopwatch.stop - Nanoc::Int::NotificationCenter.post(key, stopwatch.duration, *args) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/item_rep_builder.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/item_rep_builder.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/item_rep_builder.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/item_rep_builder.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class ItemRepBuilder - attr_reader :reps - - def initialize(site, action_provider, reps) - @site = site - @action_provider = action_provider - @reps = reps - end - - def run - @site.items.each do |item| - @action_provider.rep_names_for(item).each do |rep_name| - @reps << Nanoc::Int::ItemRep.new(item, rep_name) - end - end - - action_sequences = Nanoc::Int::ItemRepRouter.new(@reps, @action_provider, @site).run - - @reps.each do |rep| - rep.snapshot_defs = action_sequences[rep].snapshots_defs - end - - action_sequences - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/item_rep_router.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/item_rep_router.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/item_rep_router.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/item_rep_router.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Assigns paths to reps. - # - # @api private - class ItemRepRouter - include Nanoc::Int::ContractsSupport - - class IdenticalRoutesError < ::Nanoc::Error - def initialize(output_path, rep_a, rep_b) - super("The item representations #{rep_a} and #{rep_b} are both routed to #{output_path}.") - end - end - - class RouteWithoutSlashError < ::Nanoc::Error - def initialize(output_path, rep) - super("The item representation #{rep} is routed to #{output_path}, which does not start with a slash, as required.") - end - end - - def initialize(reps, action_provider, site) - @reps = reps - @action_provider = action_provider - @site = site - end - - def run - action_sequences = {} - assigned_paths = {} - @reps.each do |rep| - # Sigh. We route reps twice, because the first time, the paths might not have converged - # yet. This isn’t ideal, but it’s the only way to work around the divergence issues that - # I can think of. For details, see - # https://github.com/nanoc/nanoc/pull/1085#issuecomment-280628426. - - @action_provider.action_sequence_for(rep).paths.each do |(snapshot_names, paths)| - route_rep(rep, paths, snapshot_names, {}) - end - - seq = @action_provider.action_sequence_for(rep) - action_sequences[rep] = seq - seq.paths.each do |(snapshot_names, paths)| - route_rep(rep, paths, snapshot_names, assigned_paths) - end - - # TODO: verify that paths converge - end - - action_sequences - end - - contract Nanoc::Int::ItemRep, C::IterOf[String], C::IterOf[Symbol], C::HashOf[String => Nanoc::Int::ItemRep] => C::Any - def route_rep(rep, paths, snapshot_names, assigned_paths) - # Encode - paths = paths.map { |path| path.encode('UTF-8') } - - # Validate format - paths.each do |path| - unless path.start_with?('/') - raise RouteWithoutSlashError.new(path, rep) - end - end - - # Validate uniqueness - paths.each do |path| - if assigned_paths.include?(path) - # TODO: Include snapshot names in error message - reps = [assigned_paths[path], rep].sort_by { |r| [r.item.identifier, r.name] } - raise IdenticalRoutesError.new(path, *reps) - end - end - paths.each do |path| - assigned_paths[path] = rep - end - - # Assign - snapshot_names.each do |snapshot_name| - rep.raw_paths[snapshot_name] = paths.map { |path| @site.config.output_dir + path } - rep.paths[snapshot_name] = paths.map { |path| strip_index_filename(path) } - end - end - - contract String => String - def strip_index_filename(basic_path) - @site.config[:index_filenames].each do |index_filename| - slashed_index_filename = '/' + index_filename - if basic_path.end_with?(slashed_index_filename) - return basic_path[0..-index_filename.length - 1] - end - end - - basic_path - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/item_rep_selector.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/item_rep_selector.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/item_rep_selector.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/item_rep_selector.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Yields item reps to compile. - # - # @api private - class ItemRepSelector - def initialize(reps) - @reps = reps - end - - class MicroGraph - def initialize(reps) - @reps = Set.new(reps) - @stack = [] - end - - def next - if @stack.any? - @stack.last - elsif @reps.any? - @reps.each { |rep| break rep }.tap do |rep| - @reps.delete(rep) - @stack.push(rep) - end - else - nil - end - end - - def mark_ok - @stack.pop - end - - def mark_failed(dep) - if @stack.include?(dep) - raise Nanoc::Int::Errors::DependencyCycle.new(@stack + [dep]) - end - - @reps.delete(dep) - @stack.push(dep) - end - end - - def each - mg = MicroGraph.new(@reps) - - loop do - rep = mg.next - break if rep.nil? - - begin - yield(rep) - mg.mark_ok - rescue => e - actual_error = e.is_a?(Nanoc::Int::Errors::CompilationError) ? e.unwrap : e - - if actual_error.is_a?(Nanoc::Int::Errors::UnmetDependency) - mg.mark_failed(actual_error.rep) - else - raise(e) - end - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/item_rep_writer.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/item_rep_writer.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/item_rep_writer.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/item_rep_writer.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class ItemRepWriter - include Nanoc::Int::ContractsSupport - include Nanoc::Assertions::Mixin - - TMP_TEXT_ITEMS_DIR = 'text_items' - - def write_all(item_rep, snapshot_repo) - written_paths = Set.new - - item_rep.snapshot_defs.map(&:name).each do |snapshot_name| - write(item_rep, snapshot_repo, snapshot_name, written_paths) - end - end - - def write(item_rep, snapshot_repo, snapshot_name, written_paths) - item_rep.raw_paths.fetch(snapshot_name, []).each do |raw_path| - write_single(item_rep, snapshot_repo, snapshot_name, raw_path, written_paths) - end - end - - def write_single(item_rep, snapshot_repo, snapshot_name, raw_path, written_paths) - assert Nanoc::Assertions::PathIsAbsolute.new(path: raw_path) - - # Don’t write twice - # TODO: test written_paths behavior - return if written_paths.include?(raw_path) - - written_paths << raw_path - - # Create parent directory - FileUtils.mkdir_p(File.dirname(raw_path)) - - # Check if file will be created - is_created = !File.file?(raw_path) - - # Notify - Nanoc::Int::NotificationCenter.post( - :rep_write_started, item_rep, raw_path - ) - - content = snapshot_repo.get(item_rep, snapshot_name) - if content.binary? - temp_path = content.filename - else - temp_path = temp_filename - File.write(temp_path, content.string) - end - - # Check whether content was modified - is_modified = is_created || !FileUtils.identical?(raw_path, temp_path) - - # Write - if is_modified - begin - FileUtils.ln(temp_path, raw_path, force: true) - rescue Errno::EXDEV - FileUtils.cp(temp_path, raw_path) - end - end - - item_rep.modified = is_modified - - # Notify - Nanoc::Int::NotificationCenter.post( - :rep_write_ended, item_rep, content.binary?, raw_path, is_created, is_modified - ) - end - - def temp_filename - Nanoc::Int::TempFilenameFactory.instance.create(TMP_TEXT_ITEMS_DIR) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/notification_center.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/notification_center.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/notification_center.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/notification_center.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Provides a way to send notifications between objects. It allows blocks - # associated with a certain notification name to be registered; these blocks - # will be called when the notification with the given name is posted. - # - # It is a slightly different implementation of the Observer pattern; the - # table of subscribers is not stored in the observable object itself, but in - # the notification center. - # - # @api private - class NotificationCenter - class << self - # Adds the given block to the list of blocks that should be called when - # the notification with the given name is received. - # - # @param [String, Symbol] name The name of the notification that will - # cause the given block to be called. - # - # @param [String, Symbol, nil] id An identifier for the block. This is - # only used to be able to remove the block (using the remove method) - # later. Can be nil, but this is not recommended because it prevents - # the given notification block from being unregistered. - # - # @yield [*args] Will be executed with the arguments passed to {.post} - # - # @return [void] - def on(name, id = nil, &block) - initialize_if_necessary(name) - - # Add observer - @notifications[name] << { id: id, block: block } - end - - # Posts a notification with the given name and the given arguments. - # - # @param [String, Symbol] name The name of the notification that should - # be posted. - # - # @param args Arguments that wil be passed to the blocks handling the - # notification. - # - # @return [void] - def post(name, *args) - initialize_if_necessary(name) - - # Notify all observers - @notifications[name].each do |observer| - observer[:block].call(*args) - end - end - - # Removes the block with the given identifier from the list of blocks - # that should be called when the notification with the given name is - # posted. - # - # @param [String, Symbol] name The name of the notification that should - # no longer be registered. - # - # @param [String, Symbol] id The identifier of the block that should be - # removed. - # - # @return [void] - def remove(name, id) - initialize_if_necessary(name) - - # Remove relevant observers - @notifications[name].reject! { |i| i[:id] == id } - end - - # @api private - # - # @return [void] - def reset - @notifications = nil - end - - private - - def initialize_if_necessary(name) - @notifications ||= {} # name => observers dictionary - @notifications[name] ||= [] # list of observers - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_checker.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_checker.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_checker.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_checker.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,217 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # Responsible for determining whether an item or a layout is outdated. - # - # @api private - class OutdatednessChecker - class Basic - DDMemoize.activate(self) - - include Nanoc::Int::ContractsSupport - - Rules = Nanoc::Int::OutdatednessRules - - RULES_FOR_ITEM_REP = - [ - Rules::RulesModified, - Rules::ContentModified, - Rules::AttributesModified, - Rules::NotWritten, - Rules::CodeSnippetsModified, - Rules::UsesAlwaysOutdatedFilter, - ].freeze - - RULES_FOR_LAYOUT = - [ - Rules::RulesModified, - Rules::ContentModified, - Rules::AttributesModified, - Rules::UsesAlwaysOutdatedFilter, - ].freeze - - RULES_FOR_CONFIG = - [ - Rules::AttributesModified, - ].freeze - - RULES_FOR_ITEM_COLLECTION = - [ - Rules::ItemCollectionExtended, - ].freeze - - RULES_FOR_LAYOUT_COLLECTION = - [ - Rules::LayoutCollectionExtended, - ].freeze - - C_OBJ_MAYBE_REP = C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Configuration, Nanoc::Int::Layout, Nanoc::Int::ItemCollection, Nanoc::Int::LayoutCollection] - - contract C::KeywordArgs[outdatedness_checker: OutdatednessChecker, reps: Nanoc::Int::ItemRepRepo] => C::Any - def initialize(outdatedness_checker:, reps:) - @outdatedness_checker = outdatedness_checker - @reps = reps - end - - contract C_OBJ_MAYBE_REP => C::Maybe[OutdatednessStatus] - memoized def outdatedness_status_for(obj) - case obj - when Nanoc::Int::ItemRep - apply_rules(RULES_FOR_ITEM_REP, obj) - when Nanoc::Int::Item - apply_rules_multi(RULES_FOR_ITEM_REP, @reps[obj]) - when Nanoc::Int::Layout - apply_rules(RULES_FOR_LAYOUT, obj) - when Nanoc::Int::Configuration - apply_rules(RULES_FOR_CONFIG, obj) - when Nanoc::Int::ItemCollection - apply_rules(RULES_FOR_ITEM_COLLECTION, obj) - when Nanoc::Int::LayoutCollection - apply_rules(RULES_FOR_LAYOUT_COLLECTION, obj) - else - raise Nanoc::Int::Errors::InternalInconsistency, "do not know how to check outdatedness of #{obj.inspect}" - end - end - - private - - contract C::ArrayOf[Class], C_OBJ_MAYBE_REP, OutdatednessStatus => C::Maybe[OutdatednessStatus] - def apply_rules(rules, obj, status = OutdatednessStatus.new) - rules.inject(status) do |acc, rule| - if !acc.useful_to_apply?(rule) - acc - else - reason = rule.instance.call(obj, @outdatedness_checker) - if reason - acc.update(reason) - else - acc - end - end - end - end - - contract C::ArrayOf[Class], C::ArrayOf[C_OBJ_MAYBE_REP] => C::Maybe[OutdatednessStatus] - def apply_rules_multi(rules, objs) - objs.inject(OutdatednessStatus.new) { |acc, elem| apply_rules(rules, elem, acc) } - end - end - - DDMemoize.activate(self) - - include Nanoc::Int::ContractsSupport - - attr_reader :checksum_store - attr_reader :checksums - attr_reader :dependency_store - attr_reader :action_sequence_store - attr_reader :action_sequences - attr_reader :site - - Reasons = Nanoc::Int::OutdatednessReasons - - C_OBJ = C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Configuration, Nanoc::Int::Layout, Nanoc::Int::ItemCollection] - C_ITEM_OR_REP = C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep] - C_ACTION_SEQUENCES = C::HashOf[C_OBJ => Nanoc::Int::ActionSequence] - - contract C::KeywordArgs[site: Nanoc::Int::Site, checksum_store: Nanoc::Int::ChecksumStore, checksums: Nanoc::Int::ChecksumCollection, dependency_store: Nanoc::Int::DependencyStore, action_sequence_store: Nanoc::Int::ActionSequenceStore, action_sequences: C_ACTION_SEQUENCES, reps: Nanoc::Int::ItemRepRepo] => C::Any - def initialize(site:, checksum_store:, checksums:, dependency_store:, action_sequence_store:, action_sequences:, reps:) - @site = site - @checksum_store = checksum_store - @checksums = checksums - @dependency_store = dependency_store - @action_sequence_store = action_sequence_store - @action_sequences = action_sequences - @reps = reps - - @objects_outdated_due_to_dependencies = {} - end - - def action_sequence_for(rep) - @action_sequences.fetch(rep) - end - - contract C_OBJ => C::Bool - def outdated?(obj) - outdatedness_reasons_for(obj).any? - end - - contract C_OBJ => C::IterOf[Reasons::Generic] - def outdatedness_reasons_for(obj) - reasons = basic.outdatedness_status_for(obj).reasons - if reasons.any? - reasons - elsif outdated_due_to_dependencies?(obj) - [Reasons::DependenciesOutdated] - else - [] - end - end - - private - - contract C::None => Basic - def basic - @_basic ||= Basic.new(outdatedness_checker: self, reps: @reps) - end - - contract C_ITEM_OR_REP, Hamster::Set => C::Bool - def outdated_due_to_dependencies?(obj, processed = Hamster::Set.new) - # Convert from rep to item if necessary - obj = obj.item if obj.is_a?(Nanoc::Int::ItemRep) - - # Get from cache - if @objects_outdated_due_to_dependencies.key?(obj) - return @objects_outdated_due_to_dependencies[obj] - end - - # Check processed - # Don’t return true; the false will be or’ed into a true if there - # really is a dependency that is causing outdatedness. - return false if processed.include?(obj) - - # Calculate - is_outdated = dependency_store.dependencies_causing_outdatedness_of(obj).any? do |dep| - dependency_causes_outdatedness?(dep) || - (dep.props.compiled_content? && - outdated_due_to_dependencies?(dep.from, processed.merge([obj]))) - end - - # Cache - @objects_outdated_due_to_dependencies[obj] = is_outdated - - # Done - is_outdated - end - - contract Nanoc::Int::Dependency => C::Bool - def dependency_causes_outdatedness?(dependency) - return true if dependency.from.nil? - - status = basic.outdatedness_status_for(dependency.from) - - active = status.props.active & dependency.props.active - active.delete(:attributes) if attributes_unaffected?(status, dependency) - active.delete(:raw_content) if raw_content_unaffected?(status, dependency) - - active.any? - end - - def attributes_unaffected?(status, dependency) - reason = status.reasons.find { |r| r.is_a?(Nanoc::Int::OutdatednessReasons::AttributesModified) } - reason && dependency.props.attributes.is_a?(Enumerable) && (dependency.props.attributes & reason.attributes).empty? - end - - def raw_content_unaffected?(status, dependency) - reason = status.reasons.find { |r| r.is_a?(Nanoc::Int::OutdatednessReasons::DocumentCollectionExtended) } - if reason.nil? - false - elsif !dependency.props.raw_content.is_a?(Enumerable) - false - else - patterns = dependency.props.raw_content.map { |r| Nanoc::Int::Pattern.from(r) } - patterns.none? { |pat| reason.objects.any? { |obj| pat.match?(obj.identifier) } } - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rule.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rule.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rule.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rule.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class OutdatednessRule - include Nanoc::Int::ContractsSupport - include Singleton - - def call(obj, outdatedness_checker) - Nanoc::Int::Instrumentor.call(:outdatedness_rule_ran, self.class) do - apply(obj, outdatedness_checker) - end - end - - def apply(_obj, _outdatedness_checker) - raise NotImplementedError.new('Nanoc::Int::OutdatednessRule subclasses must implement #apply') - end - - contract C::None => String - def inspect - "#{self.class.name}(#{reason})" - end - - def self.affects_props(*names) - @affected_props = Set.new(names) - end - - def self.affected_props - @affected_props - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::OutdatednessRules - class AttributesModified < Nanoc::Int::OutdatednessRule - include Nanoc::Int::ContractsSupport - - affects_props :attributes, :compiled_content - - contract C::Or[Nanoc::Int::ItemRep, Nanoc::Int::Item, Nanoc::Int::Configuration, Nanoc::Int::Layout], C::Named['Nanoc::Int::OutdatednessChecker'] => C::Maybe[Nanoc::Int::OutdatednessReasons::Generic] - def apply(obj, outdatedness_checker) - case obj - when Nanoc::Int::ItemRep - apply(obj.item, outdatedness_checker) - when Nanoc::Int::Item, Nanoc::Int::Layout, Nanoc::Int::Configuration - if outdatedness_checker.checksum_store[obj] == outdatedness_checker.checksums.checksum_for(obj) - return nil - end - - old_checksums = outdatedness_checker.checksum_store.attributes_checksum_for(obj) - unless old_checksums - return Nanoc::Int::OutdatednessReasons::AttributesModified.new(true) - end - - new_checksums = outdatedness_checker.checksums.attributes_checksum_for(obj) - - attributes = Set.new(old_checksums.keys) + Set.new(new_checksums.keys) - changed_attributes = attributes.reject { |a| old_checksums[a] == new_checksums[a] } - - if changed_attributes.any? - Nanoc::Int::OutdatednessReasons::AttributesModified.new(changed_attributes) - end - else - raise ArgumentError - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::OutdatednessRules - class CodeSnippetsModified < Nanoc::Int::OutdatednessRule - DDMemoize.activate(self) - - include Nanoc::Int::ContractsSupport - - affects_props :raw_content, :attributes, :compiled_content, :path - - def apply(_obj, outdatedness_checker) - if any_snippets_modified?(outdatedness_checker) - Nanoc::Int::OutdatednessReasons::CodeSnippetsModified - end - end - - private - - memoized def any_snippets_modified?(outdatedness_checker) - outdatedness_checker.site.code_snippets.any? do |cs| - ch_old = outdatedness_checker.checksum_store[cs] - ch_new = outdatedness_checker.checksums.checksum_for(cs) - ch_old != ch_new - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/content_modified.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/content_modified.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/content_modified.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/content_modified.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::OutdatednessRules - class ContentModified < Nanoc::Int::OutdatednessRule - affects_props :raw_content, :compiled_content - - def apply(obj, outdatedness_checker) - obj = obj.item if obj.is_a?(Nanoc::Int::ItemRep) - - ch_old = outdatedness_checker.checksum_store.content_checksum_for(obj) - ch_new = outdatedness_checker.checksums.content_checksum_for(obj) - if ch_old != ch_new - Nanoc::Int::OutdatednessReasons::ContentModified - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/item_collection_extended.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/item_collection_extended.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/item_collection_extended.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/item_collection_extended.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::OutdatednessRules - class ItemCollectionExtended < Nanoc::Int::OutdatednessRule - affects_props :raw_content - - contract Nanoc::Int::ItemCollection, C::Named['Nanoc::Int::OutdatednessChecker'] => C::Maybe[Nanoc::Int::OutdatednessReasons::Generic] - def apply(_obj, outdatedness_checker) - new_items = outdatedness_checker.dependency_store.new_items - - if new_items.any? - Nanoc::Int::OutdatednessReasons::ItemCollectionExtended.new(new_items) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/layout_collection_extended.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/layout_collection_extended.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/layout_collection_extended.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/layout_collection_extended.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::OutdatednessRules - class LayoutCollectionExtended < Nanoc::Int::OutdatednessRule - affects_props :raw_content - - contract Nanoc::Int::LayoutCollection, C::Named['Nanoc::Int::OutdatednessChecker'] => C::Maybe[Nanoc::Int::OutdatednessReasons::Generic] - def apply(_obj, outdatedness_checker) - new_layouts = outdatedness_checker.dependency_store.new_layouts - - if new_layouts.any? - Nanoc::Int::OutdatednessReasons::LayoutCollectionExtended.new(new_layouts) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/not_written.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/not_written.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/not_written.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/not_written.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::OutdatednessRules - class NotWritten < Nanoc::Int::OutdatednessRule - affects_props :raw_content, :attributes, :compiled_content, :path - - def apply(obj, _outdatedness_checker) - if obj.raw_paths.values.flatten.compact.any? { |fn| !File.file?(fn) } - Nanoc::Int::OutdatednessReasons::NotWritten - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/rules_modified.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/rules_modified.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/rules_modified.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/rules_modified.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::OutdatednessRules - class RulesModified < Nanoc::Int::OutdatednessRule - affects_props :compiled_content, :path - - def apply(obj, outdatedness_checker) - # Check rules of obj itself - if rules_modified?(obj, outdatedness_checker) - return Nanoc::Int::OutdatednessReasons::RulesModified - end - - # Check rules of layouts used by obj - layouts = layouts_touched_by(obj, outdatedness_checker) - if layouts.any? { |layout| rules_modified?(layout, outdatedness_checker) } - return Nanoc::Int::OutdatednessReasons::RulesModified - end - - nil - end - - private - - def rules_modified?(obj, outdatedness_checker) - seq_old = outdatedness_checker.action_sequence_store[obj] - seq_new = outdatedness_checker.action_sequence_for(obj).serialize - - !seq_old.eql?(seq_new) - end - - def layouts_touched_by(obj, outdatedness_checker) - actions = outdatedness_checker.action_sequence_store[obj] - layout_actions = actions.select { |a| a.first == :layout } - - layout_actions.map do |layout_action| - layout_pattern = layout_action[1] - outdatedness_checker.site.layouts[layout_pattern] - end.compact - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int::OutdatednessRules - class UsesAlwaysOutdatedFilter < Nanoc::Int::OutdatednessRule - affects_props :raw_content, :attributes, :path - - def apply(obj, outdatedness_checker) - seq = outdatedness_checker.action_sequence_for(obj) - if any_always_outdated?(seq) - Nanoc::Int::OutdatednessReasons::UsesAlwaysOutdatedFilter - end - end - - def any_always_outdated?(seq) - seq - .select { |a| a.is_a?(Nanoc::Int::ProcessingActions::Filter) } - .map { |a| Nanoc::Filter.named(a.filter_name) } - .compact - .any?(&:always_outdated?) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/outdatedness_rules.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/outdatedness_rules.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - module OutdatednessRules - end -end - -require_relative 'outdatedness_rules/attributes_modified' -require_relative 'outdatedness_rules/code_snippets_modified' -require_relative 'outdatedness_rules/content_modified' -require_relative 'outdatedness_rules/not_written' -require_relative 'outdatedness_rules/rules_modified' -require_relative 'outdatedness_rules/uses_always_outdated_filter' -require_relative 'outdatedness_rules/item_collection_extended' -require_relative 'outdatedness_rules/layout_collection_extended' diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/pruner.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/pruner.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/pruner.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/pruner.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - # Responsible for finding and deleting files in the site’s output directory - # that are not managed by Nanoc. - # - # @api private - class Pruner - include Nanoc::Int::ContractsSupport - - # @param [Nanoc::Int::Configuration] config - # - # @param [Nanoc::Int::ItemRepRepo] reps - # - # @param [Boolean] dry_run true if the files to be deleted - # should only be printed instead of actually deleted, false if the files - # should actually be deleted. - # - # @param [Enumerable] exclude - def initialize(config, reps, dry_run: false, exclude: []) - @config = config - @reps = reps - @dry_run = dry_run - @exclude = Set.new(exclude) - end - - def run - return unless File.directory?(@config.output_dir) - - compiled_files = @reps.flat_map { |r| r.raw_paths.values.flatten }.compact - present_files, present_dirs = files_and_dirs_in(@config.output_dir + '/') - - remove_stray_files(present_files, compiled_files) - remove_empty_directories(present_dirs) - end - - contract String => C::Bool - def filename_excluded?(filename) - pathname = Pathname.new(strip_output_dir(filename)) - @exclude.any? { |e| pathname_components(pathname).include?(e) } - end - - contract String => String - def strip_output_dir(filename) - if filename.start_with?(@config.output_dir) - filename[@config.output_dir.size..-1] - else - filename - end - end - - contract Pathname => C::ArrayOf[String] - def pathname_components(pathname) - components = [] - tmp = pathname - loop do - old = tmp - components << File.basename(tmp) - tmp = File.dirname(tmp) - break if old == tmp - end - components.reverse - end - - contract C::ArrayOf[String], C::ArrayOf[String] => self - # @api private - def remove_stray_files(present_files, compiled_files) - (present_files - compiled_files).each do |f| - delete_file(f) unless filename_excluded?(f) - end - self - end - - contract C::ArrayOf[String] => self - # @api private - def remove_empty_directories(present_dirs) - present_dirs.reverse_each do |dir| - next if Dir.foreach(dir) { |n| break true if n !~ /\A\.\.?\z/ } - next if filename_excluded?(dir) - - delete_dir(dir) - end - self - end - - contract String => C::ArrayOf[C::ArrayOf[String]] - # @api private - def files_and_dirs_in(dir) - present_files = [] - present_dirs = [] - - expanded_dir = File.expand_path(dir) - - Find.find(dir) do |f| - case File.ftype(f) - when 'file' - unless filename_excluded?(f) - present_files << f - end - when 'directory' - if filename_excluded?(f) - Find.prune - elsif expanded_dir != File.expand_path(f) - present_dirs << f - end - end - end - - [present_files, present_dirs] - end - - protected - - def delete_file(file) - log_delete_and_run(file) { FileUtils.rm(file) } - end - - def delete_dir(dir) - log_delete_and_run(dir) { Dir.rmdir(dir) } - end - - def log_delete_and_run(thing) - if @dry_run - puts thing - else - Nanoc::CLI::Logger.instance.file(:high, :delete, thing) - yield - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services/temp_filename_factory.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services/temp_filename_factory.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services/temp_filename_factory.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services/temp_filename_factory.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Int - # @api private - class TempFilenameFactory - # @return [String] The root directory for all temporary filenames - attr_reader :root_dir - - # @return [Nanoc::Int::TempFilenameFactory] A common instance - def self.instance - @instance ||= new - end - - def initialize - @counts = {} - @root_dir = Dir.mktmpdir('nanoc') - end - - # @param [String] prefix A string prefix to include in the temporary - # filename, often the type of filename being provided. - # - # @return [String] A new unused filename - def create(prefix) - count = @counts.fetch(prefix, 0) - @counts[prefix] = count + 1 - - dirname = File.join(@root_dir, prefix) - filename = File.join(@root_dir, prefix, count.to_s) - - FileUtils.mkdir_p(dirname) - - filename - end - - # @param [String] prefix A string prefix that indicates which temporary - # filenames should be deleted. - # - # @return [void] - def cleanup(prefix) - path = File.join(@root_dir, prefix) - if File.exist?(path) - FileUtils.rm_rf(path) - end - - @counts.delete(prefix) - - if @counts.empty? && File.directory?(@root_dir) - FileUtils.rm_rf(@root_dir) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/services.rb nanoc-4.11.14/nanoc/lib/nanoc/base/services.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/services.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/services.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -require_relative 'services/action_provider' -require_relative 'services/action_sequence_builder' -require_relative 'services/checksummer' -require_relative 'services/compilation_context' -require_relative 'services/compiler' -require_relative 'services/compiler_loader' -require_relative 'services/dependency_tracker' -require_relative 'services/executor' -require_relative 'services/filter' -require_relative 'services/instrumentor' -require_relative 'services/item_rep_builder' -require_relative 'services/item_rep_router' -require_relative 'services/item_rep_selector' -require_relative 'services/item_rep_writer' -require_relative 'services/notification_center' -require_relative 'services/pruner' -require_relative 'services/temp_filename_factory' -require_relative 'services/outdatedness_rule' -require_relative 'services/outdatedness_rules' - -require_relative 'services/compiler/phases' -require_relative 'services/compiler/stages' - -require_relative 'services/outdatedness_checker' diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/basic_item_rep_collection_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/basic_item_rep_collection_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/basic_item_rep_collection_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/basic_item_rep_collection_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class BasicItemRepCollectionView < ::Nanoc::View - include Enumerable - - class NoSuchItemRepError < ::Nanoc::Error - def initialize(rep_name) - super("No rep named #{rep_name.inspect} was found.") - end - end - - # @api private - def initialize(item_reps, context) - super(context) - @item_reps = item_reps - end - - # @api private - def _unwrap - @item_reps - end - - # @api private - def view_class - Nanoc::BasicItemRepView - end - - def to_ary - @item_reps.map { |ir| view_class.new(ir, @context) } - end - - # Calls the given block once for each item rep, passing that item rep as a parameter. - # - # @yieldparam [Object] item rep view - # - # @yieldreturn [void] - # - # @return [self] - def each - @item_reps.each { |ir| yield view_class.new(ir, @context) } - self - end - - # @return [Integer] - def size - @item_reps.size - end - - # Return the item rep with the given name, or nil if no item rep exists. - # - # @param [Symbol] rep_name - # - # @return [nil] if no item rep with the given name was found - # - # @return [Nanoc::BasicItemRepView] if an item rep with the given name was found - def [](rep_name) - case rep_name - when Symbol - res = @item_reps.find { |ir| ir.name == rep_name } - res && view_class.new(res, @context) - when Integer - raise ArgumentError, "expected BasicItemRepCollectionView#[] to be called with a symbol (you likely want `.reps[:default]` rather than `.reps[#{rep_name}]`)" - else - raise ArgumentError, 'expected BasicItemRepCollectionView#[] to be called with a symbol' - end - end - - # Return the item rep with the given name, or raises an exception if there - # is no rep with the given name. - # - # @param [Symbol] rep_name - # - # @return [Nanoc::BasicItemRepView] - # - # @raise if no rep was found - def fetch(rep_name) - res = @item_reps.find { |ir| ir.name == rep_name } - if res - view_class.new(res, @context) - else - raise NoSuchItemRepError.new(rep_name) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/basic_item_rep_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/basic_item_rep_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/basic_item_rep_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/basic_item_rep_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class BasicItemRepView < ::Nanoc::View - # @api private - def initialize(item_rep, context) - super(context) - @item_rep = item_rep - end - - # @abstract - def item_view_class - Nanoc::BasicItemView - end - - # @api private - def _unwrap - @item_rep - end - - # @see Object#== - def ==(other) - other.respond_to?(:item) && other.respond_to?(:name) && item == other.item && name == other.name - end - - # @see Object#eql? - def eql?(other) - other.is_a?(self.class) && - item.eql?(other.item) && - name.eql?(other.name) - end - - # @see Object#hash - def hash - self.class.hash ^ item.identifier.hash ^ name.hash - end - - # @return [Symbol] - def name - @item_rep.name - end - - def snapshot?(name) - @context.dependency_tracker.bounce(_unwrap.item, compiled_content: true) - @item_rep.snapshot?(name) - end - - # Returns the item rep’s path, as used when being linked to. It starts - # with a slash and it is relative to the output directory. It does not - # include the path to the output directory. It will not include the - # filename if the filename is an index filename. - # - # @param [Symbol] snapshot The snapshot for which the path should be - # returned. - # - # @return [String] The item rep’s path. - def path(snapshot: :last) - @context.dependency_tracker.bounce(_unwrap.item, path: true) - @item_rep.path(snapshot: snapshot) - end - - # Returns the item that this item rep belongs to. - # - # @return [Nanoc::CompilationItemView] - def item - item_view_class.new(@item_rep.item, @context) - end - - # @api private - def binary? - snapshot_def = _unwrap.snapshot_defs.find { |sd| sd.name == :last } - raise Nanoc::Int::Errors::NoSuchSnapshot.new(_unwrap, :last) if snapshot_def.nil? - - snapshot_def.binary? - end - - def inspect - "<#{self.class} item.identifier=#{item.identifier} name=#{name}>" - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/basic_item_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/basic_item_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/basic_item_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/basic_item_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class BasicItemView < ::Nanoc::View - include Nanoc::DocumentViewMixin - - # Returns the children of this item. For items with identifiers that have - # extensions, returns an empty collection. - # - # @return [Enumerable] - def children - unless _unwrap.identifier.legacy? - raise Nanoc::Int::Errors::CannotGetParentOrChildrenOfNonLegacyItem.new(_unwrap.identifier) - end - - children_pattern = Nanoc::Int::Pattern.from(_unwrap.identifier.to_s + '*/') - children = @context.items.select { |i| children_pattern.match?(i.identifier) } - - children.map { |i| self.class.new(i, @context) }.freeze - end - - # Returns the parent of this item, if one exists. For items with identifiers - # that have extensions, returns nil. - # - # @return [Nanoc::CompilationItemView] if the item has a parent - # - # @return [nil] if the item has no parent - def parent - unless _unwrap.identifier.legacy? - raise Nanoc::Int::Errors::CannotGetParentOrChildrenOfNonLegacyItem.new(_unwrap.identifier) - end - - parent_identifier = '/' + _unwrap.identifier.components[0..-2].join('/') + '/' - parent_identifier = '/' if parent_identifier == '//' - - parent = @context.items[parent_identifier] - - parent && self.class.new(parent, @context) - end - - # @return [Boolean] True if the item is binary, false otherwise - def binary? - _unwrap.content.binary? - end - - # @return [String, nil] The path to the file containing the uncompiled content of this item. - def raw_filename - @context.dependency_tracker.bounce(_unwrap, raw_content: true) - _unwrap.content.filename - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/compilation_item_rep_collection_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/compilation_item_rep_collection_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/compilation_item_rep_collection_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/compilation_item_rep_collection_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class CompilationItemRepCollectionView < ::Nanoc::BasicItemRepCollectionView - # @api private - def view_class - Nanoc::CompilationItemRepView - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/compilation_item_rep_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/compilation_item_rep_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/compilation_item_rep_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/compilation_item_rep_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class CompilationItemRepView < ::Nanoc::BasicItemRepView - # @abstract - def item_view_class - Nanoc::CompilationItemView - end - - # Returns the item rep’s raw path. It includes the path to the output - # directory and the full filename. - # - # @param [Symbol] snapshot The snapshot for which the path should be - # returned. - # - # @return [String] The item rep’s raw path. - def raw_path(snapshot: :last) - @context.dependency_tracker.bounce(_unwrap.item, compiled_content: true) - - res = @item_rep.raw_path(snapshot: snapshot) - - unless @item_rep.compiled? - Fiber.yield(Nanoc::Int::Errors::UnmetDependency.new(@item_rep)) - end - - # Wait for file to exist - if res - start = Time.now - sleep 0.05 until File.file?(res) || Time.now - start > 1.0 - raise Nanoc::Int::Errors::InternalInconsistency, "File did not apear in time: #{res}" unless File.file?(res) - end - - res - end - - # Returns the compiled content. - # - # @param [String] snapshot The name of the snapshot from which to - # fetch the compiled content. By default, the returned compiled content - # will be the content compiled right before the first layout call (if - # any). - # - # @return [String] The content at the given snapshot. - def compiled_content(snapshot: nil) - @context.dependency_tracker.bounce(_unwrap.item, compiled_content: true) - @context.snapshot_repo.compiled_content(rep: _unwrap, snapshot: snapshot) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/compilation_item_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/compilation_item_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/compilation_item_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/compilation_item_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class CompilationItemView < ::Nanoc::BasicItemView - # Returns the compiled content. - # - # @param [String] rep The name of the representation - # from which the compiled content should be fetched. By default, the - # compiled content will be fetched from the default representation. - # - # @param [String] snapshot The name of the snapshot from which to - # fetch the compiled content. By default, the returned compiled content - # will be the content compiled right before the first layout call (if - # any). - # - # @return [String] The content of the given rep at the given snapshot. - def compiled_content(rep: :default, snapshot: nil) - reps.fetch(rep).compiled_content(snapshot: snapshot) - end - - # Returns the item path, as used when being linked to. It starts - # with a slash and it is relative to the output directory. It does not - # include the path to the output directory. It will not include the - # filename if the filename is an index filename. - # - # @param [String] rep The name of the representation - # from which the path should be fetched. By default, the path will be - # fetched from the default representation. - # - # @param [Symbol] snapshot The snapshot for which the - # path should be returned. - # - # @return [String] The item’s path. - def path(rep: :default, snapshot: :last) - reps.fetch(rep).path(snapshot: snapshot) - end - - # Returns the representations of this item. - # - # @return [Nanoc::BasicItemRepCollectionView] - def reps - Nanoc::CompilationItemRepCollectionView.new(@context.reps[_unwrap], @context) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/config_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/config_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/config_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/config_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class ConfigView < ::Nanoc::View - # @api private - NONE = Object.new.freeze - - # @api private - def initialize(config, context) - super(context) - @config = config - end - - # @api private - def _unwrap - @config - end - - # @api private - def output_dir - @config.output_dir - end - - # @see Hash#fetch - def fetch(key, fallback = NONE, &_block) - @context.dependency_tracker.bounce(_unwrap, attributes: [key]) - @config.fetch(key) do - if !fallback.equal?(NONE) - fallback - elsif block_given? - yield(key) - else - raise KeyError, "key not found: #{key.inspect}" - end - end - end - - # @see Hash#key? - def key?(key) - @context.dependency_tracker.bounce(_unwrap, attributes: [key]) - @config.key?(key) - end - - # @see Hash#[] - def [](key) - @context.dependency_tracker.bounce(_unwrap, attributes: [key]) - @config[key] - end - - # @see Hash#each - def each(&block) - @context.dependency_tracker.bounce(_unwrap, attributes: true) - @config.each(&block) - end - - # @see Hash#dig - def dig(*keys) - @context.dependency_tracker.bounce(_unwrap, attributes: keys.take(1)) - @config.dig(*keys) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/identifiable_collection_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/identifiable_collection_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/identifiable_collection_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/identifiable_collection_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class IdentifiableCollectionView < ::Nanoc::View - include Enumerable - - NOTHING = Object.new - - # @api private - def initialize(objects, context) - super(context) - @objects = objects - end - - # @api private - def _unwrap - @objects - end - - # @abstract - # - # @api private - def view_class - raise NotImplementedError - end - - # Calls the given block once for each object, passing that object as a parameter. - # - # @yieldparam [#identifier] object - # - # @yieldreturn [void] - # - # @return [self] - def each - @context.dependency_tracker.bounce(_unwrap, raw_content: true) - @objects.each { |i| yield view_class.new(i, @context) } - self - end - - # @return [Integer] - def size - @context.dependency_tracker.bounce(_unwrap, raw_content: true) - @objects.size - end - - # Finds all objects whose identifier matches the given argument. - # - # @param [String, Regex] arg - # - # @return [Enumerable] - def find_all(arg = NOTHING, &block) - if NOTHING.equal?(arg) - @context.dependency_tracker.bounce(_unwrap, raw_content: true) - return @objects.select(&block).map { |i| view_class.new(i, @context) } - end - - prop_attribute = - case arg - when String, Nanoc::Identifier - [arg.to_s] - when Regexp - [arg] - else - true - end - - @context.dependency_tracker.bounce(_unwrap, raw_content: prop_attribute) - @objects.find_all(arg).map { |i| view_class.new(i, @context) } - end - - # @overload [](string) - # - # Finds the object whose identifier matches the given string. - # - # If the glob syntax is enabled, the string can be a glob, in which case - # this method finds the first object that matches the given glob. - # - # @param [String] string - # - # @return [nil] if no object matches the string - # - # @return [#identifier] if an object was found - # - # @overload [](regex) - # - # Finds the object whose identifier matches the given regular expression. - # - # @param [Regex] regex - # - # @return [nil] if no object matches the regex - # - # @return [#identifier] if an object was found - def [](arg) - prop_attribute = - case arg - when String, Nanoc::Identifier - [arg.to_s] - when Regexp - [arg] - else - true - end - - @context.dependency_tracker.bounce(_unwrap, raw_content: prop_attribute) - res = @objects[arg] - res && view_class.new(res, @context) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/item_collection_without_reps_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/item_collection_without_reps_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/item_collection_without_reps_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/item_collection_without_reps_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class ItemCollectionWithoutRepsView < ::Nanoc::IdentifiableCollectionView - # @api private - def view_class - Nanoc::BasicItemView - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/item_collection_with_reps_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/item_collection_with_reps_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/item_collection_with_reps_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/item_collection_with_reps_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class ItemCollectionWithRepsView < ::Nanoc::IdentifiableCollectionView - # @api private - def view_class - Nanoc::CompilationItemView - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/layout_collection_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/layout_collection_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/layout_collection_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/layout_collection_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class LayoutCollectionView < ::Nanoc::IdentifiableCollectionView - # @api private - def view_class - Nanoc::LayoutView - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/layout_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/layout_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/layout_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/layout_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class LayoutView < ::Nanoc::View - include Nanoc::DocumentViewMixin - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/mixins/document_view_mixin.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/mixins/document_view_mixin.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/mixins/document_view_mixin.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/mixins/document_view_mixin.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - module DocumentViewMixin - # @api private - NONE = Object.new.freeze - - # @api private - def initialize(document, context) - super(context) - @document = document - end - - # @api private - def _unwrap - @document - end - - # @see Object#== - def ==(other) - other.respond_to?(:identifier) && identifier == other.identifier - end - - # @see Object#eql? - def eql?(other) - other.is_a?(self.class) && identifier.eql?(other.identifier) - end - - # @see Object#hash - def hash - self.class.hash ^ identifier.hash - end - - # @return [Nanoc::Identifier] - def identifier - _unwrap.identifier - end - - # @see Hash#[] - def [](key) - @context.dependency_tracker.bounce(_unwrap, attributes: [key]) - _unwrap.attributes[key] - end - - # @return [Hash] - def attributes - # TODO: Refine dependencies - @context.dependency_tracker.bounce(_unwrap, attributes: true) - _unwrap.attributes - end - - # @see Hash#fetch - def fetch(key, fallback = NONE, &_block) - @context.dependency_tracker.bounce(_unwrap, attributes: [key]) - - if _unwrap.attributes.key?(key) - _unwrap.attributes[key] - elsif !fallback.equal?(NONE) - fallback - elsif block_given? - yield(key) - else - raise KeyError, "key not found: #{key.inspect}" - end - end - - # @see Hash#key? - def key?(key) - @context.dependency_tracker.bounce(_unwrap, attributes: [key]) - _unwrap.attributes.key?(key) - end - - # @api private - def reference - _unwrap.reference - end - - # @api private - def raw_content - @context.dependency_tracker.bounce(_unwrap, raw_content: true) - _unwrap.content.string - end - - def inspect - "<#{self.class} identifier=#{_unwrap.identifier}>" - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/mixins/mutable_document_view_mixin.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/mixins/mutable_document_view_mixin.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/mixins/mutable_document_view_mixin.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/mixins/mutable_document_view_mixin.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - module MutableDocumentViewMixin - # @api private - class DisallowedAttributeValueError < Nanoc::Error - attr_reader :value - - def initialize(value) - @value = value - end - - def message - "The #{value.class} cannot be stored inside an attribute. Store its identifier instead." - end - end - - def raw_content=(arg) - _unwrap.content = Nanoc::Int::Content.create(arg) - end - - # Sets the value for the given attribute. - # - # @param [Symbol] key - # - # @see Hash#[]= - def []=(key, value) - disallowed_value_classes = Set.new([ - Nanoc::Int::Item, - Nanoc::Int::Layout, - Nanoc::CompilationItemView, - Nanoc::LayoutView, - ]) - if disallowed_value_classes.include?(value.class) - raise DisallowedAttributeValueError.new(value) - end - - _unwrap.set_attribute(key, value) - end - - # Sets the identifier to the given argument. - # - # @param [String, Nanoc::Identifier] arg - def identifier=(arg) - _unwrap.identifier = Nanoc::Identifier.from(arg) - end - - # Updates the attributes based on the given hash. - # - # @param [Hash] hash - # - # @return [self] - def update_attributes(hash) - hash.each { |k, v| _unwrap.set_attribute(k, v) } - self - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/mutable_config_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/mutable_config_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/mutable_config_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/mutable_config_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class MutableConfigView < Nanoc::ConfigView - # Sets the value for the given attribute. - # - # @param [Symbol] key - # - # @see Hash#[]= - def []=(key, value) - @config[key] = value - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/mutable_identifiable_collection_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/mutable_identifiable_collection_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/mutable_identifiable_collection_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/mutable_identifiable_collection_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class MutableIdentifiableCollectionView < Nanoc::IdentifiableCollectionView - # Deletes every object for which the block evaluates to true. - # - # @yieldparam [#identifier] object - # - # @yieldreturn [Boolean] - # - # @return [self] - def delete_if(&_block) - @objects = @objects.reject { |o| yield(view_class.new(o, @context)) } - self - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/mutable_item_collection_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/mutable_item_collection_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/mutable_item_collection_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/mutable_item_collection_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class MutableItemCollectionView < Nanoc::MutableIdentifiableCollectionView - # @api private - def view_class - Nanoc::MutableItemView - end - - # Creates a new item and adds it to the site’s collection of items. - # - # @param [String] content The uncompiled item content (if it is a textual - # item) or the path to the filename containing the content (if it is a - # binary item). - # - # @param [Hash] attributes A hash containing this item's attributes. - # - # @param [Nanoc::Identifier, String] identifier This item's identifier. - # - # @param [Boolean] binary Whether or not this item is binary - # - # @param [String] filename Absolute path to the file - # containing this content (if any) - # - # @return [self] - def create(content, attributes, identifier, binary: false, filename: nil) - content = Nanoc::Int::Content.create(content, binary: binary, filename: filename) - @objects = @objects.add(Nanoc::Int::Item.new(content, attributes, identifier)) - self - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/mutable_item_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/mutable_item_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/mutable_item_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/mutable_item_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class MutableItemView < Nanoc::BasicItemView - include Nanoc::MutableDocumentViewMixin - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/mutable_layout_collection_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/mutable_layout_collection_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/mutable_layout_collection_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/mutable_layout_collection_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class MutableLayoutCollectionView < Nanoc::MutableIdentifiableCollectionView - # @api private - def view_class - Nanoc::MutableLayoutView - end - - # Creates a new layout and adds it to the site’s collection of layouts. - # - # @param [String] content The layout content. - # - # @param [Hash] attributes A hash containing this layout's attributes. - # - # @param [Nanoc::Identifier, String] identifier This layout's identifier. - # - # @return [self] - def create(content, attributes, identifier) - @objects = @objects.add(Nanoc::Int::Layout.new(content, attributes, identifier)) - self - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/mutable_layout_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/mutable_layout_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/mutable_layout_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/mutable_layout_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class MutableLayoutView < Nanoc::LayoutView - include Nanoc::MutableDocumentViewMixin - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/post_compile_item_collection_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/post_compile_item_collection_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/post_compile_item_collection_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/post_compile_item_collection_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class PostCompileItemCollectionView < Nanoc::IdentifiableCollectionView - # @api private - def view_class - Nanoc::PostCompileItemView - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/post_compile_item_rep_collection_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/post_compile_item_rep_collection_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/post_compile_item_rep_collection_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/post_compile_item_rep_collection_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class PostCompileItemRepCollectionView < Nanoc::BasicItemRepCollectionView - # @api private - def view_class - Nanoc::PostCompileItemRepView - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/post_compile_item_rep_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/post_compile_item_rep_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/post_compile_item_rep_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/post_compile_item_rep_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class PostCompileItemRepView < ::Nanoc::BasicItemRepView - def item_view_class - Nanoc::PostCompileItemView - end - - def compiled_content(snapshot: nil) - compilation_context = @context.compilation_context - snapshot_contents = compilation_context.compiled_content_cache[_unwrap] - - snapshot_name = snapshot || (snapshot_contents[:pre] ? :pre : :last) - - unless snapshot_contents[snapshot_name] - raise Nanoc::Int::Errors::NoSuchSnapshot.new(_unwrap, snapshot_name) - end - - content = snapshot_contents[snapshot_name] - if content.binary? - raise Nanoc::Int::Errors::CannotGetCompiledContentOfBinaryItem.new(_unwrap) - end - - content.string - end - - def raw_path(snapshot: :last) - @item_rep.raw_path(snapshot: snapshot) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/post_compile_item_view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/post_compile_item_view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/post_compile_item_view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/post_compile_item_view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class PostCompileItemView < Nanoc::CompilationItemView - def reps - Nanoc::PostCompileItemRepCollectionView.new(@context.reps[_unwrap], @context) - end - - # @deprecated Use {#modified_reps} instead - def modified - modified_reps - end - - def modified_reps - reps.select { |rep| rep._unwrap.modified? } - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/view_context_for_compilation.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/view_context_for_compilation.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/view_context_for_compilation.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/view_context_for_compilation.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - # @api private - class ViewContextForCompilation - include Nanoc::Int::ContractsSupport - - attr_reader :reps - attr_reader :items - attr_reader :dependency_tracker - attr_reader :compilation_context - attr_reader :snapshot_repo - - contract C::KeywordArgs[ - reps: Nanoc::Int::ItemRepRepo, - items: Nanoc::Int::IdentifiableCollection, - dependency_tracker: C::Any, - compilation_context: C::Any, - snapshot_repo: C::Any, - ] => C::Any - def initialize(reps:, items:, dependency_tracker:, compilation_context:, snapshot_repo:) - @reps = reps - @items = items - @dependency_tracker = dependency_tracker - @compilation_context = compilation_context - @snapshot_repo = snapshot_repo - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/view_context_for_pre_compilation.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/view_context_for_pre_compilation.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/view_context_for_pre_compilation.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/view_context_for_pre_compilation.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - # @api private - class ViewContextForPreCompilation - include Nanoc::Int::ContractsSupport - - attr_reader :items - attr_reader :dependency_tracker - - contract C::KeywordArgs[items: Nanoc::Int::IdentifiableCollection] => C::Any - def initialize(items:) - @items = items - - @dependency_tracker = Nanoc::Int::DependencyTracker::Null.new - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/view_context_for_shell.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/view_context_for_shell.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/view_context_for_shell.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/view_context_for_shell.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - # @api private - class ViewContextForShell - include Nanoc::Int::ContractsSupport - - attr_reader :items - attr_reader :reps - attr_reader :dependency_tracker - - contract C::KeywordArgs[ - items: Nanoc::Int::IdentifiableCollection, - reps: Nanoc::Int::ItemRepRepo, - ] => C::Any - def initialize(items:, reps:) - @items = items - @reps = reps - - @dependency_tracker = Nanoc::Int::DependencyTracker::Null.new - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views/view.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views/view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views/view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views/view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - class View - # @api private - def initialize(context) - @context = context - end - - # @api private - def _context - @context - end - - # @api private - def _unwrap - raise NotImplementedError - end - - # True if the wrapped object is frozen; false otherwise. - # - # @return [Boolean] - # - # @see Object#frozen? - def frozen? - _unwrap.frozen? - end - - def inspect - "<#{self.class}>" - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base/views.rb nanoc-4.11.14/nanoc/lib/nanoc/base/views.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base/views.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base/views.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require_relative 'views/mixins/document_view_mixin' -require_relative 'views/mixins/mutable_document_view_mixin' - -require_relative 'views/view_context_for_compilation' -require_relative 'views/view_context_for_pre_compilation' -require_relative 'views/view_context_for_shell' - -require_relative 'views/view' - -require_relative 'views/basic_item_rep_view' -require_relative 'views/basic_item_rep_collection_view' -require_relative 'views/basic_item_view' - -require_relative 'views/compilation_item_rep_view' -require_relative 'views/compilation_item_rep_collection_view' -require_relative 'views/compilation_item_view' - -require_relative 'views/config_view' -require_relative 'views/identifiable_collection_view' -require_relative 'views/item_collection_with_reps_view' -require_relative 'views/item_collection_without_reps_view' -require_relative 'views/layout_view' -require_relative 'views/layout_collection_view' - -require_relative 'views/mutable_config_view' -require_relative 'views/mutable_identifiable_collection_view' -require_relative 'views/mutable_item_view' -require_relative 'views/mutable_item_collection_view' -require_relative 'views/mutable_layout_view' -require_relative 'views/mutable_layout_collection_view' - -require_relative 'views/post_compile_item_view' -require_relative 'views/post_compile_item_collection_view' -require_relative 'views/post_compile_item_rep_view' -require_relative 'views/post_compile_item_rep_collection_view' diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/base.rb nanoc-4.11.14/nanoc/lib/nanoc/base.rb --- nanoc-4.11.0/nanoc/lib/nanoc/base.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/base.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,18 +1,13 @@ # frozen_string_literal: true # @api private -module Nanoc::Int +module Nanoc + module Int + end + + module Base + end end -require_relative 'base/core_ext' -require_relative 'base/contracts_support' -require_relative 'base/error' require_relative 'base/errors' require_relative 'base/changes_stream' -require_relative 'base/assertions' - -require_relative 'base/entities' -require_relative 'base/feature' -require_relative 'base/repos' -require_relative 'base/services' -require_relative 'base/views' diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/checking/check.rb nanoc-4.11.14/nanoc/lib/nanoc/checking/check.rb --- nanoc-4.11.0/nanoc/lib/nanoc/checking/check.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/checking/check.rb 2019-11-10 09:34:31.000000000 +0000 @@ -2,16 +2,18 @@ module Nanoc::Checking # @api private - class OutputDirNotFoundError < Nanoc::Int::Errors::Generic + class OutputDirNotFoundError < ::Nanoc::Core::Error def initialize(directory_path) super("Unable to run check against output directory at “#{directory_path}”: directory does not exist.") end end # @api private - class Check < Nanoc::Int::Context + class Check < Nanoc::Core::Context extend DDPlugin::Plugin + DDMemoize.activate(self) + attr_reader :issues def self.define(ident, &block) @@ -30,16 +32,19 @@ output_filenames = Dir[output_dir + '/**/*'].select { |f| File.file?(f) } # FIXME: ugly - compiler = Nanoc::Int::Compiler.new_for(site) + compiler = Nanoc::Core::Compiler.new_for(site) res = compiler.run_until_reps_built reps = res.fetch(:reps) - compilation_context = compiler.compilation_context(reps: reps) - view_context = compilation_context.create_view_context(Nanoc::Int::DependencyTracker::Null.new) + view_context = + Nanoc::Core::ViewContextForShell.new( + items: site.items, + reps: reps, + ) context = { - items: Nanoc::PostCompileItemCollectionView.new(site.items, view_context), - layouts: Nanoc::LayoutCollectionView.new(site.layouts, view_context), - config: Nanoc::ConfigView.new(site.config, view_context), + items: Nanoc::Core::PostCompileItemCollectionView.new(site.items, view_context), + layouts: Nanoc::Core::LayoutCollectionView.new(site.layouts, view_context), + config: Nanoc::Core::ConfigView.new(site.config, view_context), output_filenames: output_filenames, } @@ -67,6 +72,20 @@ end # @private + def output_filenames + super.reject { |f| excluded_patterns.any? { |pat| pat.match?(f) } } + end + + # @private + memoized def excluded_patterns + @config + .fetch(:checks, {}) + .fetch(:all, {}) + .fetch(:exclude_files, []) + .map { |pattern| Regexp.new(pattern) } + end + + # @private def output_html_filenames output_filenames.select { |f| File.extname(f) =~ /\A\.x?html?\z/ } end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/checking/checks/external_links.rb nanoc-4.11.14/nanoc/lib/nanoc/checking/checks/external_links.rb --- nanoc-4.11.0/nanoc/lib/nanoc/checking/checks/external_links.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/checking/checks/external_links.rb 2019-11-10 09:34:31.000000000 +0000 @@ -12,7 +12,7 @@ # TODO: de-duplicate this (duplicated in internal links check) filenames = output_html_filenames.reject { |f| excluded_file?(f) } hrefs_with_filenames = ::Nanoc::Extra::LinkCollector.new(filenames, :external).filenames_per_href - results = select_invalid(hrefs_with_filenames.keys) + results = select_invalid(hrefs_with_filenames.keys.shuffle) # Report them results.each do |res| @@ -77,6 +77,10 @@ location = extract_location(res, url) return Result.new(href, 'redirection without a target location') if location.nil? + if /^30[18]$/.match?(res.code) + return Result.new(href, "link has moved permanently to '#{location}'") + end + url = URI.parse(location) elsif res.code == '200' return nil @@ -87,7 +91,7 @@ if last_err return Result.new(href, last_err.message) else - raise Nanoc::Int::Errors::InternalInconsistency, 'last_err cannot be nil' + raise Nanoc::Core::Errors::InternalInconsistency, 'last_err cannot be nil' end end @@ -125,6 +129,7 @@ def request_url_once(url) req = Net::HTTP::Get.new(path_for_url(url)) + req['User-Agent'] = "Mozilla/5.0 Nanoc/#{Nanoc::VERSION} (link rot checker)" http = Net::HTTP.new(url.host, url.port) if url.instance_of? URI::HTTPS http.use_ssl = true diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/checking/checks/internal_links.rb nanoc-4.11.14/nanoc/lib/nanoc/checking/checks/internal_links.rb --- nanoc-4.11.0/nanoc/lib/nanoc/checking/checks/internal_links.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/checking/checks/internal_links.rb 2019-11-10 09:34:31.000000000 +0000 @@ -16,10 +16,8 @@ def run # TODO: de-duplicate this (duplicated in external links check) filenames = output_html_filenames - hrefs_with_filenames = ::Nanoc::Extra::LinkCollector.new(filenames, :internal).filenames_per_href - resource_uris_with_filenames = ::Nanoc::Extra::LinkCollector.new(filenames, :internal).filenames_per_resource_uri + uris = ::Nanoc::Extra::LinkCollector.new(filenames, :internal).filenames_per_href - uris = hrefs_with_filenames.merge(resource_uris_with_filenames) uris.each_pair do |href, fns| fns.each do |filename| next if valid?(href, filename) @@ -39,11 +37,23 @@ # FIXME: this is ugly and won’t always be correct return true if href == '.' + # Turn file: into output_dir-as-root relative paths + + output_dir = @config.output_dir + output_dir += '/' unless output_dir.end_with?('/') + base_uri = URI("file://#{output_dir}") + path = href.sub(/#{base_uri}/, '').sub(/file:\/{1,3}/, '') + + path = "/#{path}" unless path.start_with?('/') + # Skip hrefs that are specified in the exclude configuration - return true if excluded?(href, origin) + return true if excluded?(path, origin) - # Remove target - path = href.sub(/#.*$/, '') + # Make an absolute path + path = ::File.join(output_dir, path[1..path.length]) + + # Remove fragment + path = path.sub(/#.*$/, '') return true if path.empty? # Remove query string @@ -53,14 +63,6 @@ # Decode URL (e.g. '%20' -> ' ') path = CGI.unescape(path) - # Make absolute - path = - if path[0, 1] == '/' - @config.output_dir + path - else - ::File.expand_path(path, ::File.dirname(origin)) - end - # Check whether file exists return true if File.file?(path) diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/checking/checks/stale.rb nanoc-4.11.14/nanoc/lib/nanoc/checking/checks/stale.rb --- nanoc-4.11.0/nanoc/lib/nanoc/checking/checks/stale.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/checking/checks/stale.rb 2019-11-10 09:34:31.000000000 +0000 @@ -33,8 +33,9 @@ def pruner exclude_config = @config.fetch(:prune, {}).fetch(:exclude, []) - # FIXME: reps=nil is icky - @pruner ||= Nanoc::Pruner.new(@config, nil, exclude: exclude_config) + # FIXME: specifying reps this way is icky + reps = Nanoc::Core::ItemRepRepo.new + @pruner ||= Nanoc::Core::Pruner.new(@config._unwrap, reps, exclude: exclude_config) end end end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/checking/runner.rb nanoc-4.11.14/nanoc/lib/nanoc/checking/runner.rb --- nanoc-4.11.0/nanoc/lib/nanoc/checking/runner.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/checking/runner.rb 2019-11-10 09:34:31.000000000 +0000 @@ -5,7 +5,7 @@ # # @api private class Runner - # @param [Nanoc::Int::Site] site The Nanoc site this runner is for + # @param [Nanoc::Core::Site] site The Nanoc site this runner is for def initialize(site) @site = site end @@ -80,7 +80,7 @@ names.map do |name| name = name.to_s.tr('-', '_').to_sym klass = Nanoc::Checking::Check.named(name) - raise Nanoc::Int::Errors::GenericTrivial, "Unknown check: #{name}" if klass.nil? + raise Nanoc::Core::TrivialError, "Unknown check: #{name}" if klass.nil? klass end @@ -90,7 +90,7 @@ return [] if classes.empty? # TODO: remove me - Nanoc::Int::Compiler.new_for(@site).run_until_reps_built + Nanoc::Core::Compiler.new_for(@site).run_until_reps_built checks = [] issues = Set.new diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/ansi_string_colorizer.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/ansi_string_colorizer.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/ansi_string_colorizer.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/ansi_string_colorizer.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI - # A simple ANSI colorizer for strings. When given a string and a list of - # attributes, it returns a colorized string. - # - # @api private - module ANSIStringColorizer - # TODO: complete mapping - MAPPING = { - bold: "\e[1m", - red: "\e[31m", - green: "\e[32m", - yellow: "\e[33m", - blue: "\e[34m", - }.freeze - - # @param [String] str The string to colorize - # - # @param [Array] attrs An array of attributes from `MAPPING` to colorize the - # string with - # - # @return [String] A string colorized using the given attributes - def self.c(str, *attrs) - attrs.map { |a| MAPPING[a] }.join('') + str + "\e[0m" - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/cleaning_stream.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/cleaning_stream.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/cleaning_stream.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/cleaning_stream.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,160 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI - # An output stream that passes output through stream cleaners. This can be - # used to strip ANSI color sequences, for instance. - # - # @api private - class CleaningStream - # @param [IO, StringIO] stream The stream to wrap - def initialize(stream) - @stream = stream - @stream_cleaners = [] - end - - # Adds a stream cleaner for the given class to this cleaning stream. If the - # cleaning stream already has the given stream cleaner, nothing happens. - # - # @param [Nanoc::CLI::StreamCleaners::Abstract] klass The class of the - # stream cleaner to add - # - # @return [void] - def add_stream_cleaner(klass) - unless @stream_cleaners.map(&:class).include?(klass) - @stream_cleaners << klass.new - end - end - - # Removes the stream cleaner for the given class from this cleaning stream. - # If the cleaning stream does not have the given stream cleaner, nothing - # happens. - # - # @param [Nanoc::CLI::StreamCleaners::Abstract] klass The class of the - # stream cleaner to add - # - # @return [void] - def remove_stream_cleaner(klass) - @stream_cleaners.delete_if { |c| c.class == klass } - end - - # @group IO proxy methods - - # @see IO#write - def write(str) - _nanoc_swallow_broken_pipe_errors_while do - @stream.write(_nanoc_clean(str)) - end - end - - # @see IO#<< - def <<(str) - _nanoc_swallow_broken_pipe_errors_while do - @stream.<<(_nanoc_clean(str)) - end - end - - # @see IO#tty? - def tty? - @cached_is_tty ||= @stream.tty? - end - - # @see IO#isatty - def isatty - tty? - end - - # @see IO#flush - def flush - _nanoc_swallow_broken_pipe_errors_while do - @stream.flush - end - end - - # @see IO#tell - def tell - @stream.tell - end - - # @see IO#print - def print(str) - _nanoc_swallow_broken_pipe_errors_while do - @stream.print(_nanoc_clean(str)) - end - end - - # @see IO#puts - def puts(*str) - _nanoc_swallow_broken_pipe_errors_while do - @stream.puts(*str.map { |ss| _nanoc_clean(ss) }) - end - end - - # @see StringIO#string - def string - @stream.string - end - - # @see IO#reopen - def reopen(*args) - @stream.reopen(*args) - end - - # @see IO#close - def close - @stream.close - end - - # @see File#exist? - def exist? - @stream.exist? - end - - # @see File.exists? - def exists? - @stream.exists? - end - - # @see IO.winsize - def winsize - @stream.winsize - end - - # @see IO.winsize= - def winsize=(arg) - @stream.winsize = arg - end - - # @see IO.sync - def sync - @stream.sync - end - - # @see IO.sync= - def sync=(arg) - @stream.sync = arg - end - - # @see IO.sync= - def external_encoding - @stream.external_encoding - end - - # @see ARGF.set_encoding - # rubocop:disable Naming/AccessorMethodName - def set_encoding(*args) - @stream.set_encoding(*args) - end - # rubocop:enable Naming/AccessorMethodName - - protected - - def _nanoc_clean(str) - @stream_cleaners.reduce(str.to_s.scrub) { |acc, elem| elem.clean(acc) } - end - - def _nanoc_swallow_broken_pipe_errors_while - yield - rescue Errno::EPIPE - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/command_runner.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/command_runner.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/command_runner.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/command_runner.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI - # A command runner subclass for Nanoc commands that adds Nanoc-specific - # convenience methods and error handling. - # - # @api private - class CommandRunner < ::Cri::CommandRunner - # @see http://rubydoc.info/gems/cri/Cri/CommandRunner#call-instance_method - # - # @return [void] - def call - Nanoc::CLI::ErrorHandler.handle_while do - run - end - end - - # @return [Boolean] true if the current working directory is a Nanoc site - # directory, false otherwise - def in_site_dir? - Nanoc::Int::SiteLoader.cwd_is_nanoc_site? - end - - def self.find_site_dir - start_here = Dir.pwd - - here = start_here - until Nanoc::Int::SiteLoader.cwd_is_nanoc_site? - Dir.chdir('..') - return nil if Dir.pwd == here - - here = Dir.pwd - end - here - ensure - Dir.chdir(start_here) - end - - def self.enter_site_dir - dir = find_site_dir - if dir.nil? - raise ::Nanoc::Int::Errors::GenericTrivial, 'The current working directory, nor any of its parents, seems to be a Nanoc site.' - end - - return if Dir.getwd == dir - - $stderr.puts "Using Nanoc site in #{dir}" - Dir.chdir(dir) - end - - # Asserts that the current working directory contains a site and loads the site into memory. - # - # @return [void] - def load_site - self.class.enter_site_dir - - $stderr.print 'Loading site… ' - $stderr.flush - site = Nanoc::Int::SiteLoader.new.new_from_cwd - - $stderr.puts 'done' - site - end - - # @return [Boolean] true if debug output is enabled, false if not - # - # @see Nanoc::CLI.debug? - def debug? - Nanoc::CLI.debug? - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/check.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/check.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/check.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/check.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -usage 'check [options] [names]' -summary 'run issue checks' -description " -Run issue checks on the current site. If the `--all` option is passed, all available issue checks will be run. By default, the issue checks marked for deployment will be run. -" - -flag :a, :all, 'run all checks' -flag :L, :list, 'list all checks' -flag :d, :deploy, '(deprecated)' - -module Nanoc::CLI::Commands - class Check < ::Nanoc::CLI::CommandRunner - def run - site = load_site - - runner = Nanoc::Checking::Runner.new(site) - - if options[:list] - runner.list_checks - return - end - - success = - if options[:all] - runner.run_all - elsif options[:deploy] - runner.run_for_deploy - elsif arguments.any? - runner.run_specific(arguments) - else - runner.run_for_deploy - end - - unless success - raise Nanoc::Int::Errors::GenericTrivial, 'One or more checks failed' - end - end - end -end - -runner Nanoc::CLI::Commands::Check diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile_listeners/abstract.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile_listeners/abstract.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile_listeners/abstract.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile_listeners/abstract.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI::Commands::CompileListeners - class Abstract - def initialize(*); end - - def self.enable_for?(command_runner, site) # rubocop:disable Lint/UnusedMethodArgument - true - end - - # @abstract - def start - raise NotImplementedError, "Subclasses of #{self.class} must implement #start" - end - - # @abstract - def stop; end - - def run_while - start - yield - ensure - stop - end - - def start_safely - start - @_started = true - end - - def stop_safely - stop if @_started - @_started = false - end - - def on(sym) - # TODO: clean up on stop - Nanoc::Int::NotificationCenter.on(sym, self) { |*args| yield(*args) } - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile_listeners/aggregate.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile_listeners/aggregate.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile_listeners/aggregate.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile_listeners/aggregate.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI::Commands::CompileListeners - class Aggregate < Abstract - def initialize(command_runner:, site:, compiler:) - @site = site - @compiler = compiler - @command_runner = command_runner - - @listener_classes = self.class.default_listener_classes - end - - def start - setup_listeners - end - - def stop - teardown_listeners - end - - def self.default_listener_classes - [ - Nanoc::CLI::Commands::CompileListeners::DiffGenerator, - Nanoc::CLI::Commands::CompileListeners::DebugPrinter, - Nanoc::CLI::Commands::CompileListeners::TimingRecorder, - Nanoc::CLI::Commands::CompileListeners::FileActionPrinter, - ] - end - - protected - - def setup_listeners - res = @compiler.run_until_reps_built - reps = res.fetch(:reps) - - @listeners = - @listener_classes - .select { |klass| klass.enable_for?(@command_runner, @site) } - .map { |klass| klass.new(reps: reps) } - - @listeners.each(&:start_safely) - end - - def teardown_listeners - return unless @listeners - - @listeners.reverse_each(&:stop_safely) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile_listeners/debug_printer.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile_listeners/debug_printer.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile_listeners/debug_printer.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile_listeners/debug_printer.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI::Commands::CompileListeners - class DebugPrinter < Abstract - # @see Listener#enable_for? - def self.enable_for?(command_runner, _site) - command_runner.debug? - end - - # @see Listener#start - def start - Nanoc::Int::NotificationCenter.on(:compilation_started) do |rep| - puts "*** Started compilation of #{rep.inspect}" - end - Nanoc::Int::NotificationCenter.on(:compilation_ended) do |rep| - puts "*** Ended compilation of #{rep.inspect}" - puts - end - Nanoc::Int::NotificationCenter.on(:compilation_suspended) do |rep, e| - puts "*** Suspended compilation of #{rep.inspect}: #{e.message}" - end - Nanoc::Int::NotificationCenter.on(:cached_content_used) do |rep| - puts "*** Used cached compiled content for #{rep.inspect} instead of recompiling" - end - Nanoc::Int::NotificationCenter.on(:filtering_started) do |rep, filter_name| - puts "*** Started filtering #{rep.inspect} with #{filter_name}" - end - Nanoc::Int::NotificationCenter.on(:filtering_ended) do |rep, filter_name| - puts "*** Ended filtering #{rep.inspect} with #{filter_name}" - end - Nanoc::Int::NotificationCenter.on(:dependency_created) do |src, dst| - puts "*** Dependency created from #{src.inspect} onto #{dst.inspect}" - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile_listeners/diff_generator.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile_listeners/diff_generator.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile_listeners/diff_generator.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile_listeners/diff_generator.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI::Commands::CompileListeners - class DiffGenerator < Abstract - # @see Listener#enable_for? - def self.enable_for?(command_runner, site) - site.config[:enable_output_diff] || command_runner.options[:diff] - end - - # @see Listener#start - def start - setup_diffs - old_contents = {} - Nanoc::Int::NotificationCenter.on(:rep_write_started, self) do |rep, path| - old_contents[rep] = File.file?(path) ? File.read(path) : nil - end - Nanoc::Int::NotificationCenter.on(:rep_write_ended, self) do |rep, binary, path, _is_created, _is_modified| - unless binary - new_contents = File.file?(path) ? File.read(path) : nil - if old_contents[rep] && new_contents - generate_diff_for(path, old_contents[rep], new_contents) - end - old_contents.delete(rep) - end - end - end - - # @see Listener#stop - def stop - super - - Nanoc::Int::NotificationCenter.remove(:rep_write_started, self) - Nanoc::Int::NotificationCenter.remove(:rep_write_ended, self) - - teardown_diffs - end - - protected - - def setup_diffs - @diff_lock = Mutex.new - @diff_threads = [] - FileUtils.rm('output.diff') if File.file?('output.diff') - end - - def teardown_diffs - @diff_threads.each(&:join) - end - - def generate_diff_for(path, old_content, new_content) - return if old_content == new_content - - @diff_threads << Thread.new do - # Simplify path - # FIXME: do not depend on working directory - if path.start_with?(Dir.getwd) - path = path[(Dir.getwd.size + 1)..path.size] - end - - # Generate diff - diff = diff_strings(old_content, new_content) - diff.sub!(/^--- .*/, '--- ' + path) - diff.sub!(/^\+\+\+ .*/, '+++ ' + path) - - # Write diff - @diff_lock.synchronize do - File.open('output.diff', 'a') { |io| io.write(diff) } - end - end - end - - def diff_strings(str_a, str_b) - # Create files - Tempfile.open('old') do |old_file| - Tempfile.open('new') do |new_file| - # Write files - old_file.write(str_a) - old_file.flush - new_file.write(str_b) - new_file.flush - - # Diff - cmd = ['diff', '-u', old_file.path, new_file.path] - Open3.popen3(*cmd) do |_stdin, stdout, _stderr| - result = stdout.read - return (result == '' ? nil : result) - end - end - end - rescue Errno::ENOENT - warn 'Failed to run `diff`, so no diff with the previously compiled ' \ - 'content will be available.' - nil - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile_listeners/file_action_printer.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile_listeners/file_action_printer.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile_listeners/file_action_printer.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile_listeners/file_action_printer.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI::Commands::CompileListeners - class FileActionPrinter < Abstract - def initialize(reps:) - @start_times = {} - @acc_durations = {} - - @reps = reps - end - - # @see Listener#start - def start - Nanoc::Int::NotificationCenter.on(:compilation_started, self) do |rep| - @start_times[rep] = Time.now - @acc_durations[rep] ||= 0.0 - end - - Nanoc::Int::NotificationCenter.on(:compilation_suspended, self) do |rep| - @acc_durations[rep] += Time.now - @start_times[rep] - end - - cached_reps = Set.new - Nanoc::Int::NotificationCenter.on(:cached_content_used, self) do |rep| - cached_reps << rep - end - - Nanoc::Int::NotificationCenter.on(:rep_write_enqueued, self) do |rep| - @acc_durations[rep] += Time.now - @start_times[rep] - end - - Nanoc::Int::NotificationCenter.on(:rep_write_started, self) do |rep, _raw_path| - @start_times[rep] = Time.now - end - - Nanoc::Int::NotificationCenter.on(:rep_write_ended, self) do |rep, _binary, path, is_created, is_modified| - @acc_durations[rep] += Time.now - @start_times[rep] - duration = @acc_durations[rep] - - action = - if is_created then :create - elsif is_modified then :update - elsif cached_reps.include?(rep) then :cached - else :identical - end - level = - if is_created then :high - elsif is_modified then :high - else :low - end - - # FIXME: do not depend on working directory - if path.start_with?(Dir.getwd) - path = path[(Dir.getwd.size + 1)..path.size] - end - - log(level, action, path, duration) - end - end - - # @see Listener#stop - def stop - super - - Nanoc::Int::NotificationCenter.remove(:compilation_started, self) - Nanoc::Int::NotificationCenter.remove(:compilation_suspended, self) - Nanoc::Int::NotificationCenter.remove(:rep_write_enqueued, self) - Nanoc::Int::NotificationCenter.remove(:rep_write_started, self) - Nanoc::Int::NotificationCenter.remove(:rep_write_ended, self) - - @reps.reject(&:compiled?).each do |rep| - raw_paths = rep.raw_paths.values.flatten.uniq - raw_paths.each do |raw_path| - log(:low, :skip, raw_path, nil) - end - end - end - - private - - def log(level, action, path, duration) - Nanoc::CLI::Logger.instance.file(level, action, path, duration) - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile_listeners/timing_recorder.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile_listeners/timing_recorder.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile_listeners/timing_recorder.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile_listeners/timing_recorder.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,166 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI::Commands::CompileListeners - class TimingRecorder < Abstract - attr_reader :stages_summary - attr_reader :phases_summary - attr_reader :outdatedness_rules_summary - attr_reader :filters_summary - - # @see Listener#enable_for? - def self.enable_for?(_command_runner, _site) - Nanoc::CLI.verbosity >= 1 - end - - # @param [Enumerable] reps - def initialize(reps:) - @reps = reps - - @stages_summary = DDMetrics::Summary.new - @phases_summary = DDMetrics::Summary.new - @outdatedness_rules_summary = DDMetrics::Summary.new - @filters_summary = DDMetrics::Summary.new - @load_stores_summary = DDMetrics::Summary.new - end - - # @see Listener#start - def start - on(:stage_ran) do |duration, klass| - @stages_summary.observe(duration, name: klass.to_s.sub(/.*::/, '')) - end - - on(:outdatedness_rule_ran) do |duration, klass| - @outdatedness_rules_summary.observe(duration, name: klass.to_s.sub(/.*::/, '')) - end - - filter_stopwatches = {} - - on(:filtering_started) do |rep, _filter_name| - stopwatch_stack = filter_stopwatches.fetch(rep) { filter_stopwatches[rep] = [] } - stopwatch_stack << DDMetrics::Stopwatch.new - stopwatch_stack.last.start - end - - on(:filtering_ended) do |rep, filter_name| - stopwatch = filter_stopwatches.fetch(rep).pop - stopwatch.stop - - @filters_summary.observe(stopwatch.duration, name: filter_name.to_s) - end - - on(:store_loaded) do |duration, klass| - @load_stores_summary.observe(duration, name: klass.to_s) - end - - on(:compilation_suspended) do |rep, _exception| - filter_stopwatches.fetch(rep).each(&:stop) - end - - on(:compilation_started) do |rep| - filter_stopwatches.fetch(rep, []).each(&:start) - end - - phase_stopwatches = {} - - on(:phase_started) do |phase_name, rep| - stopwatches = phase_stopwatches.fetch(rep) { phase_stopwatches[rep] = {} } - stopwatches[phase_name] = DDMetrics::Stopwatch.new.tap(&:start) - end - - on(:phase_ended) do |phase_name, rep| - stopwatch = phase_stopwatches.fetch(rep).fetch(phase_name) - stopwatch.stop - - @phases_summary.observe(stopwatch.duration, name: phase_name) - end - - on(:phase_yielded) do |phase_name, rep| - stopwatch = phase_stopwatches.fetch(rep).fetch(phase_name) - stopwatch.stop - end - - on(:phase_resumed) do |phase_name, rep| - stopwatch = phase_stopwatches.fetch(rep).fetch(phase_name) - stopwatch.start if stopwatch.stopped? - end - - on(:phase_aborted) do |phase_name, rep| - stopwatch = phase_stopwatches.fetch(rep).fetch(phase_name) - stopwatch.stop if stopwatch.running? - - @phases_summary.observe(stopwatch.duration, name: phase_name) - end - end - - # @see Listener#stop - def stop - print_profiling_feedback - super - end - - protected - - def table_for_summary(name, summary) - headers = [name.to_s, 'count', 'min', '.50', '.90', '.95', 'max', 'tot'] - - rows = summary.map do |label, stats| - name = label.fetch(:name) - - count = stats.count - min = stats.min - p50 = stats.quantile(0.50) - p90 = stats.quantile(0.90) - p95 = stats.quantile(0.95) - tot = stats.sum - max = stats.max - - [name, count.to_s] + [min, p50, p90, p95, max, tot].map { |r| "#{format('%4.2f', r)}s" } - end - - [headers] + rows - end - - def table_for_summary_durations(name, summary) - headers = [name.to_s, 'tot'] - - rows = summary.map do |label, stats| - name = label.fetch(:name) - [name, "#{format('%4.2f', stats.sum)}s"] - end - - [headers] + rows - end - - def print_profiling_feedback - print_table_for_summary(:filters, @filters_summary) - print_table_for_summary(:phases, @phases_summary) if Nanoc::CLI.verbosity >= 2 - print_table_for_summary_duration(:stages, @stages_summary) if Nanoc::CLI.verbosity >= 2 - print_table_for_summary(:outdatedness_rules, @outdatedness_rules_summary) if Nanoc::CLI.verbosity >= 2 - print_table_for_summary_duration(:load_stores, @load_stores_summary) if Nanoc::CLI.verbosity >= 2 - print_ddmemoize_metrics if Nanoc::CLI.verbosity >= 2 - end - - def print_table_for_summary(name, summary) - return unless summary.any? - - puts - print_table(table_for_summary(name, summary)) - end - - def print_table_for_summary_duration(name, summary) - return unless summary.any? - - puts - print_table(table_for_summary_durations(name, summary)) - end - - def print_ddmemoize_metrics - puts - DDMemoize.print_metrics - end - - def print_table(rows) - puts DDMetrics::Table.new(rows).to_s - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/compile.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/compile.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -# frozen_string_literal: true - -usage 'compile [options]' -summary 'compile items of this site' -description <<~EOS - Compile all items of the current site. -EOS -no_params - -flag nil, :diff, 'generate diff' -if Nanoc::Feature.enabled?(Nanoc::Feature::LIVE_CMD) - flag :w, :watch, 'watch for changes and recompile when needed' -end - -module Nanoc::CLI::Commands - class Compile < ::Nanoc::CLI::CommandRunner - attr_accessor :listener_classes - - def run - self.class.enter_site_dir - - if options[:watch] - run_repeat - else - run_once - end - end - - def run_repeat - require 'nanoc/live' - Nanoc::Live::LiveRecompiler.new(command_runner: self).run - end - - def run_once - time_before = Time.now - - @site = load_site - - puts 'Compiling site…' - compiler = Nanoc::Int::Compiler.new_for(@site) - listener = Nanoc::CLI::Commands::CompileListeners::Aggregate.new( - command_runner: self, - site: @site, - compiler: compiler, - ) - listener.run_while do - compiler.run_until_end - end - - time_after = Time.now - puts - puts "Site compiled in #{format('%.2f', time_after - time_before)}s." - end - end -end - -runner Nanoc::CLI::Commands::Compile diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/create-site.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/create-site.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/create-site.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/create-site.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,262 +0,0 @@ -# frozen_string_literal: true - -usage 'create-site [options] path' -aliases :create_site, :cs -summary 'create a site' -description 'Create a new site at the given path. The site will use the `filesystem` data source.' -flag nil, :force, 'force creation of new site' -param :path - -module Nanoc::CLI::Commands - class CreateSite < ::Nanoc::CLI::CommandRunner - class << self - protected - - # Converts the given array to YAML format - def array_to_yaml(array) - '[ ' + array.map { |s| "'" + s + "'" }.join(', ') + ' ]' - end - end - - DEFAULT_CONFIG = <<~EOS unless defined? DEFAULT_CONFIG - # A list of file extensions that Nanoc will consider to be textual rather than - # binary. If an item with an extension not in this list is found, the file - # will be considered as binary. - text_extensions: #{array_to_yaml(Nanoc::Int::Configuration::DEFAULT_CONFIG[:text_extensions])} - - prune: - auto_prune: true - - data_sources: - - type: filesystem - encoding: utf-8 - EOS - - DEFAULT_RULES = <<~EOS unless defined? DEFAULT_RULES - #!/usr/bin/env ruby - - compile '/index.html' do - layout '/default.*' - write '/index.html' - end - - compile '/**/*.html' do - layout '/default.*' - write item.identifier.without_ext + '/index.html' - end - - # This is an example rule that matches Markdown (.md) files, and filters them - # using the :kramdown filter. It is commented out by default, because kramdown - # is not bundled with Nanoc or Ruby. - # - #compile '/**/*.md' do - # filter :kramdown - # layout '/default.*' - # write item.identifier.without_ext + '/index.html' - #end - - compile '/**/*' do - write item.identifier.to_s - end - - layout '/**/*', :erb - EOS - - DEFAULT_ITEM = <<~EOS unless defined? DEFAULT_ITEM - --- - title: Home - --- - -

A Brand New Nanoc Site

- -

You’ve just created a new Nanoc site. The page you are looking at right now is the home page for your site. To get started, consider replacing this default homepage with your own customized homepage. Some pointers on how to do so:

- -
    -
  • Change this page’s content by editing the “index.html” file in the “content” directory. This is the actual page content, and therefore doesn’t include the header, sidebar or style information (those are part of the layout).

  • -
  • Change the layout, which is the “default.html” file in the “layouts” directory, and create something unique (and hopefully less bland).

  • -
- -

If you need any help with customizing your Nanoc web site, be sure to check out the documentation (see sidebar), and be sure to subscribe to the discussion group (also see sidebar). Enjoy!

- EOS - - DEFAULT_STYLESHEET = <<~EOS unless defined? DEFAULT_STYLESHEET - * { - margin: 0; - padding: 0; - - font-family: Georgia, Palatino, serif; - } - - body { - background: #fff; - } - - a { - text-decoration: none; - } - - a:link, - a:visited { - color: #f30; - } - - a:hover { - color: #f90; - } - - #main { - position: absolute; - - top: 40px; - left: 280px; - - width: 500px; - } - - #main h1 { - font-size: 40px; - font-weight: normal; - - line-height: 40px; - - letter-spacing: -1px; - } - - #main p { - margin: 20px 0; - - font-size: 15px; - - line-height: 20px; - } - - #main ul, #main ol { - margin: 20px; - } - - #main li { - font-size: 15px; - - line-height: 20px; - } - - #main ul li { - list-style-type: square; - } - - #sidebar { - position: absolute; - - top: 40px; - left: 20px; - width: 200px; - - padding: 20px 20px 0 0; - - border-right: 1px solid #ccc; - - text-align: right; - } - - #sidebar h2 { - text-transform: uppercase; - - font-size: 13px; - - color: #333; - - letter-spacing: 1px; - - line-height: 20px; - } - - #sidebar ul { - list-style-type: none; - - margin: 20px 0; - } - - #sidebar li { - font-size: 14px; - - line-height: 20px; - } - EOS - - DEFAULT_LAYOUT = <<~EOS unless defined? DEFAULT_LAYOUT - - - - - A Brand New Nanoc Site - <%= @item[:title] %> - - - - - - -
- <%= yield %> -
- - - - EOS - - def run - path = arguments[:path] - - # Check whether site exists - if File.exist?(path) && (!File.directory?(path) || !(Dir.entries(path) - %w[. ..]).empty?) && !options[:force] - raise( - Nanoc::Int::Errors::GenericTrivial, - "The site was not created because '#{path}' already exists. " \ - 'Re-run the command using --force to create the site anyway.', - ) - end - - # Setup notifications - Nanoc::Int::NotificationCenter.on(:file_created) do |file_path| - Nanoc::CLI::Logger.instance.file(:high, :create, file_path) - end - - # Build entire site - FileUtils.mkdir_p(path) - FileUtils.cd(File.join(path)) do - FileUtils.mkdir_p('content') - FileUtils.mkdir_p('layouts') - FileUtils.mkdir_p('lib') - FileUtils.mkdir_p('output') - - write('nanoc.yaml', DEFAULT_CONFIG) - write('Rules', DEFAULT_RULES) - write('content/index.html', DEFAULT_ITEM) - write('content/stylesheet.css', DEFAULT_STYLESHEET) - write('layouts/default.html', DEFAULT_LAYOUT) - end - - puts "Created a blank nanoc site at '#{path}'. Enjoy!" - end - - private - - def write(filename, content) - File.write(filename, content) - Nanoc::Int::NotificationCenter.post(:file_created, filename) - end - end -end - -runner Nanoc::CLI::Commands::CreateSite diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/deploy.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/deploy.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/deploy.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/deploy.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -# frozen_string_literal: true - -usage 'deploy [target] [options]' -summary 'deploy the compiled site' -description " -Deploys the compiled site. The compiled site contents in the output directory will be uploaded to the destination, which is specified using the `--target` option. -" - -option :t, :target, 'specify the location to deploy to (default: `default`)', argument: :required -flag :C, :'no-check', 'do not run the issue checks marked for deployment' -flag :L, :list, 'list available locations to deploy to' -flag :D, :'list-deployers', 'list available deployers' -option :n, :'dry-run', 'show what would be deployed' - -module Nanoc::CLI::Commands - class Deploy < ::Nanoc::CLI::CommandRunner - def run - @site = load_site - Nanoc::Int::Compiler.new_for(@site).run_until_preprocessed - - if options[:'list-deployers'] - list_deployers - elsif options[:list] - list_deploy_configs - else - deploy - end - end - - private - - def list_deployers - deployers = Nanoc::Deploying::Deployer.all - deployer_names = deployers.map(&:identifier).sort - puts 'Available deployers:' - deployer_names.each do |name| - puts " #{name}" - end - end - - def list_deploy_configs - if deploy_configs.empty? - puts 'No deployment configurations.' - else - puts 'Available deployment configurations:' - deploy_configs.each_key do |name| - puts " #{name}" - end - end - end - - def deploy - deployer = deployer_for(deploy_config) - - checks_successful = options[:'no-check'] ? true : check - return unless checks_successful - - deployer.run - end - - def deploy_config - if deploy_configs.empty? - raise Nanoc::Int::Errors::GenericTrivial, 'The site has no deployment configurations.' - end - - if arguments.length > 1 - raise Nanoc::Int::Errors::GenericTrivial, "usage: #{command.usage}" - end - - target_from_arguments = arguments[0] - target_from_options = options.fetch(:target, nil) - if target_from_arguments && target_from_options - raise Nanoc::Int::Errors::GenericTrivial, 'Only one deployment target can be specified on the command line.' - end - - target = target_from_arguments || target_from_options || :default - deploy_configs.fetch(target.to_sym) do - raise Nanoc::Int::Errors::GenericTrivial, "The site has no deployment configuration named `#{target}`." - end - end - - def deployer_for(config) - deployer_class_for_config(config).new( - @site.config.output_dir, - config, - dry_run: options[:'dry-run'], - ) - end - - def check - runner = Nanoc::Checking::Runner.new(@site) - if runner.any_enabled_checks? - puts 'Running issue checks…' - is_success = runner.run_for_deploy - if is_success - puts 'No issues found. Deploying!' - else - puts 'Issues found, deploy aborted.' - end - is_success - else - true - end - end - - def deploy_configs - @site.config.fetch(:deploy, {}) - end - - def deployer_class_for_config(config) - name = config.fetch(:kind) do - $stderr.puts 'Warning: The specified deploy target does not have a kind attribute. Assuming rsync.' - 'rsync' - end - - deployer_class = Nanoc::Deploying::Deployer.named(name.to_sym) - if deployer_class.nil? - names = Nanoc::Deploying::Deployer.all.map(&:identifier) - raise Nanoc::Int::Errors::GenericTrivial, "The specified deploy target has an unrecognised kind “#{name}” (expected one of #{names.join(', ')})." - end - deployer_class - end - end -end - -runner Nanoc::CLI::Commands::Deploy diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/nanoc.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/nanoc.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/nanoc.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/nanoc.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -usage 'nanoc command [options] [arguments]' -summary 'Nanoc, a static site compiler written in Ruby' -default_subcommand 'compile' - -opt :l, :color, 'enable color' do - $stdout.remove_stream_cleaner(Nanoc::CLI::StreamCleaners::ANSIColors) - $stderr.remove_stream_cleaner(Nanoc::CLI::StreamCleaners::ANSIColors) -end - -opt :d, :debug, 'enable debugging' do - Nanoc::CLI.debug = true -end - -opt :e, :env, 'set environment', argument: :required do |value| - ENV.store('NANOC_ENV', value) -end - -opt :h, :help, 'show the help message and quit' do |_value, cmd| - puts cmd.help - exit 0 -end - -opt :C, :'no-color', 'disable color' do - $stdout.add_stream_cleaner(Nanoc::CLI::StreamCleaners::ANSIColors) - $stderr.add_stream_cleaner(Nanoc::CLI::StreamCleaners::ANSIColors) -end - -opt :V, :verbose, 'make output more detailed', multiple: true do |val| - Nanoc::CLI::Logger.instance.level = :low - Nanoc::CLI.verbosity = val.size -end - -opt :v, :version, 'show version information and quit' do - puts Nanoc.version_information - exit 0 -end - -opt :w, :warn, 'enable warnings' do - $-w = true -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/prune.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/prune.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/prune.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/prune.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -# frozen_string_literal: true - -usage 'prune' -summary 'remove files not managed by Nanoc from the output directory' -description <<~EOS - Find all files in the output directory that do not correspond to an item - managed by Nanoc and remove them. Since this is a hazardous operation, an - additional `--yes` flag is needed as confirmation. - - Also see the `auto_prune` configuration option in `nanoc.yaml` (`config.yaml` - for older Nanoc sites), which will automatically prune after compilation. -EOS -no_params - -flag :y, :yes, 'confirm deletion' -flag :n, :'dry-run', 'print files to be deleted instead of actually deleting them' - -module Nanoc::CLI::Commands - class Prune < ::Nanoc::CLI::CommandRunner - def run - @site = load_site - res = Nanoc::Int::Compiler.new_for(@site).run_until_reps_built - reps = res.fetch(:reps) - - if options.key?(:yes) - Nanoc::Pruner.new(@site.config, reps, exclude: prune_config_exclude).run - elsif options.key?(:'dry-run') - Nanoc::Pruner.new(@site.config, reps, exclude: prune_config_exclude, dry_run: true).run - else - $stderr.puts 'WARNING: Since the prune command is a destructive command, it requires an additional --yes flag in order to work.' - $stderr.puts - $stderr.puts 'Please ensure that the output directory does not contain any files (such as images or stylesheets) that are necessary but are not managed by Nanoc. If you want to get a list of all files that would be removed, pass --dry-run.' - exit 1 - end - end - - protected - - def prune_config - @site.config[:prune] || {} - end - - def prune_config_exclude - prune_config[:exclude] || {} - end - end -end - -runner Nanoc::CLI::Commands::Prune diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/shell.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/shell.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/shell.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/shell.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -# frozen_string_literal: true - -usage 'shell' -summary 'open a shell on the Nanoc environment' -aliases 'console', 'sh' -description " -Open an IRB shell on a context that contains @items, @layouts, and @config. -" -flag :p, :preprocess, 'run preprocessor' -no_params - -module Nanoc::CLI::Commands - class Shell < ::Nanoc::CLI::CommandRunner - def run - require 'pry' - - # Needed to make pry behave properly sometimes -- see nanoc/nanoc#1309 - Signal.trap('SIGINT') { raise Interrupt } - - @site = load_site - Nanoc::Int::Compiler.new_for(@site).run_until_preprocessed if options[:preprocess] - - Nanoc::Int::Context.new(env).pry - end - - def env - self.class.env_for_site(@site) - end - - def self.reps_for(site) - Nanoc::Int::ItemRepRepo.new.tap do |reps| - action_provider = Nanoc::Int::ActionProvider.named(site.config.action_provider).for(site) - builder = Nanoc::Int::ItemRepBuilder.new(site, action_provider, reps) - builder.run - end - end - - def self.view_context_for(site) - Nanoc::ViewContextForShell.new( - items: site.items, - reps: reps_for(site), - ) - end - - def self.env_for_site(site) - view_context = view_context_for(site) - - { - items: Nanoc::ItemCollectionWithRepsView.new(site.items, view_context), - layouts: Nanoc::LayoutCollectionView.new(site.layouts, view_context), - config: Nanoc::ConfigView.new(site.config, view_context), - } - end - end -end - -runner Nanoc::CLI::Commands::Shell diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/show-data.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/show-data.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/show-data.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/show-data.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,185 +0,0 @@ -# frozen_string_literal: true - -usage 'show-data' -aliases :debug -summary 'show data in this site' -description <<~EOS - Show information about all items, item representations and layouts in the - current site, along with dependency information. -EOS -no_params - -module Nanoc::CLI::Commands - class ShowData < ::Nanoc::CLI::CommandRunner - def run - site = load_site - res = Nanoc::Int::Compiler.new_for(site).run_until_precompiled - - items = site.items - layouts = site.layouts - reps = res.fetch(:reps) - dependency_store = res.fetch(:dependency_store) - outdatedness_checker = res.fetch(:outdatedness_checker) - - # Print data - print_item_dependencies(items, dependency_store) - print_item_rep_paths(items, reps) - print_item_rep_outdatedness(items, outdatedness_checker, reps) - print_layouts(layouts, outdatedness_checker) - end - - protected - - def sorted_with_prev(objects) - prev = nil - objects.sort_by(&:identifier).each do |object| - yield(object, prev) - prev = object - end - end - - def sorted_reps_with_prev(items, reps) - prev = nil - items.sort_by(&:identifier).each do |item| - reps[item].sort_by { |r| r.name.to_s }.each do |rep| - yield(rep, prev) - prev = rep - end - end - end - - def print_header(title) - header = '=' * 78 - header[3..(title.length + 5)] = " #{title} " - - puts - puts header - puts - end - - def print_item_dependencies(items, dependency_store) - print_header('Item dependencies') - - puts 'Legend:' - puts ' r = dependency on raw content' - puts ' a = dependency on attributes' - puts ' c = dependency on compiled content' - puts ' p = dependency on the path' - puts - - sorter = - lambda do |dep| - case dep - when Nanoc::Int::Document - dep.from.identifier.to_s - else - '' - end - end - - sorted_with_prev(items) do |item, prev| - puts if prev - puts "item #{item.identifier} depends on:" - dependencies = - dependency_store - .dependencies_causing_outdatedness_of(item) - .sort_by(&sorter) - dependencies.each do |dep| - pred = dep.from - - type = - case pred - when Nanoc::Int::Layout - 'layout' - when Nanoc::Int::Item - 'item' - when Nanoc::Int::Configuration - 'config' - when Nanoc::Int::ItemCollection - 'items' - when Nanoc::Int::LayoutCollection - 'layouts' - else - raise Nanoc::Int::Errors::InternalInconsistency, "unexpected pred type #{pred}" - end - - pred_identifier = - case pred - when Nanoc::Int::Document - pred.identifier.to_s - when Nanoc::Int::Configuration - nil - when Nanoc::Int::IdentifiableCollection - case dep.props.raw_content - when true - 'matching any' - else - "matching any of #{dep.props.raw_content.sort.join(', ')}" - end - else - raise Nanoc::Int::Errors::InternalInconsistency, "unexpected pred type #{pred}" - end - - if pred - puts " [ #{format '%6s', type} ] (#{dep.props}) #{pred_identifier}" - else - puts ' ( removed item )' - end - end - puts ' (nothing)' if dependencies.empty? - end - end - - def print_item_rep_paths(items, reps) - print_header('Item representation paths') - - sorted_reps_with_prev(items, reps) do |rep, prev| - puts if prev - puts "item #{rep.item.identifier}, rep #{rep.name}:" - if rep.raw_paths.empty? - puts ' (not written)' - end - length = rep.raw_paths.keys.map { |s| s.to_s.length }.max - rep.raw_paths.each do |snapshot_name, raw_paths| - raw_paths.each do |raw_path| - puts format(" [ %-#{length}s ] %s", snapshot_name, raw_path) - end - end - end - end - - def print_item_rep_outdatedness(items, outdatedness_checker, reps) - print_header('Item representation outdatedness') - - sorted_reps_with_prev(items, reps) do |rep, prev| - puts if prev - puts "item #{rep.item.identifier}, rep #{rep.name}:" - print_outdatedness_reasons_for(rep, outdatedness_checker) - end - end - - def print_layouts(layouts, outdatedness_checker) - print_header('Layouts') - - sorted_with_prev(layouts) do |layout, prev| - puts if prev - puts "layout #{layout.identifier}:" - print_outdatedness_reasons_for(layout, outdatedness_checker) - end - end - - def print_outdatedness_reasons_for(obj, outdatedness_checker) - reasons = outdatedness_checker.outdatedness_reasons_for(obj) - if reasons.any? - puts ' is outdated:' - reasons.each do |reason| - puts " - #{reason.message}" - end - else - puts ' is not outdated' - end - end - end -end - -runner Nanoc::CLI::Commands::ShowData diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/show-plugins.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/show-plugins.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/show-plugins.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/show-plugins.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -summary 'show all available plugins' -aliases :info -usage 'show-plugins [options]' -description <<~EOS - Show a list of available plugins, including filters and data sources. - If the current directory contains a Nanoc web site, the plugins defined in this site will be shown as well. -EOS -no_params - -module Nanoc::CLI::Commands - class ShowPlugins < ::Nanoc::CLI::CommandRunner - def run - # Get list of plugins (before and after) - plugins_before = PLUGIN_CLASSES.keys.each_with_object({}) { |c, acc| acc[c] = c.all } - site = load_site - site&.code_snippets - plugins_after = PLUGIN_CLASSES.keys.each_with_object({}) { |c, acc| acc[c] = c.all } - - # Divide list of plugins into builtin and custom - plugins_builtin = plugins_before - plugins_custom = plugins_after.each_with_object({}) do |(superclass, klasses), acc| - acc[superclass] = klasses - plugins_before[superclass] - end - - # Find max identifiers length - all_identifiers = plugins_after.values.flatten.map(&:identifiers) - max_identifiers_length = all_identifiers.map(&:to_s).map(&:size).max - - PLUGIN_CLASS_ORDER.each do |superclass| - plugins_with_this_superclass = { - builtin: plugins_builtin.fetch(superclass, []), - custom: plugins_custom.fetch(superclass, []), - } - - # Print kind - kind = name_for_plugin_class(superclass) - puts "#{kind}:" - puts - - # Print plugins organised by subtype - %i[builtin custom].each do |type| - # Find relevant plugins - relevant_plugins = plugins_with_this_superclass[type] - - # Print type - puts " #{type}:" - if relevant_plugins.empty? - puts ' (none)' - next - end - - # Print plugins - relevant_plugins.sort_by { |k| k.identifiers.join(', ') }.each do |plugin| - # Display - puts format( - " %-#{max_identifiers_length}s (%s)", - plugin.identifiers.join(', '), - plugin.to_s.sub(/^::/, ''), - ) - end - end - - puts - end - end - - private - - PLUGIN_CLASS_ORDER = [ - Nanoc::Filter, - Nanoc::DataSource, - Nanoc::Deploying::Deployer, - ].freeze - - PLUGIN_CLASSES = { - Nanoc::Filter => 'Filters', - Nanoc::DataSource => 'Data Sources', - Nanoc::Deploying::Deployer => 'Deployers', - }.freeze - - def name_for_plugin_class(klass) - PLUGIN_CLASSES[klass] - end - end -end - -runner Nanoc::CLI::Commands::ShowPlugins diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/show-rules.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/show-rules.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/show-rules.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/show-rules.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -# frozen_string_literal: true - -usage 'show-rules [thing]' -aliases :explain -summary 'describe the rules for each item' -description " -Prints the rules used for all items and layouts in the current site. -" -no_params - -module Nanoc::CLI::Commands - class ShowRules < ::Nanoc::CLI::CommandRunner - def run - site = load_site - - res = Nanoc::Int::Compiler.new_for(site).run_until_reps_built - reps = res.fetch(:reps) - - action_provider = Nanoc::Int::ActionProvider.named(site.config.action_provider).for(site) - rules = action_provider.rules_collection - - items = site.items.sort_by(&:identifier) - layouts = site.layouts.sort_by(&:identifier) - - items.each { |e| explain_item(e, rules: rules, reps: reps) } - layouts.each { |e| explain_layout(e, rules: rules) } - end - - def explain_item(item, rules:, reps:) - puts(fmt_heading("Item #{item.identifier}") + ':') - - reps[item].each do |rep| - rule = rules.compilation_rule_for(rep) - puts " Rep #{rep.name}: #{rule ? rule.pattern : '(none)'}" - end - - puts - end - - def explain_layout(layout, rules:) - puts(fmt_heading("Layout #{layout.identifier}") + ':') - - found = false - rules.layout_filter_mapping.each_key do |pattern| - if pattern.match?(layout.identifier) - puts " #{pattern}" - found = true - break - end - end - unless found - puts ' (none)' - end - - puts - end - - def fmt_heading(str) - Nanoc::CLI::ANSIStringColorizer.c(str, :bold, :yellow) - end - end -end - -runner Nanoc::CLI::Commands::ShowRules diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/view.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/view.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/commands/view.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/commands/view.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -# frozen_string_literal: true - -usage 'view [options]' -summary 'start the web server that serves static files' -description <<~EOS - Start the static web server. Unless specified, the web server will run on port - 3000 and listen on all IP addresses. Running this static web server requires - `adsf` (not `asdf`!). -EOS - -required :H, :handler, 'specify the handler to use (webrick/mongrel/...)' -required :o, :host, 'specify the host to listen on (default: 127.0.0.1)', default: '127.0.0.1' -required :p, :port, 'specify the port to listen on (default: 3000)', transform: Nanoc::CLI::Transform::Port, default: 3000 -flag :L, :'live-reload', 'reload on changes' -no_params - -module Nanoc::CLI::Commands - class View < ::Nanoc::CLI::CommandRunner - DEFAULT_HANDLER_NAME = :thin - - def run - load_adsf - - config = Nanoc::Int::ConfigLoader.new.new_from_cwd - - # Create output dir so that viewer/watcher doesn’t explode. - FileUtils.mkdir_p(config.output_dir) - - server = - Adsf::Server.new( - root: File.absolute_path(config.output_dir), - live: options[:'live-reload'], - index_filenames: config[:index_filenames], - host: options.fetch(:host), - port: options.fetch(:port), - handler: options[:handler], - ) - - server.run - end - - protected - - def load_adsf - # Load adsf - begin - require 'adsf' - return - rescue LoadError - $stderr.puts "Could not find the required 'adsf' gem, " \ - 'which is necessary for the view command.' - end - - # Check asdf - begin - require 'asdf' - $stderr.puts "You appear to have 'asdf' installed, " \ - "but not 'adsf'. Please install 'adsf' (check the spelling)!" - rescue LoadError - end - - # Done - exit 1 - end - end -end - -runner Nanoc::CLI::Commands::View diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/error_handler.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/error_handler.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/error_handler.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/error_handler.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,365 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI - # Catches errors and prints nice diagnostic messages, then exits. - # - # @api private - class ErrorHandler - # Enables error handling in the given block. - # - # @return [void] - def self.handle_while(exit_on_error: true) - if @disabled - yield - else - new.handle_while(exit_on_error: exit_on_error) { yield } - end - end - - # Disables error handling. This is used by the test cases to prevent error - # from being handled by the CLI while tests are running. - def self.disable - @disabled = true - end - - # Re-enables error handling after it was disabled. This is used by the test - # cases to prevent error from being handled by the CLI while tests are - # running. - def self.enable - @disabled = false - end - - # Enables error handling in the given block. This method should not be - # called directly; use {Nanoc::CLI::ErrorHandler.handle_while} instead. - # - # @return [void] - def handle_while(exit_on_error:) - # Set exit handler - %w[INT TERM].each do |signal| - Signal.trap(signal) do - puts - exit!(0) - end - end - - # Set stack trace dump handler - if !defined?(RUBY_ENGINE) || RUBY_ENGINE != 'jruby' - begin - Signal.trap('USR1') do - puts 'Caught USR1; dumping a stack trace' - puts caller.map { |i| " #{i}" }.join("\n") - end - rescue ArgumentError - end - end - - # Run - yield - rescue Interrupt - exit(1) - rescue StandardError, ScriptError => e - handle_error(e, exit_on_error: exit_on_error) - end - - def handle_error(error, exit_on_error:) - if trivial?(error) - $stderr.puts - $stderr.puts "Error: #{error.message}" - resolution = resolution_for(error) - if resolution - $stderr.puts - $stderr.puts resolution - end - else - print_error(error) - end - exit(1) if exit_on_error - end - - # Prints the given error to stderr. Includes message, possible resolution - # (see {#resolution_for}), compilation stack, backtrace, etc. - # - # @param [Error] error The error that should be described - # - # @return [void] - def self.print_error(error) - new.print_error(error) - end - - # Prints the given error to stderr. Includes message, possible resolution - # (see {#resolution_for}), compilation stack, backtrace, etc. - # - # @param [Error] error The error that should be described - # - # @return [void] - def print_error(error) - write_compact_error(error, $stderr) - - File.open('crash.log', 'w') do |io| - cio = Nanoc::CLI.wrap_in_cleaning_stream(io) - cio.add_stream_cleaner(::Nanoc::CLI::StreamCleaners::ANSIColors) - write_verbose_error(error, cio) - end - end - - # Writes a compact representation of the error, suitable for a terminal, on - # the given stream (probably stderr). - # - # @param [Error] error The error that should be described - # - # @param [IO] stream The stream to write the description too - # - # @return [void] - def write_compact_error(error, stream) - stream.puts - stream.puts 'Captain! We’ve been hit!' - - if forwards_stack_trace? - write_stack_trace(stream, error) - write_error_message(stream, error) - write_item_rep(stream, error) - else - write_error_message(stream, error) - write_item_rep(stream, error) - write_stack_trace(stream, error) - end - - stream.puts - stream.puts 'A detailed crash log has been written to ./crash.log.' - end - - # Writes a verbose representation of the error on the given stream. - # - # @param [Error] error The error that should be described - # - # @param [IO] stream The stream to write the description too - # - # @return [void] - def write_verbose_error(error, stream) - stream.puts "Crashlog created at #{Time.now}" - - write_error_message(stream, error, verbose: true) - write_item_rep(stream, error, verbose: true) - write_stack_trace(stream, error, verbose: true) - write_version_information(stream, verbose: true) - write_system_information(stream, verbose: true) - write_installed_gems(stream, verbose: true) - write_gemfile_lock(stream, verbose: true) - write_load_paths(stream, verbose: true) - end - - # @api private - def forwards_stack_trace? - ruby_version.start_with?('2.5') - end - - # @api private - def trivial?(error) - case error - when Nanoc::Int::Errors::GenericTrivial, Errno::EADDRINUSE - true - when LoadError - GEM_NAMES.key?(gem_name_from_load_error(error)) - else - false - end - end - - protected - - # @return [Hash] A hash containing the gem names as keys and gem versions as value - def gems_and_versions - gems = {} - Gem::Specification.find_all.sort_by { |s| [s.name, s.version] }.each do |spec| - gems[spec.name] ||= [] - gems[spec.name] << spec.version.to_s - end - gems - end - - # A hash that contains the name of the gem for a given required file. If a - # `#require` fails, the gem name is looked up in this hash. - GEM_NAMES = { - 'adsf' => 'adsf', - 'asciidoctor' => 'asciidoctor', - 'bluecloth' => 'bluecloth', - 'builder' => 'builder', - 'coderay' => 'coderay', - 'coffee-script' => 'coffee-script', - 'cri' => 'cri', - 'erubi' => 'erubi', - 'erubis' => 'erubis', - 'escape' => 'escape', - 'fog' => 'fog', - 'haml' => 'haml', - 'handlebars' => 'hbs', - 'json' => 'json', - 'kramdown' => 'kramdown', - 'less' => 'less', - 'listen' => 'listen', - 'markaby' => 'markaby', - 'maruku' => 'maruku', - 'mime/types' => 'mime-types', - 'mustache' => 'mustache', - 'nanoc/live' => 'nanoc-live', - 'nokogiri' => 'nokogiri', - 'nokogumbo' => 'nokogumbo', - 'pandoc-ruby' => 'pandoc-ruby', - 'pry' => 'pry', - 'rack' => 'rack', - 'rack/cache' => 'rack-cache', - 'rainpress' => 'rainpress', - 'rdiscount' => 'rdiscount', - 'redcarpet' => 'redcarpet', - 'redcloth' => 'RedCloth', - 'rubypants' => 'rubypants', - 'sass' => 'sass', - 'slim' => 'slim', - 'typogruby' => 'typogruby', - 'uglifier' => 'uglifier', - 'w3c_validators' => 'w3c_validators', - 'yuicompressor' => 'yuicompressor', - }.freeze - - # Attempts to find a resolution for the given error, or nil if no - # resolution can be automatically obtained. - # - # @param [Error] error The error to find a resolution for - # - # @return [String] The resolution for the given error - def resolution_for(error) - error = unwrap_error(error) - - case error - when LoadError - gem_name = gem_name_from_load_error(error) - - if gem_name - if using_bundler? - <<~RES - 1. Add `gem '#{gem_name}'` to your Gemfile - 2. Run `bundle install` - 3. Re-run this command - RES - else - "Install the '#{gem_name}' gem using `gem install #{gem_name}`." - end - end - when RuntimeError - if /^can't modify frozen/.match?(error.message) - 'You attempted to modify immutable data. Some data cannot ' \ - 'be modified once compilation has started. Such data includes ' \ - 'content and attributes of items and layouts, and filter arguments.' - end - when Errno::EADDRINUSE - 'There already is a server running. Either shut down that one, or ' \ - 'specify a different port to run this server on.' - end - end - - def gem_name_from_load_error(error) - matches = error.message.match(/(no such file to load|cannot load such file) -- ([^\s]+)/) - return nil if matches.nil? - - GEM_NAMES[matches[2]] - end - - def using_bundler? - defined?(Bundler) && Bundler::SharedHelpers.in_bundle? - end - - def ruby_version - RUBY_VERSION - end - - def write_section_header(stream, title, verbose: false) - stream.puts - - if verbose - stream.puts '===== ' + title.upcase + ':' - stream.puts - end - end - - def write_error_message(stream, error, verbose: false) - write_section_header(stream, 'Message', verbose: verbose) - - error = unwrap_error(error) - - message = "#{error.class}: #{message_for_error(error)}" - unless verbose - message = "\e[1m\e[31m" + message + "\e[0m" - end - stream.puts message - resolution = resolution_for(error) - stream.puts resolution.to_s if resolution - end - - def message_for_error(error) - case error - when JsonSchema::AggregateError - "\n" + error.errors.map { |e| " * #{e.pointer}: #{e.message}" }.join("\n") - else - error.message - end - end - - def write_item_rep(stream, error, verbose: false) - return unless error.is_a?(Nanoc::Int::Errors::CompilationError) - - write_section_header(stream, 'Item being compiled', verbose: verbose) - - item_rep = error.item_rep - stream.puts "Current item: #{item_rep.item.identifier} (#{item_rep.name.inspect} representation)" - end - - def write_stack_trace(stream, error, verbose: false) - write_section_header(stream, 'Stack trace', verbose: verbose) - - writer = StackTraceWriter.new(stream, forwards: forwards_stack_trace?) - writer.write(unwrap_error(error), verbose: verbose) - end - - def write_version_information(stream, verbose: false) - write_section_header(stream, 'Version information', verbose: verbose) - stream.puts Nanoc.version_information - end - - def write_system_information(stream, verbose: false) - uname = `uname -a` - write_section_header(stream, 'System information', verbose: verbose) - stream.puts uname - rescue Errno::ENOENT - end - - def write_installed_gems(stream, verbose: false) - write_section_header(stream, 'Installed gems', verbose: verbose) - gems_and_versions.each do |g| - stream.puts " #{g.first} #{g.last.join(', ')}" - end - end - - def write_gemfile_lock(stream, verbose: false) - if File.exist?('Gemfile.lock') - write_section_header(stream, 'Gemfile.lock', verbose: verbose) - stream.puts File.read('Gemfile.lock') - end - end - - def write_load_paths(stream, verbose: false) - write_section_header(stream, 'Load paths', verbose: verbose) - $LOAD_PATH.each_with_index do |i, index| - stream.puts " #{index}. #{i}" - end - end - - def unwrap_error(e) - case e - when Nanoc::Int::Errors::CompilationError - e.unwrap - else - e - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/logger.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/logger.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/logger.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/logger.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI - # Nanoc::CLI::Logger is a singleton class responsible for generating - # feedback in the terminal. - # - # @api private - class Logger - # Maps actions (`:create`, `:update`, `:identical`, `:cached`, `:skip` and `:delete`) - # onto their ANSI color codes. - ACTION_COLORS = { - create: "\e[32m", # green - update: "\e[33m", # yellow - identical: '', # (nothing) - cached: '', # (nothing) - skip: '', # (nothing) - delete: "\e[31m" # red - }.freeze - - include Singleton - - # Returns the log level, which can be :high, :low or :off (which will log - # all messages, only high-priority messages, or no messages at all, - # respectively). - # - # @return [Symbol] The log level - attr_accessor :level - - def initialize - @level = :high - @mutex = Mutex.new - end - - # Logs a file-related action. - # - # @param [:high, :low] level The importance of this action - # - # @param [:create, :update, :identical, :cached, :skip, :delete] action The kind of file action - # - # @param [String] name The name of the file the action was performed on - # - # @return [void] - def file(level, action, name, duration = nil) - log( - level, - format( - '%s%12s%s %s%s', - ACTION_COLORS[action.to_sym], - action, - "\e[0m", - duration.nil? ? '' : format('[%2.2fs] ', duration), - name, - ), - ) - end - - # Logs a message. - # - # @param [:high, :low] level The importance of this message - # - # @param [String] message The message to be logged - # - # @param [#puts] io The stream to which the message should be written - # - # @return [void] - def log(level, message, io = $stdout) - return if @level == :off - return if @level != :low && @level != level - - @mutex.synchronize do - io.puts(message) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/stack_trace_writer.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/stack_trace_writer.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/stack_trace_writer.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/stack_trace_writer.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI - # @api private - class StackTraceWriter - def initialize(stream, forwards:) - @stream = stream - @forwards = forwards - end - - def write(error, verbose:) - if @forwards - write_forwards(error, verbose: verbose) - else - write_backwards(error, verbose: verbose) - end - end - - private - - def write_backwards(error, verbose:) - count = verbose ? -1 : 10 - - error.backtrace[0...count].each_with_index do |item, index| - @stream.puts " #{index}. #{item}" - end - - if !verbose && error.backtrace.size > count - @stream.puts " ... #{error.backtrace.size - count} lines omitted (see crash.log for details)" - end - end - - def write_forwards(error, verbose:) - count = 10 - backtrace = verbose ? error.backtrace : error.backtrace.take(count) - - if !verbose && error.backtrace.size > count - @stream.puts " ... #{error.backtrace.size - count} lines omitted (see crash.log for details)" - end - - backtrace.each_with_index.to_a.reverse_each do |(item, index)| - if index.zero? - @stream.puts " #{item}" - else - @stream.puts " #{index}. from #{item}" - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/stream_cleaners/abstract.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/stream_cleaners/abstract.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/stream_cleaners/abstract.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/stream_cleaners/abstract.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI::StreamCleaners - # Superclass for all stream cleaners. Stream cleaners have a single method, - # {#clean}, that takes a string and returns a cleaned string. Stream cleaners - # can have state, so they can act as a FSM. - # - # @abstract Subclasses must implement {#clean} - # - # @api private - class Abstract - # Returns a cleaned version of the given string. - # - # @param [String] str The string to clean - # - # @return [String] The cleaned string - def clean(str) # rubocop:disable Lint/UnusedMethodArgument - raise NotImplementedError, 'Subclasses of Nanoc::CLI::StreamCleaners::Abstract must implement #clean' - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/stream_cleaners/ansi_colors.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/stream_cleaners/ansi_colors.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/stream_cleaners/ansi_colors.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/stream_cleaners/ansi_colors.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI::StreamCleaners - # Removes ANSI color escape sequences. - # - # @api private - class ANSIColors < Abstract - # @see Nanoc::CLI::StreamCleaners::Abstract#clean - def clean(str) - str.gsub(/\e\[.+?m/, '') - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/stream_cleaners/utf8.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/stream_cleaners/utf8.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/stream_cleaners/utf8.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/stream_cleaners/utf8.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI::StreamCleaners - # Simplifies output by replacing UTF-8 characters with their ASCII decompositions. - # - # @api private - class UTF8 < Abstract - # @see Nanoc::CLI::StreamCleaners::Abstract#clean - def clean(str) - # FIXME: this decomposition is not generally usable - str - .unicode_normalize(:nfkd) - .tr('─┼“”‘’', '-+""\'\'') - .gsub('©', '(c)') - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/stream_cleaners.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/stream_cleaners.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/stream_cleaners.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/stream_cleaners.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -# @api private -module Nanoc::CLI::StreamCleaners -end - -require_relative 'stream_cleaners/abstract' - -require_relative 'stream_cleaners/ansi_colors' -require_relative 'stream_cleaners/utf8' diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli/transform.rb nanoc-4.11.14/nanoc/lib/nanoc/cli/transform.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli/transform.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli/transform.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::CLI - # @api private - module Transform - module Port - RANGE = (0x0001..0xffff).freeze - - def self.call(data) - Integer(data).tap do |int| - raise 'not a valid port' unless RANGE.cover?(int) - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/cli.rb nanoc-4.11.14/nanoc/lib/nanoc/cli.rb --- nanoc-4.11.0/nanoc/lib/nanoc/cli.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/cli.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,241 +0,0 @@ -# frozen_string_literal: true - -begin - require 'cri' -rescue LoadError => e - $stderr.puts e - $stderr.puts "If you are using a Gemfile, make sure that the Gemfile contains Nanoc ('gem \"nanoc\"')." - exit 1 -end - -# @api private -module Nanoc::CLI - module Commands - end -end - -require_relative 'cli/ansi_string_colorizer' -require_relative 'cli/logger' -require_relative 'cli/command_runner' -require_relative 'cli/cleaning_stream' -require_relative 'cli/stream_cleaners' -require_relative 'cli/error_handler' -require_relative 'cli/stack_trace_writer' -require_relative 'cli/transform' - -require_relative 'cli/commands/compile_listeners/abstract' -require_relative 'cli/commands/compile_listeners/debug_printer' -require_relative 'cli/commands/compile_listeners/diff_generator' -require_relative 'cli/commands/compile_listeners/file_action_printer' -require_relative 'cli/commands/compile_listeners/timing_recorder' -require_relative 'cli/commands/compile_listeners/aggregate' - -# @api private -module Nanoc::CLI - # @return [Boolean] true if debug output is enabled, false if not - def self.debug? - @debug || false - end - - # @param [Boolean] boolean true if debug output should be enabled, - # false if it should not - # - # @return [void] - def self.debug=(boolean) - @debug = boolean - end - - def self.verbosity - @verbosity || 0 - end - - def self.verbosity=(val) - @verbosity = val - end - - # Invokes the Nanoc command-line tool with the given arguments. - # - # @param [Array] args An array of command-line arguments - # - # @return [void] - def self.run(args) - Nanoc::CLI::ErrorHandler.handle_while do - setup - root_command.run(args) - end - end - - # @return [Cri::Command] The root command, i.e. the command-line tool itself - def self.root_command - @root_command - end - - # Adds the given command to the collection of available commands. - # - # @param [Cri::Command] cmd The command to add - # - # @return [void] - def self.add_command(cmd) - root_command.add_command(cmd) - end - - # Schedules the given block to be executed after the CLI has been set up. - # - # @return [void] - def self.after_setup(&block) - # TODO: decide what should happen if the CLI is already set up - add_after_setup_proc(block) - end - - # Makes the command-line interface ready for use. - # - # @return [void] - def self.setup - setup_cleaning_streams - setup_commands - load_custom_commands - after_setup_procs.each(&:call) - end - - # Sets up the root command and base subcommands. - # - # @return [void] - def self.setup_commands - # Reinit - @root_command = nil - - # Add root command - filename = __dir__ + '/cli/commands/nanoc.rb' - @root_command = Cri::Command.load_file(filename, infer_name: true) - - # Add help command - help_cmd = Cri::Command.new_basic_help - add_command(help_cmd) - - # Add other commands - cmd_filenames = Dir[__dir__ + '/cli/commands/*.rb'] - cmd_filenames.each do |cmd_filename| - basename = File.basename(cmd_filename, '.rb') - - next if basename == 'nanoc' - - cmd = Cri::Command.load_file(cmd_filename, infer_name: true) - add_command(cmd) - end - - if defined?(Bundler) - # Discover external commands through Bundler - begin - Bundler.require(:nanoc) - rescue Bundler::GemfileNotFound - # When running nanoc with Bundler being defined but - # no gemfile being present (rubygems automatically loads - # Bundler when executing from command line), don't crash. - end - end - end - - # Loads site-specific commands. - # - # @return [void] - def self.load_custom_commands - if Nanoc::Int::SiteLoader.cwd_is_nanoc_site? - config = Nanoc::Int::ConfigLoader.new.new_from_cwd - config[:commands_dirs].each do |path| - load_commands_at(path) - end - end - end - - def self.load_commands_at(path) - recursive_contents_of(path).each do |filename| - # Create command - command = Cri::Command.load_file(filename, infer_name: true) - - # Get supercommand - pieces = filename.gsub(/^#{path}\/|\.rb$/, '').split('/') - pieces = pieces[0, pieces.size - 1] || [] - root = Nanoc::CLI.root_command - supercommand = pieces.reduce(root) do |cmd, piece| - cmd.nil? ? nil : cmd.command_named(piece) - end - - # Add to supercommand - if supercommand.nil? - raise "Cannot load command at #{filename} because its supercommand cannot be found" - end - - supercommand.add_command(command) - end - end - - # Loads the command in the file with the given filename. - # - # @param [String] filename The name of the file that contains the command - # - # @return [Cri::Command] The loaded command - # - # @deprecated - def self.load_command_at(filename) - # TODO: remove me one guard-nanoc is in this repo - Cri::Command.load_file(filename, infer_name: true) - end - - # @return [Array] The directory contents - def self.recursive_contents_of(path) - return [] unless File.directory?(path) - - files, dirs = *Dir[path + '/*'].sort.partition { |e| File.file?(e) } - dirs.each { |d| files.concat recursive_contents_of(d) } - files - end - - # Wraps the given stream in a cleaning stream. The cleaning streams will - # have the proper stream cleaners configured. - # - # @param [IO] io The stream to wrap - # - # @return [::Nanoc::CLI::CleaningStream] - def self.wrap_in_cleaning_stream(io) - cio = ::Nanoc::CLI::CleaningStream.new(io) - - unless enable_utf8?(io) - cio.add_stream_cleaner(Nanoc::CLI::StreamCleaners::UTF8) - end - - unless enable_ansi_colors?(io) - cio.add_stream_cleaner(Nanoc::CLI::StreamCleaners::ANSIColors) - end - - cio - end - - # Wraps `$stdout` and `$stderr` in appropriate cleaning streams. - # - # @return [void] - def self.setup_cleaning_streams - $stdout = wrap_in_cleaning_stream($stdout) - $stderr = wrap_in_cleaning_stream($stderr) - end - - # @return [Boolean] true if UTF-8 support is present, false if not - def self.enable_utf8?(io) - return true unless io.tty? - - %w[LC_ALL LC_CTYPE LANG].any? { |e| ENV[e] =~ /UTF/i } - end - - # @return [Boolean] true if color support is present, false if not - def self.enable_ansi_colors?(io) - io.tty? && !ENV.key?('NO_COLOR') - end - - def self.after_setup_procs - @after_setup_procs || [] - end - - def self.add_after_setup_proc(proc) - @after_setup_procs ||= [] - @after_setup_procs << proc - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/data_sources/filesystem/tools.rb nanoc-4.11.14/nanoc/lib/nanoc/data_sources/filesystem/tools.rb --- nanoc-4.11.0/nanoc/lib/nanoc/data_sources/filesystem/tools.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/data_sources/filesystem/tools.rb 2019-11-10 09:34:31.000000000 +0000 @@ -6,7 +6,7 @@ # @api private module Tools # Error that is raised when too many symlink indirections are encountered. - class MaxSymlinkDepthExceededError < ::Nanoc::Int::Errors::GenericTrivial + class MaxSymlinkDepthExceededError < ::Nanoc::Core::TrivialError # @return [String] The last filename that was attempted to be # resolved before giving up attr_reader :filename @@ -21,7 +21,7 @@ # Error that is raised when a file of an unknown type is encountered # (something other than file, directory or link). - class UnsupportedFileTypeError < ::Nanoc::Int::Errors::GenericTrivial + class UnsupportedFileTypeError < ::Nanoc::Core::TrivialError # @return [String] The filename of the file whose type is not supported attr_reader :filename @@ -93,7 +93,7 @@ # # @return [Array] A list of files and directories # - # @raise [GenericTrivial] when pattern can not be handled + # @raise [Nanoc::Core::TrivialError] when pattern can not be handled def all_files_and_dirs_in(dir_name, extra_files) base_patterns = ["#{dir_name}/**/*"] @@ -107,7 +107,7 @@ extra_files.map { |extra_file| "#{dir_name}/#{extra_file}" } else raise( - Nanoc::Int::Errors::GenericTrivial, + Nanoc::Core::TrivialError, "Do not know how to handle extra_files: #{extra_files.inspect}", ) end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/data_sources/filesystem.rb nanoc-4.11.14/nanoc/lib/nanoc/data_sources/filesystem.rb --- nanoc-4.11.0/nanoc/lib/nanoc/data_sources/filesystem.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/data_sources/filesystem.rb 2019-11-10 09:34:31.000000000 +0000 @@ -66,12 +66,12 @@ # See {Nanoc::DataSource#items}. def items - load_objects(content_dir_name, Nanoc::Int::Item) + load_objects(content_dir_name, Nanoc::Core::Item) end # See {Nanoc::DataSource#layouts}. def layouts - load_objects(layouts_dir_name, Nanoc::Int::Layout) + load_objects(layouts_dir_name, Nanoc::Core::Layout) end def item_changes @@ -141,11 +141,11 @@ def read_proto_document(content_filename, meta_filename, klass) is_binary = content_filename && !@site_config[:text_extensions].include?(File.extname(content_filename)[1..-1]) - if is_binary && klass == Nanoc::Int::Item + if is_binary && klass == Nanoc::Core::Item meta = (meta_filename && YAML.load_file(meta_filename)) || {} ProtoDocument.new(is_binary: true, filename: content_filename, attributes: meta) - elsif is_binary && klass == Nanoc::Int::Layout + elsif is_binary && klass == Nanoc::Core::Layout raise Errors::BinaryLayout.new(content_filename) else parse_result = parse(content_filename, meta_filename) @@ -261,9 +261,9 @@ full_content_filename = content_filename && File.expand_path(content_filename) if proto_doc.binary? - Nanoc::Int::BinaryContent.new(full_content_filename) + Nanoc::Core::BinaryContent.new(full_content_filename) else - Nanoc::Int::TextualContent.new(proto_doc.content, filename: full_content_filename) + Nanoc::Core::TextualContent.new(proto_doc.content, filename: full_content_filename) end end @@ -351,7 +351,7 @@ # can be the content filename or the meta filename. def identifier_for_filename(filename) if config[:identifier_type] == 'full' - return Nanoc::Identifier.new(filename) + return Nanoc::Core::Identifier.new(filename) end regex = @@ -360,7 +360,7 @@ else allow_periods_in_identifiers? ? /\.[^\/\.]+$/ : /\.[^\/]+$/ end - Nanoc::Identifier.new(filename.sub(regex, ''), type: :legacy) + Nanoc::Core::Identifier.new(filename.sub(regex, ''), type: :legacy) end # Returns the base name of filename, i.e. filename with the first or all diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/deploying/deployers/git.rb nanoc-4.11.14/nanoc/lib/nanoc/deploying/deployers/git.rb --- nanoc-4.11.0/nanoc/lib/nanoc/deploying/deployers/git.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/deploying/deployers/git.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,7 +1,7 @@ # frozen_string_literal: true module Nanoc::Deploying::Deployers - # A deployer that deploys a site using [Git](http://git-scm.com). + # A deployer that deploys a site using [Git](https://git-scm.com). # # @example A deployment configuration for GitHub Pages: # @@ -16,7 +16,7 @@ identifier :git module Errors - class Generic < ::Nanoc::Error + class Generic < ::Nanoc::Core::Error end class OutputDirDoesNotExist < Generic @@ -64,7 +64,7 @@ if remote_is_name?(remote) begin run_cmd(%W[git config --get remote.#{remote}.url]) - rescue Nanoc::Extra::Piper::Error + rescue TTY::Command::ExitError raise Errors::RemoteDoesNotExist.new(remote) end end @@ -72,7 +72,7 @@ # If the branch exists then switch to it, otherwise prompt the user to create one. begin run_cmd_unless_dry(%W[git checkout #{branch}]) - rescue Nanoc::Extra::Piper::Error + rescue TTY::Command::ExitError raise Errors::BranchDoesNotExist.new(branch) end @@ -97,24 +97,16 @@ remote !~ /:\/\/|@.+:/ end - def run_cmd(cmd) - piper = Nanoc::Extra::Piper.new(stdout: $stdout, stderr: $stderr) - piper.run(cmd, nil) + def run_cmd(cmd, dry_run: false) + TTY::Command.new(printer: :null).run(*cmd, dry_run: dry_run) end def run_cmd_unless_dry(cmd) - if dry_run - puts cmd.join(' ') - else - run_cmd(cmd) - end + run_cmd(cmd, dry_run: dry_run) end def clean_repo? - stdout = StringIO.new - piper = Nanoc::Extra::Piper.new(stdout: stdout, stderr: $stderr) - piper.run(%w[git status --porcelain], nil) - stdout.string.empty? + TTY::Command.new(printer: :null).run('git status --porcelain').out.empty? end end end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/deploying/deployers/rsync.rb nanoc-4.11.14/nanoc/lib/nanoc/deploying/deployers/rsync.rb --- nanoc-4.11.0/nanoc/lib/nanoc/deploying/deployers/rsync.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/deploying/deployers/rsync.rb 2019-11-10 09:34:31.000000000 +0000 @@ -62,8 +62,7 @@ private def run_shell_cmd(cmd) - piper = Nanoc::Extra::Piper.new(stdout: $stdout, stderr: $stderr) - piper.run(cmd, nil) + TTY::Command.new(printer: :null).run(*cmd) end end end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/deploying/deployers.rb nanoc-4.11.14/nanoc/lib/nanoc/deploying/deployers.rb --- nanoc-4.11.0/nanoc/lib/nanoc/deploying/deployers.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/deploying/deployers.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'tty-command' + # @api private module Nanoc::Deploying::Deployers end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/extra/link_collector.rb nanoc-4.11.14/nanoc/lib/nanoc/extra/link_collector.rb --- nanoc-4.11.0/nanoc/lib/nanoc/extra/link_collector.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/extra/link_collector.rb 2019-11-10 09:34:31.000000000 +0000 @@ -3,16 +3,24 @@ module ::Nanoc::Extra # @api private class LinkCollector + # HTML5 element attributes URI_ATTRS = { - 'a' => :href, - 'audio' => :src, - 'form' => :action, - 'iframe' => :src, - 'img' => :src, - 'link' => :href, - 'script' => :src, - 'video' => :src, + 'a' => %i[href ping], + 'area' => %i[href ping], + 'audio' => %i[src], + 'base' => %i[href], + 'blockquote' => %i[cite], + 'form' => %i[action], + 'iframe' => %i[src], + 'img' => %i[src srcset], + 'link' => %i[href], + 'object' => %i[data], + 'script' => %i[src], + 'source' => %i[src srcset], + 'video' => %i[poster src], }.freeze + # HTML+RDFa global URI attributes + GLOBAL_ATTRS = %i[about resource].freeze def initialize(filenames, mode = nil) Nanoc::Extra::JRubyNokogiriWarner.check_and_warn @@ -25,7 +33,7 @@ when :external ->(h) { external_href?(h) } when :internal - ->(h) { !external_href?(h) } + ->(h) { internal_href?(h) } else raise ArgumentError, 'Expected mode argument to be :internal, :external or nil' end @@ -40,15 +48,25 @@ end def external_href?(href) + return false if internal_href?(href) + href =~ %r{^(\/\/|[a-z\-]+:)} end + def internal_href?(href) + return false if href.nil? + + href.start_with?('file:/') + end + + # all links def hrefs_in_file(filename) - uris_in_file filename, %w[a img] + uris_in_file filename, nil end + # embedded resources, used by the mixed-content checker def resource_uris_in_file(filename) - uris_in_file filename, %w[audio form img iframe link script video] + uris_in_file filename, %w[audio base form iframe img link object script source video] end private @@ -67,16 +85,45 @@ def uris_in_file(filename, tag_names) uris = Set.new + base_uri = URI("file://#{filename}") doc = Nokogiri::HTML(::File.read(filename)) - tag_names.each do |tag_name| - attr = URI_ATTRS[tag_name] - doc.css(tag_name).each do |e| - uris << e[attr] unless e[attr].nil? + doc.traverse do |tag| + next unless tag_names.nil? || tag_names.include?(tag.name) + + attrs = [] + attrs += URI_ATTRS[tag.name] unless URI_ATTRS[tag.name].nil? + attrs += GLOBAL_ATTRS if tag_names.nil? + next if attrs.nil? + + attrs.each do |attr_name| + next if tag[attr_name].nil? + + if attr_name == :srcset + uris = uris.merge(tag[attr_name].split(',').map { |v| v.strip.split[0].strip }.compact) + elsif %i[about ping resource].include?(attr_name) + uris = uris.merge(tag[attr_name].split.map(&:strip).compact) + else + uris << tag[attr_name.to_s] + end end end # Strip fragment - uris.map! { |href| href.gsub(/#.*$/, '') } + uris.map! { |uri| uri.gsub(/#.*$/, '') } + + # Resolve paths relative to the filename, return invalid URIs as-is + uris.map! do |uri| + if uri.start_with?('//') + # Don’t modify protocol-relative URLs. They’re absolute! + uri + else + begin + URI.join(base_uri, uri).to_s + rescue + uri + end + end + end uris.select(&@filter) end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/extra/piper.rb nanoc-4.11.14/nanoc/lib/nanoc/extra/piper.rb --- nanoc-4.11.0/nanoc/lib/nanoc/extra/piper.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/extra/piper.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -module Nanoc::Extra - # @api private - class Piper - class Error < ::Nanoc::Int::Errors::Generic - def initialize(command, exit_code) - @command = command - @exit_code = exit_code - end - - def message - "command exited with a nonzero status code #{@exit_code} (command: #{@command.join(' ')})" - end - end - - # @param [IO] stdout - # @param [IO] stderr - def initialize(stdout: $stdout, stderr: $stderr) - @stdout = stdout - @stderr = stderr - end - - # @param [Array] cmd - # - # @param [String, nil] input - def run(cmd, input) - Open3.popen3(*cmd) do |stdin, stdout, stderr, wait_thr| - stdout_thread = Thread.new { @stdout << stdout.read } - stderr_thread = Thread.new { @stderr << stderr.read } - - if input - stdin << input - end - stdin.close - - stdout_thread.join - stderr_thread.join - - exit_status = wait_thr.value - unless exit_status.success? - raise Error.new(cmd, exit_status.to_i) - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/extra.rb nanoc-4.11.14/nanoc/lib/nanoc/extra.rb --- nanoc-4.11.0/nanoc/lib/nanoc/extra.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/extra.rb 2019-11-10 09:34:31.000000000 +0000 @@ -12,10 +12,9 @@ Deployer = Nanoc::Deploying::Deployer # @deprecated - Pruner = Nanoc::Pruner + Pruner = Nanoc::Core::Pruner end require_relative 'extra/link_collector' -require_relative 'extra/piper' require_relative 'extra/jruby_nokogiri_warner' require_relative 'extra/core_ext' diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/asciidoc.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/asciidoc.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/asciidoc.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/asciidoc.rb 2019-11-10 09:34:31.000000000 +0000 @@ -12,11 +12,7 @@ # # @return [String] The filtered content def run(content, _params = {}) - stdout = StringIO.new - stderr = $stderr - piper = Nanoc::Extra::Piper.new(stdout: stdout, stderr: stderr) - piper.run(%w[asciidoc -o - -], content) - stdout.string + TTY::Command.new(printer: :null).run('asciidoc -o - -', input: content).out end end end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/colorize_syntax/colorizers.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/colorize_syntax/colorizers.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/colorize_syntax/colorizers.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/colorize_syntax/colorizers.rb 2019-11-10 09:34:31.000000000 +0000 @@ -13,8 +13,7 @@ private def check_availability(*cmd) - piper = Nanoc::Extra::Piper.new(stdout: StringIO.new, stderr: StringIO.new) - piper.run(cmd, nil) + TTY::Command.new(printer: :null).run!(*cmd).success? end end @@ -66,12 +65,7 @@ cmd = ['pygmentize', '-l', language, '-f', 'html'] cmd << '-O' << params.map { |k, v| "#{k}=#{v}" }.join(',') unless params.empty? - stdout = StringIO.new - stderr = $stderr - piper = Nanoc::Extra::Piper.new(stdout: stdout, stderr: stderr) - piper.run(cmd, code) - - stdout.string + TTY::Command.new(printer: :null).run(*cmd, input: code).out end end @@ -116,12 +110,7 @@ end end - stdout = StringIO.new - stderr = $stderr - piper = Nanoc::Extra::Piper.new(stdout: stdout, stderr: stderr) - piper.run(cmd, code) - - stdout.string + TTY::Command.new(printer: :null).run(*cmd, input: code).out end end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/erb.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/erb.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/erb.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/erb.rb 2019-11-10 09:34:31.000000000 +0000 @@ -22,7 +22,7 @@ assigns.merge!(params[:locals] || {}) # Create context - context = ::Nanoc::Int::Context.new(assigns) + context = ::Nanoc::Core::Context.new(assigns) # Get binding proc = assigns[:content] ? -> { assigns[:content] } : nil diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/erubi.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/erubi.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/erubi.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/erubi.rb 2019-11-10 09:34:31.000000000 +0000 @@ -16,7 +16,7 @@ # @return [String] The filtered content def run(content, params = {}) # Create context - context = ::Nanoc::Int::Context.new(assigns) + context = ::Nanoc::Core::Context.new(assigns) # Get binding proc = assigns[:content] ? -> { assigns[:content] } : nil diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/erubis.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/erubis.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/erubis.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/erubis.rb 2019-11-10 09:34:31.000000000 +0000 @@ -15,7 +15,7 @@ # @return [String] The filtered content def run(content, _params = {}) # Create context - context = ::Nanoc::Int::Context.new(assigns) + context = ::Nanoc::Core::Context.new(assigns) # Get binding proc = assigns[:content] ? -> { assigns[:content] } : nil diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/haml.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/haml.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/haml.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/haml.rb 2019-11-10 09:34:31.000000000 +0000 @@ -18,7 +18,7 @@ options = params.merge(filename: filename) # Create context - context = ::Nanoc::Int::Context.new(assigns) + context = ::Nanoc::Core::Context.new(assigns) # Get result proc = assigns[:content] ? -> { assigns[:content] } : nil diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/handlebars.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/handlebars.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/handlebars.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/handlebars.rb 2019-11-10 09:34:31.000000000 +0000 @@ -5,7 +5,7 @@ class Handlebars < Nanoc::Filter identifier :handlebars - requires 'handlebars' + requires 'ruby-handlebars' # Runs the content through # [Handlebars](http://handlebarsjs.com/) using @@ -24,7 +24,7 @@ context[:layout] = assigns[:layout].attributes end - handlebars = ::Handlebars::Context.new + handlebars = ::Handlebars::Handlebars.new template = handlebars.compile(content) template.call(context) end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/kramdown.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/kramdown.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/kramdown.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/kramdown.rb 2019-11-10 09:34:31.000000000 +0000 @@ -7,7 +7,7 @@ requires 'kramdown' - # Runs the content through [Kramdown](http://kramdown.gettalong.org/). + # Runs the content through [Kramdown](https://kramdown.gettalong.org/). # Parameters passed to this filter will be passed on to Kramdown. # # @param [String] content The content to filter diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/mustache.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/mustache.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/mustache.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/mustache.rb 2019-11-10 09:34:31.000000000 +0000 @@ -8,7 +8,7 @@ requires 'mustache' # Runs the content through - # [Mustache](http://github.com/defunkt/mustache). This method takes no + # [Mustache](https://github.com/defunkt/mustache). This method takes no # options. # # @param [String] content The content to filter diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/rainpress.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/rainpress.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/rainpress.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/rainpress.rb 2019-11-10 09:34:31.000000000 +0000 @@ -7,7 +7,7 @@ requires 'rainpress' - # Runs the content through [Rainpress](http://code.google.com/p/rainpress/). + # Runs the content through [Rainpress](https://github.com/ddfreyne/rainpress). # Parameters passed to this filter will be passed on to Rainpress. # # @param [String] content The content to filter diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/rdiscount.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/rdiscount.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/rdiscount.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/rdiscount.rb 2019-11-10 09:34:31.000000000 +0000 @@ -7,7 +7,7 @@ requires 'rdiscount' - # Runs the content through [RDiscount](http://github.com/rtomayko/rdiscount). + # Runs the content through [RDiscount](https://github.com/davidfstr/rdiscount). # # @option params [Array] :extensions ([]) A list of RDiscount extensions # diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/redcarpet.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/redcarpet.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/redcarpet.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/redcarpet.rb 2019-11-10 09:34:31.000000000 +0000 @@ -34,8 +34,8 @@ # Render if with_toc renderer_toc = ::Redcarpet::Render::HTML_TOC.new - toc = ::Redcarpet::Markdown.new(renderer_toc, options).render(content) - body = ::Redcarpet::Markdown.new(renderer, options).render(content) + toc = ::Redcarpet::Markdown.new(renderer_toc, options).render(content) + body = ::Redcarpet::Markdown.new(renderer, options).render(content) toc + body else ::Redcarpet::Markdown.new(renderer, options).render(content) diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/sass/importer.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/sass/importer.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/sass/importer.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/sass/importer.rb 2019-11-10 09:34:31.000000000 +0000 @@ -36,13 +36,9 @@ items = filter.items.find_all(identifier) return if items.empty? - content = if items.size == 1 - items.first.compiled_content - else - items.map { |item| %(@import "#{item.identifier}";) }.join("\n") - end + content, syntax = import(items) - options[:syntax] = :scss + options[:syntax] = syntax options[:filename] = identifier.to_s options[:importer] = self ::Sass::Engine.new(content, options) @@ -71,8 +67,9 @@ @raw_filename_to_item_map[config.object_id] ||= {}.tap do |map| items.each do |item| - if item.raw_filename - path = Pathname.new(item.raw_filename).realpath.to_s + filename_without_registering_dependency = item._unwrap.content.filename + if filename_without_registering_dependency + path = Pathname.new(filename_without_registering_dependency).realpath.to_s map[path] = item end end @@ -85,5 +82,37 @@ map = self.class.raw_filename_to_item_map_for_config(filter.config, filter.items) map[realpath] end + + private + + def import(items) + if items.size == 1 + import_single(items.first) + else + import_all(items) + end + end + + def import_single(item) + syntax = if (ext = item.identifier.ext).nil? + nil + else + ext.downcase.to_sym + end + + [ + item.compiled_content, + syntax, + ] + end + + def import_all(items) + import_all = items.map { |i| %(@import "#{i.identifier}";) }.join("\n") + + [ + import_all, + :scss, + ] + end end end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/sass.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/sass.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/sass.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/sass.rb 2019-11-10 09:34:31.000000000 +0000 @@ -28,7 +28,7 @@ css_path = options.delete(:css_path) || filter.object_id.to_s sourcemap_path = options.delete(:sourcemap_path) if sourcemap_path == :inline - sourcemap_path = Nanoc::Int::TempFilenameFactory.instance.create('sass_sourcemap') + sourcemap_path = Nanoc::Core::TempFilenameFactory.instance.create('sass_sourcemap') inline = true end @@ -41,7 +41,7 @@ [css.gsub(%r{^/\*#\s+sourceMappingURL=\s*#{sourcemap_path}\s*\*/$}, "/*# sourceMappingURL=#{encoded} */")] else sourcemap = sourcemap&.to_json(css_path: css_path, sourcemap_path: sourcemap_path, type: params[:sources_content] ? :inline : :auto) - sourcemap = sourcemap&.split("\n")&.reject { |l| l =~ /^\s*"file":\s*"#{filter.object_id.to_s}"\s*$/ }&.join("\n") + sourcemap = sourcemap&.split("\n")&.reject { |l| l =~ /^\s*"file":\s*"#{filter.object_id}"\s*$/ }&.join("\n") [css, sourcemap] end end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/filters/slim.rb nanoc-4.11.14/nanoc/lib/nanoc/filters/slim.rb --- nanoc-4.11.0/nanoc/lib/nanoc/filters/slim.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/filters/slim.rb 2019-11-10 09:34:31.000000000 +0000 @@ -20,7 +20,7 @@ }.merge params # Create context - context = ::Nanoc::Int::Context.new(assigns) + context = ::Nanoc::Core::Context.new(assigns) ::Slim::Template.new(filename, params) { content }.render(context) { assigns[:content] } end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/helpers/blogging.rb nanoc-4.11.14/nanoc/lib/nanoc/helpers/blogging.rb --- nanoc-4.11.0/nanoc/lib/nanoc/helpers/blogging.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/helpers/blogging.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,7 +1,7 @@ # frozen_string_literal: true module Nanoc::Helpers - # @see http://nanoc.ws/doc/reference/helpers/#blogging + # @see https://nanoc.ws/doc/reference/helpers/#blogging module Blogging # @return [Array] def articles @@ -83,28 +83,28 @@ def validate_config if @config[:base_url].nil? - raise Nanoc::Int::Errors::GenericTrivial.new('Cannot build Atom feed: site configuration has no base_url') + raise Nanoc::Core::TrivialError.new('Cannot build Atom feed: site configuration has no base_url') end end def validate_feed_item if title.nil? - raise Nanoc::Int::Errors::GenericTrivial.new('Cannot build Atom feed: no title in params, item or site config') + raise Nanoc::Core::TrivialError.new('Cannot build Atom feed: no title in params, item or site config') end if author_name.nil? - raise Nanoc::Int::Errors::GenericTrivial.new('Cannot build Atom feed: no author_name in params, item or site config') + raise Nanoc::Core::TrivialError.new('Cannot build Atom feed: no author_name in params, item or site config') end if author_uri.nil? - raise Nanoc::Int::Errors::GenericTrivial.new('Cannot build Atom feed: no author_uri in params, item or site config') + raise Nanoc::Core::TrivialError.new('Cannot build Atom feed: no author_uri in params, item or site config') end end def validate_articles if relevant_articles.empty? - raise Nanoc::Int::Errors::GenericTrivial.new('Cannot build Atom feed: no articles') + raise Nanoc::Core::TrivialError.new('Cannot build Atom feed: no articles') end if relevant_articles.any? { |a| a[:created_at].nil? } - raise Nanoc::Int::Errors::GenericTrivial.new('Cannot build Atom feed: one or more articles lack created_at') + raise Nanoc::Core::TrivialError.new('Cannot build Atom feed: one or more articles lack created_at') end end @@ -120,8 +120,8 @@ xml.updated(updated.__nanoc_to_iso8601_time) # Add links - xml.link(rel: 'alternate', href: (alt_link || root_url)) - xml.link(rel: 'self', href: feed_url) + xml.link(rel: 'alternate', href: (alt_link || root_url), type: 'text/html') + xml.link(rel: 'self', href: feed_url, type: 'application/atom+xml') # Add author information xml.author do @@ -163,7 +163,7 @@ end # Add link - xml.link(rel: 'alternate', href: url) + xml.link(rel: 'alternate', href: url, type: 'text/html') # Add content summary = excerpt_proc.call(article) @@ -218,7 +218,7 @@ def url_for(item) # Check attributes if @config[:base_url].nil? - raise Nanoc::Int::Errors::GenericTrivial.new('Cannot build Atom feed: site configuration has no base_url') + raise Nanoc::Core::TrivialError.new('Cannot build Atom feed: site configuration has no base_url') end # Build URL @@ -235,7 +235,7 @@ def feed_url # Check attributes if @config[:base_url].nil? - raise Nanoc::Int::Errors::GenericTrivial.new('Cannot build Atom feed: site configuration has no base_url') + raise Nanoc::Core::TrivialError.new('Cannot build Atom feed: site configuration has no base_url') end @item[:feed_url] || @config[:base_url] + @item.path diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/helpers/breadcrumbs.rb nanoc-4.11.14/nanoc/lib/nanoc/helpers/breadcrumbs.rb --- nanoc-4.11.0/nanoc/lib/nanoc/helpers/breadcrumbs.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/helpers/breadcrumbs.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,9 +1,9 @@ # frozen_string_literal: true module Nanoc::Helpers - # @see http://nanoc.ws/doc/reference/helpers/#breadcrumbs + # @see https://nanoc.ws/doc/reference/helpers/#breadcrumbs module Breadcrumbs - class AmbiguousAncestorError < Nanoc::Int::Errors::Generic + class AmbiguousAncestorError < ::Nanoc::Core::Error def initialize(pattern, items) @pattern = pattern @items = items @@ -49,7 +49,7 @@ def self.patterns_for_prefix(prefix) prefixes = unfold(prefix) do |old_prefix| - new_prefix = Nanoc::Identifier.new(old_prefix).without_ext + new_prefix = Nanoc::Core::Identifier.new(old_prefix).without_ext new_prefix == old_prefix ? nil : new_prefix end @@ -110,7 +110,7 @@ tiebreaker = Int::ERROR_TIEBREAKER if tiebreaker == :error if @item.identifier.legacy? - prefixes.map { |pr| @items[Nanoc::Identifier.new('/' + pr, type: :legacy)] } + prefixes.map { |pr| @items[Nanoc::Core::Identifier.new('/' + pr, type: :legacy)] } else ancestral_prefixes = prefixes.reject { |pr| pr =~ /^\/index\./ }[0..-2] ancestral_items = diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/helpers/capturing.rb nanoc-4.11.14/nanoc/lib/nanoc/helpers/capturing.rb --- nanoc-4.11.0/nanoc/lib/nanoc/helpers/capturing.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/helpers/capturing.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,7 +1,7 @@ # frozen_string_literal: true module Nanoc::Helpers - # @see http://nanoc.ws/doc/reference/helpers/#capturing + # @see https://nanoc.ws/doc/reference/helpers/#capturing module Capturing # @api private class SetContent @@ -20,7 +20,7 @@ content_string = capture(&block) # Get existing contents and prep for store - snapshot_repo = @item._context.snapshot_repo + compiled_content_store = @item._context.compiled_content_store rep = @item.reps[:default]._unwrap capture_name = "__capture_#{@name}".to_sym old_content_string = @@ -28,10 +28,10 @@ when :overwrite '' when :append - c = snapshot_repo.get(rep, capture_name) + c = compiled_content_store.get(rep, capture_name) c ? c.string : '' when :error - contents = snapshot_repo.get(rep, capture_name) + contents = compiled_content_store.get(rep, capture_name) if contents && contents.string != content_string # FIXME: get proper exception raise "a capture named #{@name.inspect} for #{@item.identifier} already exists" @@ -44,8 +44,8 @@ end # Store - new_content = Nanoc::Int::TextualContent.new(old_content_string + content_string) - snapshot_repo.set(rep, capture_name, new_content) + new_content = Nanoc::Core::TextualContent.new(old_content_string + content_string) + compiled_content_store.set(rep, capture_name, new_content) end end @@ -67,13 +67,14 @@ dependency_tracker.bounce(@requested_item._unwrap, compiled_content: true) unless rep.compiled? - Fiber.yield(Nanoc::Int::Errors::UnmetDependency.new(rep)) + # FIXME: is :last appropriate? + Fiber.yield(Nanoc::Core::Errors::UnmetDependency.new(rep, :last)) return run end end - snapshot_repo = @config._context.snapshot_repo - content = snapshot_repo.get(rep, "__capture_#{@name}".to_sym) + compiled_content_store = @config._context.compiled_content_store + content = compiled_content_store.get(rep, "__capture_#{@name}".to_sym) content ? content.string : nil end end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/helpers/child_parent.rb nanoc-4.11.14/nanoc/lib/nanoc/helpers/child_parent.rb --- nanoc-4.11.0/nanoc/lib/nanoc/helpers/child_parent.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/helpers/child_parent.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,7 +1,7 @@ # frozen_string_literal: true module Nanoc::Helpers - # @see http://nanoc.ws/doc/reference/helpers/#childparent + # @see https://nanoc.ws/doc/reference/helpers/#childparent module ChildParent def parent_of(item) if item.identifier.legacy? diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/helpers/filtering.rb nanoc-4.11.14/nanoc/lib/nanoc/helpers/filtering.rb --- nanoc-4.11.0/nanoc/lib/nanoc/helpers/filtering.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/helpers/filtering.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,7 +1,7 @@ # frozen_string_literal: true module Nanoc::Helpers - # @see http://nanoc.ws/doc/reference/helpers/#filtering + # @see https://nanoc.ws/doc/reference/helpers/#filtering module Filtering require 'nanoc/helpers/capturing' include Nanoc::Helpers::Capturing @@ -30,9 +30,9 @@ filter = klass.new(assigns) # Filter captured data - Nanoc::Int::NotificationCenter.post(:filtering_started, @item_rep._unwrap, filter_name) + Nanoc::Core::NotificationCenter.post(:filtering_started, @item_rep._unwrap, filter_name) filtered_data = filter.setup_and_run(data, arguments) - Nanoc::Int::NotificationCenter.post(:filtering_ended, @item_rep._unwrap, filter_name) + Nanoc::Core::NotificationCenter.post(:filtering_ended, @item_rep._unwrap, filter_name) # Append filtered data to buffer buffer = eval('_erbout', block.binding) diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/helpers/html_escape.rb nanoc-4.11.14/nanoc/lib/nanoc/helpers/html_escape.rb --- nanoc-4.11.0/nanoc/lib/nanoc/helpers/html_escape.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/helpers/html_escape.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,7 +1,7 @@ # frozen_string_literal: true module Nanoc::Helpers - # @see http://nanoc.ws/doc/reference/helpers/#filtering + # @see https://nanoc.ws/doc/reference/helpers/#filtering module HTMLEscape require 'nanoc/helpers/capturing' include Nanoc::Helpers::Capturing diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/helpers/link_to.rb nanoc-4.11.14/nanoc/lib/nanoc/helpers/link_to.rb --- nanoc-4.11.0/nanoc/lib/nanoc/helpers/link_to.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/helpers/link_to.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,7 +1,7 @@ # frozen_string_literal: true module Nanoc::Helpers - # @see http://nanoc.ws/doc/reference/helpers/#linkto + # @see https://nanoc.ws/doc/reference/helpers/#linkto module LinkTo require 'nanoc/helpers/html_escape' include Nanoc::Helpers::HTMLEscape @@ -17,7 +17,7 @@ case target when String target - when Nanoc::CompilationItemView, Nanoc::BasicItemView, Nanoc::BasicItemRepView + when Nanoc::Core::CompilationItemView, Nanoc::Core::BasicItemView, Nanoc::Core::BasicItemRepView raise "Cannot create a link to #{target.inspect} because this target is not outputted (its routing rule returns nil)" if target.path.nil? target.path diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/helpers/rendering.rb nanoc-4.11.14/nanoc/lib/nanoc/helpers/rendering.rb --- nanoc-4.11.0/nanoc/lib/nanoc/helpers/rendering.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/helpers/rendering.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,7 +1,7 @@ # frozen_string_literal: true module Nanoc::Helpers - # @see http://nanoc.ws/doc/reference/helpers/#rendering + # @see https://nanoc.ws/doc/reference/helpers/#rendering module Rendering include Nanoc::Helpers::Capturing @@ -10,7 +10,7 @@ # # @raise [Nanoc::Int::Errors::UnknownLayout] # @raise [Nanoc::Int::Errors::CannotDetermineFilter] - # @raise [Nanoc::Int::Errors::UnknownFilter] + # @raise [Nanoc::Filter::UnknownFilter] # # @return [String, nil] def render(identifier, other_assigns = {}, &block) @@ -40,7 +40,9 @@ }.merge(other_assigns) # Get filter name - filter_name, filter_args = *@config._context.compilation_context.filter_name_and_args_for_layout(layout) + filter_name_and_args = @config._context.compilation_context.filter_name_and_args_for_layout(layout) + filter_name = filter_name_and_args.name + filter_args = filter_name_and_args.args raise Nanoc::Int::Errors::CannotDetermineFilter.new(layout.identifier) if filter_name.nil? # Get filter class diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/helpers/tagging.rb nanoc-4.11.14/nanoc/lib/nanoc/helpers/tagging.rb --- nanoc-4.11.0/nanoc/lib/nanoc/helpers/tagging.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/helpers/tagging.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,7 +1,7 @@ # frozen_string_literal: true module Nanoc::Helpers - # @see http://nanoc.ws/doc/reference/helpers/#tagging + # @see https://nanoc.ws/doc/reference/helpers/#tagging module Tagging require 'nanoc/helpers/html_escape' include Nanoc::Helpers::HTMLEscape diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/helpers/text.rb nanoc-4.11.14/nanoc/lib/nanoc/helpers/text.rb --- nanoc-4.11.0/nanoc/lib/nanoc/helpers/text.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/helpers/text.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,7 +1,7 @@ # frozen_string_literal: true module Nanoc::Helpers - # @see http://nanoc.ws/doc/reference/helpers/#text + # @see https://nanoc.ws/doc/reference/helpers/#text module Text # @param [String] string # @param [Number] length diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/helpers/xml_sitemap.rb nanoc-4.11.14/nanoc/lib/nanoc/helpers/xml_sitemap.rb --- nanoc-4.11.0/nanoc/lib/nanoc/helpers/xml_sitemap.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/helpers/xml_sitemap.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,7 +1,7 @@ # frozen_string_literal: true module Nanoc::Helpers - # @see http://nanoc.ws/doc/reference/helpers/#xmlsitemap + # @see https://nanoc.ws/doc/reference/helpers/#xmlsitemap module XMLSitemap # @option params [Array] :items # @option params [Proc] :rep_select diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/orig_cli/commands/check.rb nanoc-4.11.14/nanoc/lib/nanoc/orig_cli/commands/check.rb --- nanoc-4.11.0/nanoc/lib/nanoc/orig_cli/commands/check.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/orig_cli/commands/check.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +usage 'check [options] [names]' +summary 'run issue checks' +description " +Run issue checks on the current site. If the `--all` option is passed, all available issue checks will be run. By default, the issue checks marked for deployment will be run. +" + +flag :a, :all, 'run all checks' +flag :L, :list, 'list all checks' +flag :d, :deploy, '(deprecated)' + +module Nanoc::OrigCLI::Commands + class Check < ::Nanoc::CLI::CommandRunner + def run + site = load_site + + runner = Nanoc::Checking::Runner.new(site) + + if options[:list] + runner.list_checks + return + end + + success = + if options[:all] + runner.run_all + elsif options[:deploy] + runner.run_for_deploy + elsif arguments.any? + runner.run_specific(arguments) + else + runner.run_for_deploy + end + + unless success + raise Nanoc::Core::TrivialError, 'One or more checks failed' + end + end + end +end + +runner Nanoc::OrigCLI::Commands::Check diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/orig_cli/commands/deploy.rb nanoc-4.11.14/nanoc/lib/nanoc/orig_cli/commands/deploy.rb --- nanoc-4.11.0/nanoc/lib/nanoc/orig_cli/commands/deploy.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/orig_cli/commands/deploy.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,126 @@ +# frozen_string_literal: true + +usage 'deploy [target] [options]' +summary 'deploy the compiled site' +description " +Deploys the compiled site. The compiled site contents in the output directory will be uploaded to the destination, which is specified using the `--target` option. +" + +option :t, :target, 'specify the location to deploy to (default: `default`)', argument: :required +flag :C, :'no-check', 'do not run the issue checks marked for deployment' +flag :L, :list, 'list available locations to deploy to' +flag :D, :'list-deployers', 'list available deployers' +option :n, :'dry-run', 'show what would be deployed' + +module Nanoc::OrigCLI::Commands + class Deploy < ::Nanoc::CLI::CommandRunner + def run + @site = load_site + Nanoc::Core::Compiler.new_for(@site).run_until_preprocessed + + if options[:'list-deployers'] + list_deployers + elsif options[:list] + list_deploy_configs + else + deploy + end + end + + private + + def list_deployers + deployers = Nanoc::Deploying::Deployer.all + deployer_names = deployers.map(&:identifier).sort + puts 'Available deployers:' + deployer_names.each do |name| + puts " #{name}" + end + end + + def list_deploy_configs + if deploy_configs.empty? + puts 'No deployment configurations.' + else + puts 'Available deployment configurations:' + deploy_configs.each_key do |name| + puts " #{name}" + end + end + end + + def deploy + deployer = deployer_for(deploy_config) + + checks_successful = options[:'no-check'] ? true : check + return unless checks_successful + + deployer.run + end + + def deploy_config + if deploy_configs.empty? + raise Nanoc::Core::TrivialError, 'The site has no deployment configurations.' + end + + if arguments.length > 1 + raise Nanoc::Core::TrivialError, "usage: #{command.usage}" + end + + target_from_arguments = arguments[0] + target_from_options = options.fetch(:target, nil) + if target_from_arguments && target_from_options + raise Nanoc::Core::TrivialError, 'Only one deployment target can be specified on the command line.' + end + + target = target_from_arguments || target_from_options || :default + deploy_configs.fetch(target.to_sym) do + raise Nanoc::Core::TrivialError, "The site has no deployment configuration named `#{target}`." + end + end + + def deployer_for(config) + deployer_class_for_config(config).new( + @site.config.output_dir, + config, + dry_run: options[:'dry-run'], + ) + end + + def check + runner = Nanoc::Checking::Runner.new(@site) + if runner.any_enabled_checks? + puts 'Running issue checks…' + is_success = runner.run_for_deploy + if is_success + puts 'No issues found. Deploying!' + else + puts 'Issues found, deploy aborted.' + end + is_success + else + true + end + end + + def deploy_configs + @site.config.fetch(:deploy, {}) + end + + def deployer_class_for_config(config) + name = config.fetch(:kind) do + $stderr.puts 'Warning: The specified deploy target does not have a kind attribute. Assuming rsync.' + 'rsync' + end + + deployer_class = Nanoc::Deploying::Deployer.named(name.to_sym) + if deployer_class.nil? + names = Nanoc::Deploying::Deployer.all.map(&:identifier) + raise Nanoc::Core::TrivialError, "The specified deploy target has an unrecognised kind “#{name}” (expected one of #{names.join(', ')})." + end + deployer_class + end + end +end + +runner Nanoc::OrigCLI::Commands::Deploy diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/orig_cli/commands/show-rules.rb nanoc-4.11.14/nanoc/lib/nanoc/orig_cli/commands/show-rules.rb --- nanoc-4.11.0/nanoc/lib/nanoc/orig_cli/commands/show-rules.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/orig_cli/commands/show-rules.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +usage 'show-rules [thing]' +aliases :explain +summary 'describe the rules for each item' +description " +Prints the rules used for all items and layouts in the current site. +" +no_params + +module Nanoc::OrigCLI::Commands + class ShowRules < ::Nanoc::CLI::CommandRunner + def run + site = load_site + + res = Nanoc::Core::Compiler.new_for(site).run_until_reps_built + reps = res.fetch(:reps) + + action_provider = Nanoc::Core::ActionProvider.named(site.config.action_provider).for(site) + rules = action_provider.rules_collection + + items = site.items.sort_by(&:identifier) + layouts = site.layouts.sort_by(&:identifier) + + items.each { |e| explain_item(e, rules: rules, reps: reps) } + layouts.each { |e| explain_layout(e, rules: rules) } + end + + def explain_item(item, rules:, reps:) + puts(fmt_heading("Item #{item.identifier}") + ':') + + reps[item].each do |rep| + rule = rules.compilation_rule_for(rep) + puts " Rep #{rep.name}: #{rule ? rule.pattern : '(none)'}" + end + + puts + end + + def explain_layout(layout, rules:) + puts(fmt_heading("Layout #{layout.identifier}") + ':') + + found = false + rules.layout_filter_mapping.each_key do |pattern| + if pattern.match?(layout.identifier) + puts " #{pattern}" + found = true + break + end + end + unless found + puts ' (none)' + end + + puts + end + + def fmt_heading(str) + Nanoc::CLI::ANSIStringColorizer.c(str, :bold, :yellow) + end + end +end + +runner Nanoc::OrigCLI::Commands::ShowRules diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/orig_cli.rb nanoc-4.11.14/nanoc/lib/nanoc/orig_cli.rb --- nanoc-4.11.0/nanoc/lib/nanoc/orig_cli.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/orig_cli.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'nanoc-cli' + +# @api private +module Nanoc::OrigCLI + module Commands + end +end + +Nanoc::CLI.after_setup do + root = File.dirname(__FILE__) + commands_path = File.join(root, 'orig_cli', 'commands') + Nanoc::CLI.add_command(Cri::Command.load_file(File.join(commands_path, 'check.rb'), infer_name: true)) + Nanoc::CLI.add_command(Cri::Command.load_file(File.join(commands_path, 'deploy.rb'), infer_name: true)) + Nanoc::CLI.add_command(Cri::Command.load_file(File.join(commands_path, 'show-rules.rb'), infer_name: true)) + + # TODO: move into nanoc-deploying, once that exists as a package + Nanoc::CLI::Commands::ShowPlugins.add_plugin_class(Nanoc::Deploying::Deployer, 'Deployers') +end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/action_provider.rb nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/action_provider.rb --- nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/action_provider.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/action_provider.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,7 +1,7 @@ # frozen_string_literal: true module Nanoc::RuleDSL - class ActionProvider < Nanoc::Int::ActionProvider + class ActionProvider < Nanoc::Core::ActionProvider identifier :rule_dsl # @api private @@ -50,22 +50,22 @@ end site.data_source = - Nanoc::Int::InMemDataSource.new(ctx.items._unwrap, ctx.layouts._unwrap, site.data_source) + Nanoc::Core::InMemoryDataSource.new(ctx.items._unwrap, ctx.layouts._unwrap, site.data_source) end def postprocess(site, compiler) - dependency_tracker = Nanoc::Int::DependencyTracker::Null.new + dependency_tracker = Nanoc::Core::DependencyTracker::Null.new res = compiler.run_until_reps_built reps = res.fetch(:reps) view_context = - Nanoc::ViewContextForCompilation.new( + Nanoc::Core::ViewContextForCompilation.new( reps: reps, items: site.items, dependency_tracker: dependency_tracker, compilation_context: compiler.compilation_context(reps: reps), - snapshot_repo: nil, + compiled_content_store: Nanoc::Core::CompiledContentStore.new, ) ctx = new_postprocessor_context(site, view_context) @@ -77,20 +77,20 @@ # @api private def new_preprocessor_context(site) view_context = - Nanoc::ViewContextForPreCompilation.new(items: site.items) + Nanoc::Core::ViewContextForPreCompilation.new(items: site.items) - Nanoc::Int::Context.new( - config: Nanoc::MutableConfigView.new(site.config, view_context), - items: Nanoc::MutableItemCollectionView.new(site.items, view_context), - layouts: Nanoc::MutableLayoutCollectionView.new(site.layouts, view_context), + Nanoc::Core::Context.new( + config: Nanoc::Core::MutableConfigView.new(site.config, view_context), + items: Nanoc::Core::MutableItemCollectionView.new(site.items, view_context), + layouts: Nanoc::Core::MutableLayoutCollectionView.new(site.layouts, view_context), ) end # @api private def new_postprocessor_context(site, view_context) - Nanoc::Int::Context.new( - config: Nanoc::ConfigView.new(site.config, view_context), - items: Nanoc::PostCompileItemCollectionView.new(site.items, view_context), + Nanoc::Core::Context.new( + config: Nanoc::Core::ConfigView.new(site.config, view_context), + items: Nanoc::Core::PostCompileItemCollectionView.new(site.items, view_context), ) end end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/action_recorder.rb nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/action_recorder.rb --- nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/action_recorder.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/action_recorder.rb 2019-11-10 09:34:31.000000000 +0000 @@ -3,11 +3,11 @@ module Nanoc module RuleDSL class ActionRecorder - include Nanoc::Int::ContractsSupport + include Nanoc::Core::ContractsSupport - contract Nanoc::Int::ItemRep => C::Any + contract Nanoc::Core::ItemRep => C::Any def initialize(rep) - @action_sequence_builder = Nanoc::Int::ActionSequenceBuilder.new(rep) + @action_sequence_builder = Nanoc::Core::ActionSequenceBuilder.new(rep) @any_layouts = false @last_snapshot = false @@ -37,15 +37,15 @@ @any_layouts = true end - MaybePathlike = C::Or[nil, Nanoc::UNDEFINED, String, Nanoc::Identifier] + MaybePathlike = C::Or[nil, Nanoc::Core::UNDEFINED, String, Nanoc::Core::Identifier] contract Symbol, C::KeywordArgs[path: C::Optional[MaybePathlike]] => nil - def snapshot(snapshot_name, path: Nanoc::UNDEFINED) - unless Nanoc::UNDEFINED.equal?(path) + def snapshot(snapshot_name, path: Nanoc::Core::UNDEFINED) + unless Nanoc::Core::UNDEFINED.equal?(path) @snapshots_for_which_to_skip_routing_rule << snapshot_name end path = - if Nanoc::UNDEFINED.equal?(path) || path.nil? + if Nanoc::Core::UNDEFINED.equal?(path) || path.nil? nil else path.to_s @@ -61,7 +61,7 @@ nil end - contract C::None => Nanoc::Int::ActionSequence + contract C::None => Nanoc::Core::ActionSequence def action_sequence @action_sequence_builder.action_sequence end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/action_sequence_calculator.rb nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/action_sequence_calculator.rb --- nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/action_sequence_calculator.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/action_sequence_calculator.rb 2019-11-10 09:34:31.000000000 +0000 @@ -31,7 +31,7 @@ # @api private attr_accessor :rules_collection - # @param [Nanoc::Int::Site] site + # @param [Nanoc::Core::Site] site # @param [Nanoc::RuleDSL::RulesCollection] rules_collection def initialize(site:, rules_collection:) @site = site @@ -40,12 +40,12 @@ # @param [#reference] obj # - # @return [Nanoc::Int::ActionSequence] + # @return [Nanoc::Core::ActionSequence] def [](obj) case obj - when Nanoc::Int::ItemRep + when Nanoc::Core::ItemRep new_action_sequence_for_rep(obj) - when Nanoc::Int::Layout + when Nanoc::Core::Layout new_action_sequence_for_layout(obj) else raise UnsupportedObjectTypeException.new(obj) @@ -54,7 +54,7 @@ def new_action_sequence_for_rep(rep) view_context = - Nanoc::ViewContextForPreCompilation.new(items: @site.items) + Nanoc::Core::ViewContextForPreCompilation.new(items: @site.items) recorder = Nanoc::RuleDSL::ActionRecorder.new(rep) rule = @rules_collection.compilation_rule_for(rep) @@ -66,7 +66,7 @@ recorder.snapshot(:raw) rule.apply_to(rep, recorder: recorder, site: @site, view_context: view_context) recorder.snapshot(:post) if recorder.any_layouts? - recorder.snapshot(:last) unless recorder.last_snapshot? + recorder.snapshot(:last) recorder.snapshot(:pre) unless recorder.pre_snapshot? copy_paths_from_routing_rules( @@ -76,9 +76,9 @@ ) end - # @param [Nanoc::Int::Layout] layout + # @param [Nanoc::Core::Layout] layout # - # @return [Nanoc::Int::ActionSequence] + # @return [Nanoc::Core::ActionSequence] def new_action_sequence_for_layout(layout) res = @rules_collection.filter_for_layout(layout) @@ -86,7 +86,7 @@ raise NoActionSequenceForLayoutException.new(layout) end - Nanoc::Int::ActionSequence.build(layout) do |b| + Nanoc::Core::ActionSequenceBuilder.build(layout) do |b| b.add_filter(res[0], res[1]) end end @@ -94,13 +94,13 @@ def compact_snapshots(seq) actions = [] seq.actions.each do |action| - if [actions.last, action].all? { |a| a.is_a?(Nanoc::Int::ProcessingActions::Snapshot) } + if [actions.last, action].all? { |a| a.is_a?(Nanoc::Core::ProcessingActions::Snapshot) } actions[-1] = actions.last.update(snapshot_names: action.snapshot_names, paths: action.paths) else actions << action end end - Nanoc::Int::ActionSequence.new(seq.item_rep, actions: actions) + Nanoc::Core::ActionSequence.new(seq.item_rep, actions: actions) end def copy_paths_from_routing_rules(seq, snapshots_for_which_to_skip_routing_rule, rep:) @@ -108,7 +108,7 @@ seq.map do |action| # Only potentially modify snapshot actions - next action unless action.is_a?(Nanoc::Int::ProcessingActions::Snapshot) + next action unless action.is_a?(Nanoc::Core::ProcessingActions::Snapshot) # If any of the action’s snapshot are explicitly marked as excluded from # getting a path from a routing rule, then ignore routing rules. @@ -132,7 +132,7 @@ return nil if routing_rule.nil? view_context = - Nanoc::ViewContextForPreCompilation.new(items: @site.items) + Nanoc::Core::ViewContextForPreCompilation.new(items: @site.items) basic_path = routing_rule.apply_to( diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/compilation_rule_context.rb nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/compilation_rule_context.rb --- nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/compilation_rule_context.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/compilation_rule_context.rb 2019-11-10 09:34:31.000000000 +0000 @@ -2,13 +2,13 @@ module Nanoc::RuleDSL class CompilationRuleContext < RuleContext - include Nanoc::Int::ContractsSupport + include Nanoc::Core::ContractsSupport contract C::KeywordArgs[ - rep: Nanoc::Int::ItemRep, - site: Nanoc::Int::Site, + rep: Nanoc::Core::ItemRep, + site: Nanoc::Core::Site, recorder: Nanoc::RuleDSL::ActionRecorder, - view_context: Nanoc::ViewContextForPreCompilation, + view_context: Nanoc::Core::ViewContextForPreCompilation, ] => C::Any def initialize(rep:, site:, recorder:, view_context:) @_recorder = recorder @@ -16,10 +16,10 @@ super(rep: rep, site: site, view_context: view_context) end - # Filters the current representation (calls {Nanoc::Int::ItemRep#filter} with + # Filters the current representation (calls {Nanoc::Core::ItemRep#filter} with # the given arguments on the rep). # - # @see Nanoc::Int::ItemRep#filter + # @see Nanoc::Core::ItemRep#filter # # @param [Symbol] filter_name The name of the filter to run the item # representations' content through @@ -32,10 +32,10 @@ @_recorder.filter(filter_name, filter_args) end - # Layouts the current representation (calls {Nanoc::Int::ItemRep#layout} with + # Layouts the current representation (calls {Nanoc::Core::ItemRep#layout} with # the given arguments on the rep). # - # @see Nanoc::Int::ItemRep#layout + # @see Nanoc::Core::ItemRep#layout # # @param [String] layout_identifier The identifier of the layout the item # should be laid out with @@ -46,16 +46,16 @@ end # Creates a snapshot of the current compiled item content. Calls - # {Nanoc::Int::ItemRep#snapshot} with the given arguments on the rep. + # {Nanoc::Core::ItemRep#snapshot} with the given arguments on the rep. # - # @see Nanoc::Int::ItemRep#snapshot + # @see Nanoc::Core::ItemRep#snapshot # # @param [Symbol] snapshot_name The name of the snapshot to create # # @param [String, nil] path # # @return [void] - def snapshot(snapshot_name, path: Nanoc::UNDEFINED) + def snapshot(snapshot_name, path: Nanoc::Core::UNDEFINED) @_recorder.snapshot(snapshot_name, path: path) end @@ -73,7 +73,7 @@ @_write_snapshot_counter += 1 case arg - when String, Nanoc::Identifier, nil + when String, Nanoc::Core::Identifier, nil snapshot(snapshot_name, path: arg) when Hash if arg.key?(:ext) diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/compilation_rule.rb nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/compilation_rule.rb --- nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/compilation_rule.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/compilation_rule.rb 2019-11-10 09:34:31.000000000 +0000 @@ -2,12 +2,12 @@ module Nanoc::RuleDSL class CompilationRule < Rule - include Nanoc::Int::ContractsSupport + include Nanoc::Core::ContractsSupport - contract Nanoc::Int::ItemRep, C::KeywordArgs[ - site: Nanoc::Int::Site, + contract Nanoc::Core::ItemRep, C::KeywordArgs[ + site: Nanoc::Core::Site, recorder: Nanoc::RuleDSL::ActionRecorder, - view_context: Nanoc::ViewContextForPreCompilation, + view_context: Nanoc::Core::ViewContextForPreCompilation, ] => C::Any def apply_to(rep, site:, recorder:, view_context:) context = Nanoc::RuleDSL::CompilationRuleContext.new( diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/compiler_dsl.rb nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/compiler_dsl.rb --- nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/compiler_dsl.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/compiler_dsl.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,7 +1,7 @@ # frozen_string_literal: true module Nanoc::RuleDSL - class CompilerDSL < Nanoc::Int::Context + class CompilerDSL < Nanoc::Core::Context # The current rules filename. # # @return [String] The current rules filename. @@ -140,7 +140,7 @@ # # layout '/custom/', :haml, :format => :html5 def layout(identifier, filter_name, params = {}) - pattern = Nanoc::Int::Pattern.from(create_pattern(identifier)) + pattern = Nanoc::Core::Pattern.from(create_pattern(identifier)) @rules_collection.layout_filter_mapping[pattern] = [filter_name, params] end @@ -254,12 +254,12 @@ def create_pattern(arg) case @config[:string_pattern_type] when 'glob' - Nanoc::Int::Pattern.from(arg) + Nanoc::Core::Pattern.from(arg) when 'legacy' - Nanoc::Int::Pattern.from(identifier_to_regex(arg)) + Nanoc::Core::Pattern.from(identifier_to_regex(arg)) else raise( - Nanoc::Int::Errors::GenericTrivial, + Nanoc::Core::TrivialError, "Invalid string_pattern_type: #{@config[:string_pattern_type]}", ) end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/routing_rule.rb nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/routing_rule.rb --- nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/routing_rule.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/routing_rule.rb 2019-11-10 09:34:31.000000000 +0000 @@ -2,21 +2,21 @@ module Nanoc::RuleDSL class RoutingRule < Rule - include Nanoc::Int::ContractsSupport + include Nanoc::Core::ContractsSupport contract C::None => C::Maybe[Symbol] attr_reader :snapshot_name - contract Nanoc::Int::Pattern, Symbol, Proc, C::KeywordArgs[snapshot_name: C::Optional[Symbol]] => C::Any + contract Nanoc::Core::Pattern, Symbol, Proc, C::KeywordArgs[snapshot_name: C::Optional[Symbol]] => C::Any def initialize(pattern, rep_name, block, snapshot_name: nil) super(pattern, rep_name, block) @snapshot_name = snapshot_name end - contract Nanoc::Int::ItemRep, C::KeywordArgs[ - site: Nanoc::Int::Site, - view_context: Nanoc::ViewContextForPreCompilation, + contract Nanoc::Core::ItemRep, C::KeywordArgs[ + site: Nanoc::Core::Site, + view_context: Nanoc::Core::ViewContextForPreCompilation, ] => C::Any def apply_to(rep, site:, view_context:) context = Nanoc::RuleDSL::RoutingRuleContext.new( diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/rule_context.rb nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/rule_context.rb --- nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/rule_context.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/rule_context.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,22 +1,22 @@ # frozen_string_literal: true module Nanoc::RuleDSL - class RuleContext < Nanoc::Int::Context - include Nanoc::Int::ContractsSupport + class RuleContext < Nanoc::Core::Context + include Nanoc::Core::ContractsSupport contract C::KeywordArgs[ - rep: Nanoc::Int::ItemRep, - site: Nanoc::Int::Site, - view_context: Nanoc::ViewContextForPreCompilation, + rep: Nanoc::Core::ItemRep, + site: Nanoc::Core::Site, + view_context: Nanoc::Core::ViewContextForPreCompilation, ] => C::Any def initialize(rep:, site:, view_context:) super({ - item: Nanoc::BasicItemView.new(rep.item, view_context), - rep: Nanoc::BasicItemRepView.new(rep, view_context), - item_rep: Nanoc::BasicItemRepView.new(rep, view_context), - items: Nanoc::ItemCollectionWithoutRepsView.new(site.items, view_context), - layouts: Nanoc::LayoutCollectionView.new(site.layouts, view_context), - config: Nanoc::ConfigView.new(site.config, view_context), + item: Nanoc::Core::BasicItemView.new(rep.item, view_context), + rep: Nanoc::Core::BasicItemRepView.new(rep, view_context), + item_rep: Nanoc::Core::BasicItemRepView.new(rep, view_context), + items: Nanoc::Core::ItemCollectionWithoutRepsView.new(site.items, view_context), + layouts: Nanoc::Core::LayoutCollectionView.new(site.layouts, view_context), + config: Nanoc::Core::ConfigView.new(site.config, view_context), }) end end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/rule.rb nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/rule.rb --- nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/rule.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/rule.rb 2019-11-10 09:34:31.000000000 +0000 @@ -2,28 +2,28 @@ module Nanoc::RuleDSL class Rule - include Nanoc::Int::ContractsSupport + include Nanoc::Core::ContractsSupport contract C::None => Symbol attr_reader :rep_name - contract C::None => Nanoc::Int::Pattern + contract C::None => Nanoc::Core::Pattern attr_reader :pattern - contract Nanoc::Int::Pattern, Symbol, Proc => C::Any + contract Nanoc::Core::Pattern, Symbol, Proc => C::Any def initialize(pattern, rep_name, block) @pattern = pattern @rep_name = rep_name.to_sym @block = block end - contract Nanoc::Int::Item => C::Bool + contract Nanoc::Core::Item => C::Bool def applicable_to?(item) @pattern.match?(item.identifier) end # @api private - contract Nanoc::Identifier => C::Or[nil, C::ArrayOf[String]] + contract Nanoc::Core::Identifier => C::Or[nil, C::ArrayOf[String]] def matches(identifier) @pattern.captures(identifier) end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/rules_collection.rb nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/rules_collection.rb --- nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl/rules_collection.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl/rules_collection.rb 2019-11-10 09:34:31.000000000 +0000 @@ -54,7 +54,7 @@ @item_routing_rules << rule end - # @param [Nanoc::Int::Item] item The item for which the compilation rules + # @param [Nanoc::Core::Item] item The item for which the compilation rules # should be retrieved # # @return [Array] The list of item compilation rules for the given item @@ -65,7 +65,7 @@ # Finds the first matching compilation rule for the given item # representation. # - # @param [Nanoc::Int::ItemRep] rep The item rep for which to fetch the rule + # @param [Nanoc::Core::ItemRep] rep The item rep for which to fetch the rule # # @return [Nanoc::Int::Rule, nil] The compilation rule for the given item rep, # or nil if no rules have been found @@ -80,7 +80,7 @@ # returned. The result is a hash containing the corresponding rule for # each snapshot. # - # @param [Nanoc::Int::ItemRep] rep The item rep for which to fetch the rules + # @param [Nanoc::Core::ItemRep] rep The item rep for which to fetch the rules # # @return [Hash] The routing rules for the given rep def routing_rules_for(rep) @@ -97,7 +97,7 @@ # Finds the filter name and arguments to use for the given layout. # - # @param [Nanoc::Int::Layout] layout The layout for which to fetch the filter. + # @param [Nanoc::Core::Layout] layout The layout for which to fetch the filter. # # @return [Array, nil] A tuple containing the filter name and the filter # arguments for the given layout. diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl.rb nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl.rb --- nanoc-4.11.0/nanoc/lib/nanoc/rule_dsl.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/rule_dsl.rb 2019-11-10 09:34:31.000000000 +0000 @@ -20,3 +20,13 @@ require_relative 'rule_dsl/rule' require_relative 'rule_dsl/compilation_rule' require_relative 'rule_dsl/routing_rule' + +Nanoc::Core::Checksummer.define_behavior( + Nanoc::RuleDSL::CompilationRuleContext, + Nanoc::Core::Checksummer::RuleContextUpdateBehavior, +) + +Nanoc::Core::Checksummer.define_behavior( + Nanoc::RuleDSL::RulesCollection, + Nanoc::Core::Checksummer::DataUpdateBehavior, +) diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/spec.rb nanoc-4.11.14/nanoc/lib/nanoc/spec.rb --- nanoc-4.11.0/nanoc/lib/nanoc/spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,245 +0,0 @@ -# frozen_string_literal: true - -module Nanoc - # @api private - module Spec - module Helper - def chdir(dir) - here = Dir.getwd - Dir.chdir(dir) - yield - ensure - Dir.chdir(here) - end - - def on_windows? - Nanoc.on_windows? - end - - def command?(cmd) - which, null = on_windows? ? %w[where NUL] : ['which', '/dev/null'] - system("#{which} #{cmd} > #{null} 2>&1") - end - - def skip_unless_have_command(cmd) - skip "Could not find external command \"#{cmd}\"" unless command?(cmd) - end - - def skip_unless_gem_available(gem) - require gem - rescue LoadError - skip "Could not load gem \"#{gem}\"" - end - - def sleep_until(max: 3.0) - start = Time.now - loop do - diff = (Time.now - start).to_f - if diff > max - raise "Waited for #{diff}s for condition to become true, but it never did" - end - - break if yield - - sleep 0.1 - end - end - end - - class HelperContext - # @return [Nanoc::Int::DependencyTracker] - attr_reader :dependency_tracker - - attr_reader :erbout - - # @param [Module] mod The helper module to create a context for - def initialize(mod) - @mod = mod - - @erbout = +'' - @action_sequence = {} - @config = Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults - @reps = Nanoc::Int::ItemRepRepo.new - @items = Nanoc::Int::ItemCollection.new(@config) - @layouts = Nanoc::Int::LayoutCollection.new(@config) - @dependency_tracker = Nanoc::Int::DependencyTracker.new(Object.new) - @snapshot_repo = Nanoc::Int::SnapshotRepo.new - @action_provider = new_action_provider - end - - # Creates a new item and adds it to the site’s collection of items. - # - # @param [String] content The uncompiled item content - # - # @param [Hash] attributes A hash containing this item's attributes - # - # @param [Nanoc::Identifier, String] identifier This item's identifier - # - # @return [Nanoc::CompilationItemView] A view for the newly created item - def create_item(content, attributes, identifier) - item = Nanoc::Int::Item.new(content, attributes, identifier) - @items = @items.add(item) - self - end - - # Creates a new layout and adds it to the site’s collection of layouts. - # - # @param [String] content The raw layout content - # - # @param [Hash] attributes A hash containing this layout's attributes - # - # @param [Nanoc::Identifier, String] identifier This layout's identifier - # - # @return [Nanoc::CompilationItemView] A view for the newly created layout - def create_layout(content, attributes, identifier) - layout = Nanoc::Int::Layout.new(content, attributes, identifier) - @layouts = @layouts.add(layout) - self - end - - # Creates a new representation for the given item. - # - # @param [Nanoc::CompilationItemView] item The item to create a represetation for - # - # @param [String] path The path of the `:last` snapshot of this item representation - # @param [Symbol] rep The rep name to create - def create_rep(item, path, rep = :default) - rep = Nanoc::Int::ItemRep.new(item._unwrap, rep) - rep.paths[:last] = [path] - @reps << rep - self - end - - # @return [Object] An object that includes the helper functions - def helper - mod = @mod - klass = Class.new(Nanoc::Int::Context) { include mod } - klass.new(assigns) - end - - def item=(item) - @item = item ? item._unwrap : nil - end - - def item_rep=(item_rep) - @item_rep = item_rep ? item_rep._unwrap : nil - end - - # @return [Nanoc::MutableConfigView] - def config - assigns[:config] - end - - # @return [Nanoc::CompilationItemView, nil] - def item - assigns[:item] - end - - # @return [Nanoc::BasicItemRepView, nil] - def item_rep - assigns[:item_rep] - end - - # @return [Nanoc::ItemCollectionWithRepsView] - def items - assigns[:items] - end - - # @return [Nanoc::LayoutCollectionView] - def layouts - assigns[:layouts] - end - - def action_sequence_for(obj) - @action_sequence.fetch(obj, []) - end - - def update_action_sequence(obj, memory) - @action_sequence[obj] = memory - end - - def snapshot_repo - view_context.snapshot_repo - end - - private - - def view_context - compilation_context = - Nanoc::Int::CompilationContext.new( - action_provider: @action_provider, - reps: @reps, - site: @site, - compiled_content_cache: :__compiled_content_cache, - snapshot_repo: @snapshot_repo, - ) - - Nanoc::ViewContextForCompilation.new( - reps: @reps, - items: @items, - dependency_tracker: @dependency_tracker, - compilation_context: compilation_context, - snapshot_repo: @snapshot_repo, - ) - end - - def new_action_provider - Class.new(Nanoc::Int::ActionProvider) do - def self.for(_context) - raise NotImplementedError - end - - def initialize(context) - @context = context - end - - def rep_names_for(_item) - [:default] - end - - def action_sequence_for(obj) - @context.action_sequence_for(obj) - end - - def snapshots_defs_for(_rep) - [Nanoc::Int::SnapshotDef.new(:last, binary: false)] - end - end.new(self) - end - - def new_compiler_for(site) - Nanoc::Int::CompilerLoader.new.load(site, action_provider: @action_provider) - end - - def site - @_site ||= - Nanoc::Int::Site.new( - config: @config, - code_snippets: [], - data_source: Nanoc::Int::InMemDataSource.new(@items, @layouts), - ) - end - - def assigns - { - config: Nanoc::MutableConfigView.new(@config, view_context), - item_rep: @item_rep ? Nanoc::CompilationItemRepView.new(@item_rep, view_context) : nil, - item: @item ? Nanoc::CompilationItemView.new(@item, view_context) : nil, - items: Nanoc::ItemCollectionWithRepsView.new(@items, view_context), - layouts: Nanoc::LayoutCollectionView.new(@layouts, view_context), - _erbout: @erbout, - } - end - end - - module HelperHelper - def ctx - @_ctx ||= HelperContext.new(described_class) - end - - def helper - @_helper ||= ctx.helper - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc/version.rb nanoc-4.11.14/nanoc/lib/nanoc/version.rb --- nanoc-4.11.0/nanoc/lib/nanoc/version.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc/version.rb 2019-11-10 09:34:31.000000000 +0000 @@ -2,5 +2,5 @@ module Nanoc # The current Nanoc version. - VERSION = '4.11.0' + VERSION = '4.11.14' end diff -Nru nanoc-4.11.0/nanoc/lib/nanoc.rb nanoc-4.11.14/nanoc/lib/nanoc.rb --- nanoc-4.11.0/nanoc/lib/nanoc.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/lib/nanoc.rb 2019-11-10 09:34:31.000000000 +0000 @@ -2,39 +2,12 @@ # Load external dependencies require 'addressable' -require 'ddmemoize' -require 'ddmetrics' +require 'colored' require 'ddplugin' -require 'hamster' require 'json' -require 'json_schema' require 'parallel' -require 'ref' -require 'slow_enumerator_tools' - -DDMemoize.enable_metrics module Nanoc - # @return [String] A string containing information about this Nanoc version - # and its environment (Ruby engine and version, Rubygems version if any). - # - # @api private - def self.version_information - "Nanoc #{Nanoc::VERSION} © 2007-2018 Denis Defreyne.\n" \ - "Running #{RUBY_ENGINE} #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) on #{RUBY_PLATFORM} with RubyGems #{Gem::VERSION}.\n" - end - - # @return [Boolean] True if the current platform is Windows, false otherwise. - # - # @api private - def self.on_windows? - RUBY_PLATFORM =~ /windows|bccwin|cygwin|djgpp|mingw|mswin|wince/i - end - - # Similar to `nil` except that it can only be compared against using - # `UNDEFINED.equal?(x)`. Used in places where `nil` already has meaning, and - # thus cannot be used to mean the presence of nothing. - UNDEFINED = Object.new end # Load general requirements @@ -42,25 +15,31 @@ require 'cgi' require 'digest' require 'English' -require 'fiber' require 'fileutils' -require 'find' require 'forwardable' +require 'logger' require 'net/http' require 'net/https' require 'open3' require 'pathname' -require 'pstore' require 'set' require 'singleton' require 'stringio' require 'tempfile' require 'time' require 'timeout' -require 'tomlrb' require 'tmpdir' +require 'tty-which' require 'uri' -require 'yaml' + +# Load extracted Nanoc dependencies +require 'nanoc-core' + +# Re-export from Nanoc::Core +Nanoc::Identifier = Nanoc::Core::Identifier +Nanoc::DataSource = Nanoc::Core::DataSource +Nanoc::Filter = Nanoc::Core::Filter +Nanoc::Error = Nanoc::Core::Error # Load Nanoc require 'nanoc/version' diff -Nru nanoc-4.11.0/nanoc/LICENSE nanoc-4.11.14/nanoc/LICENSE --- nanoc-4.11.0/nanoc/LICENSE 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/LICENSE 2019-11-10 09:34:31.000000000 +0000 @@ -1,4 +1,4 @@ -Copyright (c) 2007-2018 Denis Defreyne and contributors +Copyright (c) 2007–… Denis Defreyne and contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff -Nru nanoc-4.11.0/nanoc/nanoc.gemspec nanoc-4.11.14/nanoc/nanoc.gemspec --- nanoc-4.11.0/nanoc/nanoc.gemspec 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/nanoc.gemspec 2019-11-10 09:34:31.000000000 +0000 @@ -5,7 +5,7 @@ Gem::Specification.new do |s| s.name = 'nanoc' s.version = Nanoc::VERSION - s.homepage = 'http://nanoc.ws/' + s.homepage = 'https://nanoc.ws/' s.summary = 'A static-site generator with a focus on flexibility.' s.description = 'Nanoc is a static-site generator focused on flexibility. It transforms content from a format such as Markdown or AsciiDoc into another format, usually HTML, and lays out pages consistently to retain the site’s look and feel throughout. Static sites built with Nanoc can be deployed to any web server.' @@ -13,21 +13,17 @@ s.email = 'denis+rubygems@denis.ws' s.license = 'MIT' - s.files = Dir['*.md'] + ['LICENSE'] + Dir['bin/*'] + Dir['lib/**/*.rb'] + Dir['lib/**/*-schema.json'] + s.files = Dir['*.md'] + ['LICENSE'] + Dir['bin/*'] + Dir['lib/**/*.rb'] s.executables = ['nanoc'] s.require_paths = ['lib'] s.required_ruby_version = '~> 2.4' s.add_runtime_dependency('addressable', '~> 2.5') - s.add_runtime_dependency('cri', '~> 2.15') - s.add_runtime_dependency('ddmemoize', '~> 1.0') - s.add_runtime_dependency('ddmetrics', '~> 1.0') - s.add_runtime_dependency('ddplugin', '~> 1.0') - s.add_runtime_dependency('hamster', '~> 3.0') - s.add_runtime_dependency('json_schema', '~> 0.19') + s.add_runtime_dependency('colored', '~> 1.2') + s.add_runtime_dependency('nanoc-cli', "= #{Nanoc::VERSION}") + s.add_runtime_dependency('nanoc-core', "= #{Nanoc::VERSION}") s.add_runtime_dependency('parallel', '~> 1.12') - s.add_runtime_dependency('ref', '~> 2.0') - s.add_runtime_dependency('slow_enumerator_tools', '~> 1.0') - s.add_runtime_dependency('tomlrb', '~> 1.2') + s.add_runtime_dependency('tty-command', '~> 0.8') + s.add_runtime_dependency('tty-which', '~> 0.4') end diff -Nru nanoc-4.11.0/nanoc/nanoc.manifest nanoc-4.11.14/nanoc/nanoc.manifest --- nanoc-4.11.0/nanoc/nanoc.manifest 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/nanoc.manifest 2019-11-10 09:34:31.000000000 +0000 @@ -6,140 +6,8 @@ lib/nanoc.rb lib/nanoc/base.rb -lib/nanoc/base/assertions.rb lib/nanoc/base/changes_stream.rb -lib/nanoc/base/contracts_support.rb -lib/nanoc/base/core_ext.rb -lib/nanoc/base/core_ext/array.rb -lib/nanoc/base/core_ext/hash.rb -lib/nanoc/base/core_ext/string.rb -lib/nanoc/base/entities.rb -lib/nanoc/base/entities/action_sequence.rb -lib/nanoc/base/entities/checksum_collection.rb -lib/nanoc/base/entities/code_snippet.rb -lib/nanoc/base/entities/configuration.rb -lib/nanoc/base/entities/configuration-schema.json -lib/nanoc/base/entities/content.rb -lib/nanoc/base/entities/context.rb -lib/nanoc/base/entities/dependency.rb -lib/nanoc/base/entities/directed_graph.rb -lib/nanoc/base/entities/document.rb -lib/nanoc/base/entities/identifiable_collection.rb -lib/nanoc/base/entities/identifier.rb -lib/nanoc/base/entities/item_collection.rb -lib/nanoc/base/entities/item_rep.rb -lib/nanoc/base/entities/item.rb -lib/nanoc/base/entities/layout_collection.rb -lib/nanoc/base/entities/layout.rb -lib/nanoc/base/entities/lazy_value.rb -lib/nanoc/base/entities/outdatedness_reasons.rb -lib/nanoc/base/entities/outdatedness_status.rb -lib/nanoc/base/entities/pattern.rb -lib/nanoc/base/entities/processing_action.rb -lib/nanoc/base/entities/processing_actions.rb -lib/nanoc/base/entities/processing_actions/filter.rb -lib/nanoc/base/entities/processing_actions/layout.rb -lib/nanoc/base/entities/processing_actions/snapshot.rb -lib/nanoc/base/entities/props.rb -lib/nanoc/base/entities/site.rb -lib/nanoc/base/entities/snapshot_def.rb -lib/nanoc/base/error.rb lib/nanoc/base/errors.rb -lib/nanoc/base/feature.rb -lib/nanoc/base/repos.rb -lib/nanoc/base/repos/action_sequence_store.rb -lib/nanoc/base/repos/aggregate_data_source.rb -lib/nanoc/base/repos/checksum_store.rb -lib/nanoc/base/repos/compiled_content_cache.rb -lib/nanoc/base/repos/config_loader.rb -lib/nanoc/base/repos/data_source.rb -lib/nanoc/base/repos/dependency_store.rb -lib/nanoc/base/repos/in_mem_data_source.rb -lib/nanoc/base/repos/item_rep_repo.rb -lib/nanoc/base/repos/outdatedness_store.rb -lib/nanoc/base/repos/prefixed_data_source.rb -lib/nanoc/base/repos/site_loader.rb -lib/nanoc/base/repos/snapshot_repo.rb -lib/nanoc/base/repos/store.rb -lib/nanoc/base/services.rb -lib/nanoc/base/services/action_provider.rb -lib/nanoc/base/services/action_sequence_builder.rb -lib/nanoc/base/services/checksummer.rb -lib/nanoc/base/services/compilation_context.rb -lib/nanoc/base/services/compiler_loader.rb -lib/nanoc/base/services/compiler.rb -lib/nanoc/base/services/compiler/phases.rb -lib/nanoc/base/services/compiler/phases/abstract.rb -lib/nanoc/base/services/compiler/phases/cache.rb -lib/nanoc/base/services/compiler/phases/mark_done.rb -lib/nanoc/base/services/compiler/phases/recalculate.rb -lib/nanoc/base/services/compiler/phases/resume.rb -lib/nanoc/base/services/compiler/phases/write.rb -lib/nanoc/base/services/compiler/stage.rb -lib/nanoc/base/services/compiler/stages.rb -lib/nanoc/base/services/compiler/stages/build_reps.rb -lib/nanoc/base/services/compiler/stages/calculate_checksums.rb -lib/nanoc/base/services/compiler/stages/cleanup.rb -lib/nanoc/base/services/compiler/stages/compile_reps.rb -lib/nanoc/base/services/compiler/stages/determine_outdatedness.rb -lib/nanoc/base/services/compiler/stages/forget_outdated_dependencies.rb -lib/nanoc/base/services/compiler/stages/load_stores.rb -lib/nanoc/base/services/compiler/stages/postprocess.rb -lib/nanoc/base/services/compiler/stages/preprocess.rb -lib/nanoc/base/services/compiler/stages/prune.rb -lib/nanoc/base/services/compiler/stages/store_post_compilation_state.rb -lib/nanoc/base/services/compiler/stages/store_pre_compilation_state.rb -lib/nanoc/base/services/dependency_tracker.rb -lib/nanoc/base/services/executor.rb -lib/nanoc/base/services/filter.rb -lib/nanoc/base/services/instrumentor.rb -lib/nanoc/base/services/item_rep_builder.rb -lib/nanoc/base/services/item_rep_router.rb -lib/nanoc/base/services/item_rep_selector.rb -lib/nanoc/base/services/item_rep_writer.rb -lib/nanoc/base/services/notification_center.rb -lib/nanoc/base/services/outdatedness_checker.rb -lib/nanoc/base/services/outdatedness_rule.rb -lib/nanoc/base/services/outdatedness_rules.rb -lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb -lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb -lib/nanoc/base/services/outdatedness_rules/content_modified.rb -lib/nanoc/base/services/outdatedness_rules/item_collection_extended.rb -lib/nanoc/base/services/outdatedness_rules/layout_collection_extended.rb -lib/nanoc/base/services/outdatedness_rules/not_written.rb -lib/nanoc/base/services/outdatedness_rules/rules_modified.rb -lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb -lib/nanoc/base/services/pruner.rb -lib/nanoc/base/services/temp_filename_factory.rb -lib/nanoc/base/views.rb -lib/nanoc/base/views/basic_item_rep_collection_view.rb -lib/nanoc/base/views/basic_item_rep_view.rb -lib/nanoc/base/views/basic_item_view.rb -lib/nanoc/base/views/compilation_item_rep_collection_view.rb -lib/nanoc/base/views/compilation_item_rep_view.rb -lib/nanoc/base/views/compilation_item_view.rb -lib/nanoc/base/views/config_view.rb -lib/nanoc/base/views/identifiable_collection_view.rb -lib/nanoc/base/views/item_collection_with_reps_view.rb -lib/nanoc/base/views/item_collection_without_reps_view.rb -lib/nanoc/base/views/layout_collection_view.rb -lib/nanoc/base/views/layout_view.rb -lib/nanoc/base/views/mixins/document_view_mixin.rb -lib/nanoc/base/views/mixins/mutable_document_view_mixin.rb -lib/nanoc/base/views/mutable_config_view.rb -lib/nanoc/base/views/mutable_identifiable_collection_view.rb -lib/nanoc/base/views/mutable_item_collection_view.rb -lib/nanoc/base/views/mutable_item_view.rb -lib/nanoc/base/views/mutable_layout_collection_view.rb -lib/nanoc/base/views/mutable_layout_view.rb -lib/nanoc/base/views/post_compile_item_collection_view.rb -lib/nanoc/base/views/post_compile_item_rep_collection_view.rb -lib/nanoc/base/views/post_compile_item_rep_view.rb -lib/nanoc/base/views/post_compile_item_view.rb -lib/nanoc/base/views/view_context_for_compilation.rb -lib/nanoc/base/views/view_context_for_pre_compilation.rb -lib/nanoc/base/views/view_context_for_shell.rb -lib/nanoc/base/views/view.rb lib/nanoc/checking.rb lib/nanoc/checking/check.rb lib/nanoc/checking/checks.rb @@ -154,35 +22,10 @@ lib/nanoc/checking/issue.rb lib/nanoc/checking/loader.rb lib/nanoc/checking/runner.rb -lib/nanoc/cli.rb -lib/nanoc/cli/ansi_string_colorizer.rb -lib/nanoc/cli/cleaning_stream.rb -lib/nanoc/cli/command_runner.rb -lib/nanoc/cli/commands/check.rb -lib/nanoc/cli/commands/compile_listeners/abstract.rb -lib/nanoc/cli/commands/compile_listeners/aggregate.rb -lib/nanoc/cli/commands/compile_listeners/debug_printer.rb -lib/nanoc/cli/commands/compile_listeners/diff_generator.rb -lib/nanoc/cli/commands/compile_listeners/file_action_printer.rb -lib/nanoc/cli/commands/compile_listeners/timing_recorder.rb -lib/nanoc/cli/commands/compile.rb -lib/nanoc/cli/commands/create-site.rb -lib/nanoc/cli/commands/deploy.rb -lib/nanoc/cli/commands/nanoc.rb -lib/nanoc/cli/commands/prune.rb -lib/nanoc/cli/commands/shell.rb -lib/nanoc/cli/commands/show-data.rb -lib/nanoc/cli/commands/show-plugins.rb -lib/nanoc/cli/commands/show-rules.rb -lib/nanoc/cli/commands/view.rb -lib/nanoc/cli/error_handler.rb -lib/nanoc/cli/logger.rb -lib/nanoc/cli/stack_trace_writer.rb -lib/nanoc/cli/stream_cleaners.rb -lib/nanoc/cli/stream_cleaners/abstract.rb -lib/nanoc/cli/stream_cleaners/ansi_colors.rb -lib/nanoc/cli/stream_cleaners/utf8.rb -lib/nanoc/cli/transform.rb +lib/nanoc/orig_cli.rb +lib/nanoc/orig_cli/commands/check.rb +lib/nanoc/orig_cli/commands/deploy.rb +lib/nanoc/orig_cli/commands/show-rules.rb lib/nanoc/data_sources.rb lib/nanoc/data_sources/filesystem.rb lib/nanoc/data_sources/filesystem/errors.rb @@ -200,7 +43,6 @@ lib/nanoc/extra/core_ext/time.rb lib/nanoc/extra/jruby_nokogiri_warner.rb lib/nanoc/extra/link_collector.rb -lib/nanoc/extra/piper.rb lib/nanoc/filters.rb lib/nanoc/filters/asciidoc.rb lib/nanoc/filters/asciidoctor.rb @@ -259,5 +101,4 @@ lib/nanoc/rule_dsl/rule_context.rb lib/nanoc/rule_dsl/rules_collection.rb lib/nanoc/rule_dsl/rules_loader.rb -lib/nanoc/spec.rb lib/nanoc/version.rb diff -Nru nanoc-4.11.0/nanoc/NEWS.md nanoc-4.11.14/nanoc/NEWS.md --- nanoc-4.11.0/nanoc/NEWS.md 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/NEWS.md 2019-11-10 09:34:31.000000000 +0000 @@ -1,5 +1,100 @@ # Nanoc news +## 4.11.14 (2019-11-10) + +Fixes: + +* Fixed an issue where removing and re-adding an item would not cause dependent items to be recompiled (#1463, #1464) + +## 4.11.13 (2019-11-02) + +Fixes: + +* Fixed an issue which could cause Nanoc to freeze when generating the output diff on Windows + +## 4.11.12 (2019-09-21) + +Fixes: + +* Fixed an issue with the output diff, where some hunks would not appear (#1457) + +## 4.11.11 (2019-09-07) + +Fixes: + +* Made output diff more reliable (#1455, #1456) + +## 4.11.10 (2019-08-31) + +Fixes: + +* Fixed problem with sporadic `DDMetrics::Stopwatch::AlreadyRunningError` (#1445) + +## 4.11.9 (2019-08-17) + +Enhancements: + +* Allowed specifying excluded files across all checks (#1438) +* Replace handlebars.rb with ruby-handlebars (#1443) +* Improved dependency tracking for Sass imports (#1451, #1452) [Romain Goyet] + +## 4.11.8 (2019-08-08) + +Fixes: + +* Fixed issue with `#find_all` yielding incorrect objects, causing a crash when attempting to access attributes (#1446, #1447) + +## 4.11.7 (2019-07-28) + +Fixes: + +* Fixed handling of protocol-relative URLs (#1444) + +## 4.11.6 (2019-07-06) + +Fixes: + +* Fixed crash in the `show-data` command when printing layout outdatedness (#1432) +* Fixed crash in the `view` command when host/port is not specified + +Enhancements: + +* Added `#env_name` to `@config` (#1437) +* Made the `external_links` checker detect more kinds of broken links (#1422) [Daniel Aleksandersen] +* Made the `external_links` checker shuffle the list of links (#1429) [Daniel Aleksandersen] + +## 4.11.5 (2019-04-30) + +Fixes: + +* Fixed an incompatibility introduced in Cri 2.15.4 (#1423, #1426) + +## 4.11.4 (2019-04-28) + +Fixes: + +* Fixed an issue which could cause `#compiled_content` to sometimes return compiled content that erroneously includes the layout (#1412, #1421) + +## 4.11.3 (2019-04-27) + +Enhancements: + +* Set a User-Agent for HTTP requests made by the `external_links` check (#1417) [Daniel Aleksandersen] +* Added `atom:link[type]` attributes (#1415) [Daniel Aleksandersen] +* Made the `external_links` check treat permanent redirects as errors (#1419) [Daniel Aleksandersen] + +## 4.11.2 (2019-02-16) + +Fixes: + +* Fixed issue which prevented Sass (not SCSS) files from being imported (#1397, #1407) [Alexander Groß] + +## 4.11.1 (2019-02-09) + +Fixes: + +* Fixed an issue which caused hardlinking to fail in certain situations (#1405, #1406) + ## 4.11.0 (2018-12-01) Features: @@ -1001,11 +1096,11 @@ * Added several convenience methods to view classes (#570, #572) -See the [nanoc 4 upgrade guide](http://nanoc.ws/doc/nanoc-4-upgrade-guide/) for details. +See the [nanoc 4 upgrade guide](https://nanoc.ws/doc/nanoc-4-upgrade-guide/) for details. ## 4.0.0a1 (2015-05-09) -This is a major upgrade. For details on upgrading, see the [nanoc 4 upgrade guide](http://nanoc.ws/doc/nanoc-4-upgrade-guide/). +This is a major upgrade. For details on upgrading, see the [nanoc 4 upgrade guide](https://nanoc.ws/doc/nanoc-4-upgrade-guide/). This release provides no new features, but streamlines the API and functionality, in order to easen future development, both for features and for optimisations. @@ -1171,7 +1266,7 @@ * Reduced number of dependencies generated by Sass filter (#306) [Gregory Pakosz] * Recognised lowercase `utf` in language value (e.g. `en_US.utf8`) as being UTF-8 (#335, #338) -* Set [Thin](http://code.macournoyer.com/thin/) as the default server for `nanoc view` (#342, #345) +* Set [Thin](https://github.com/macournoyer/thin) as the default server for `nanoc view` (#342, #345) * Removed watcher section from the default configuration file (#343, #344) Fixes: @@ -1189,7 +1284,7 @@ Enhancements: -* Deprecated `watch` and `autocompile` commands in favour of [`guard-nanoc`](https://github.com/nanoc/guard-nanoc) +* Deprecated `watch` and `autocompile` commands in favour of [`guard-nanoc`](https://github.com/guard/guard-nanoc) Fixes: @@ -1383,7 +1478,7 @@ * Removed bin/nanoc3 (use nanoc3 gem if you want it) * Fixed wrong “no such snapshot” errors * Made deployer default to rsync for backwards compatibility -* Fixed missing Nanoc::CLI in deployment tasks +* Fixed missing Nanoc::OrigCLI in deployment tasks * Fixed “unrecognised kind” deployer error ## 3.3.1 (2012-02-18) @@ -1536,7 +1631,7 @@ * A new “+” wildcard in rule patterns that matches one or more characters * A `view` command that starts a web server in the output directory * A `debug` command that shows information about the items, reps and layouts -* A `kramdown` filter ([kramdown site](http://kramdown.gettalong.org/)) +* A `kramdown` filter ([kramdown site](https://kramdown.gettalong.org/)) * A diff between the previously compiled content and the last compiled content is now written to `output.diff` if the `enable_output_diff` site configuration attribute is true * Assigns, such as `@items`, `@layouts`, `@item`, … are accessible without `@` * Support for binary items @@ -1664,7 +1759,7 @@ * `--no-color` command-line option * `Filtering` helper * `#relative_path_to` function in `LinkTo` helper -* `rainpress` filter ([Rainpress site](http://code.google.com/p/rainpress/)) +* `rainpress` filter ([Rainpress site](https://github.com/ddfreyne/rainpress)) * `relativize_paths` filter * The current layout is now accessible through the `@layout` variable * Much more informative stack traces when something goes wrong @@ -1718,12 +1813,12 @@ ## 2.1 (2008-08-17) This is only a short summary of all changes in 2.1. For details, see the -[nanoc web site](http://nanoc.stoneship.org/). Especially the blog and the +[nanoc web site](https://nanoc.ws/). Especially the blog and the updated manual will be useful. New: -* New `rdiscount` filter ([RDiscount site](http://github.com/rtomayko/rdiscount)) +* New `rdiscount` filter ([RDiscount site](https://github.com/davidfstr/rdiscount)) * New `maruku` filter ([Maruku site](https://github.com/bhollis/maruku/)) * New `erubis` filter ([Erubis site](http://www.kuwata-lab.com/erubis/)) * A better command-line frontend diff -Nru nanoc-4.11.0/nanoc/README.md nanoc-4.11.14/nanoc/README.md --- nanoc-4.11.0/nanoc/README.md 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/README.md 2019-11-10 09:34:31.000000000 +0000 @@ -2,4 +2,4 @@ # Nanoc -Nanoc is a flexible static-site generator written in Ruby. See the [Nanoc web site](http://nanoc.ws) for more information. +Nanoc is a flexible static-site generator written in Ruby. See the [Nanoc web site](https://nanoc.ws) for more information. diff -Nru nanoc-4.11.0/nanoc/spec/contributors_spec.rb nanoc-4.11.14/nanoc/spec/contributors_spec.rb --- nanoc-4.11.0/nanoc/spec/contributors_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/contributors_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -9,12 +9,12 @@ File.read('NEWS.md').scan(/\[[^\]]+\]$/).map { |s| s[1..-2].split(', ') }.flatten end - it 'should include everyone mentioned in NEWS.md' do + it 'includes everyone mentioned in NEWS.md' do diff = (contributors_in_release_notes - contributors_in_readme).uniq.sort expect(diff).to be_empty, "some contributors are missing from the README: #{diff.join(', ')}" end - it 'should be sorted' do + it 'is sorted' do expect(contributors_in_readme).to be_humanly_sorted end end diff -Nru nanoc-4.11.0/nanoc/spec/gem_spec.rb nanoc-4.11.14/nanoc/spec/gem_spec.rb --- nanoc-4.11.0/nanoc/spec/gem_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/gem_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,17 +1,16 @@ # frozen_string_literal: true describe 'nanoc.gem', chdir: false, stdio: true do + subject do + TTY::Command.new.run('gem build nanoc.gemspec') + end + around do |ex| Dir['*.gem'].each { |f| FileUtils.rm(f) } ex.run Dir['*.gem'].each { |f| FileUtils.rm(f) } end - subject do - piper = Nanoc::Extra::Piper.new(stdout: $stdout, stderr: $stderr) - piper.run(%w[gem build nanoc.gemspec], nil) - end - it 'builds gem' do expect { subject } .to change { Dir['*.gem'] } diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/checksummer_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/checksummer_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/checksummer_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/checksummer_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,419 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Checksummer::VerboseDigest do - let(:digest) { described_class.new } - - it 'concatenates' do - digest.update('foo') - digest.update('bar') - expect(digest.to_s).to eql('foobar') - end -end - -describe Nanoc::Int::Checksummer::CompactDigest do - let(:digest) { described_class.new } - - it 'uses SHA1 and Base64' do - digest.update('foo') - digest.update('bar') - expect(digest.to_s).to eql(Digest::SHA1.base64digest('foobar')) - end -end - -describe Nanoc::Int::Checksummer do - subject { described_class.calc(obj, Nanoc::Int::Checksummer::VerboseDigest) } - - describe '.calc_for_each_attribute_of' do - let(:obj) { Nanoc::Int::Item.new('asdf', { 'foo' => 'bar' }, '/foo.md') } - - context 'compact' do - subject do - described_class.calc_for_each_attribute_of(obj) - end - - it { is_expected.to have_key(:foo) } - end - - context 'verbose' do - subject do - described_class.calc_for_each_attribute_of(obj, Nanoc::Int::Checksummer::VerboseDigest) - end - - it { is_expected.to eq(foo: 'String') } - end - end - - context 'String' do - let(:obj) { 'hello' } - it { is_expected.to eql('String') } - end - - context 'Symbol' do - let(:obj) { :hello } - it { is_expected.to eql('Symbol') } - end - - context 'nil' do - let(:obj) { nil } - it { is_expected.to eql('NilClass<>') } - end - - context 'true' do - let(:obj) { true } - it { is_expected.to eql('TrueClass<>') } - end - - context 'false' do - let(:obj) { false } - it { is_expected.to eql('FalseClass<>') } - end - - context 'Array' do - let(:obj) { %w[hello goodbye] } - it { is_expected.to eql('Array,String,>') } - - context 'different order' do - let(:obj) { %w[goodbye hello] } - it { is_expected.to eql('Array,String,>') } - end - - context 'recursive' do - let(:obj) { [].tap { |arr| arr << ['hello', arr] } } - it { is_expected.to eql('Array,Array,>,>') } - end - - context 'non-serializable' do - let(:obj) { [-> {}] } - it { is_expected.to match(/\AArray>,>\z/) } - end - end - - context 'Hash' do - let(:obj) { { 'a' => 'foo', 'b' => 'bar' } } - it { is_expected.to eql('Hash=String,String=String,>') } - - context 'different order' do - let(:obj) { { 'b' => 'bar', 'a' => 'foo' } } - it { is_expected.to eql('Hash=String,String=String,>') } - end - - context 'non-serializable' do - let(:obj) { { 'a' => -> {} } } - it { is_expected.to match(/\AHash=Proc<#>,>\z/) } - end - - context 'recursive values' do - let(:obj) { {}.tap { |hash| hash['a'] = hash } } - it { is_expected.to eql('Hash=Hash,>') } - end - - context 'recursive keys' do - let(:obj) { {}.tap { |hash| hash[hash] = 'hello' } } - it { is_expected.to eql('Hash=String,>') } - end - end - - context 'Pathname' do - let(:obj) { ::Pathname.new(filename) } - - let(:filename) { '/tmp/whatever' } - let(:mtime) { 200 } - let(:data) { 'stuffs' } - - before do - FileUtils.mkdir_p(File.dirname(filename)) - File.write(filename, data) - File.utime(mtime, mtime, filename) - end - - it { is_expected.to eql('Pathname<6-200>') } - - context 'does not exist' do - before do - FileUtils.rm_rf(filename) - end - - it { is_expected.to eql('Pathname') } - end - - context 'different data' do - let(:data) { 'other stuffs :o' } - it { is_expected.to eql('Pathname<15-200>') } - end - end - - context 'Time' do - let(:obj) { Time.at(111_223) } - it { is_expected.to eql('Time<111223>') } - end - - context 'Float' do - let(:obj) { 3.14 } - it { is_expected.to eql('Float<3.14>') } - end - - context 'Fixnum/Integer' do - let(:obj) { 3 } - it { is_expected.to match(/\A(Integer|Fixnum)<3>\z/) } - end - - context 'Nanoc::Identifier' do - let(:obj) { Nanoc::Identifier.new('/foo.md') } - it { is_expected.to eql('Nanoc::Identifier>') } - end - - context 'Nanoc::RuleDSL::RulesCollection' do - let(:obj) do - Nanoc::RuleDSL::RulesCollection.new.tap { |rc| rc.data = data } - end - - let(:data) { 'STUFF!' } - - it { is_expected.to eql('Nanoc::RuleDSL::RulesCollection>') } - end - - context 'Nanoc::Int::CodeSnippet' do - let(:obj) { Nanoc::Int::CodeSnippet.new('asdf', '/bob.rb') } - it { is_expected.to eql('Nanoc::Int::CodeSnippet>') } - end - - context 'Nanoc::Int::Configuration' do - let(:obj) { Nanoc::Int::Configuration.new(dir: Dir.getwd, hash: { 'foo' => 'bar' }) } - it { is_expected.to eql('Nanoc::Int::Configuration=String,>') } - end - - context 'Nanoc::Int::Item' do - let(:obj) { Nanoc::Int::Item.new('asdf', { 'foo' => 'bar' }, '/foo.md') } - - it { is_expected.to eql('Nanoc::Int::Item>,attributes=Hash=String,>,identifier=Nanoc::Identifier>>') } - - context 'binary' do - let(:filename) { File.expand_path('foo.dat') } - let(:content) { Nanoc::Int::BinaryContent.new(filename) } - let(:obj) { Nanoc::Int::Item.new(content, { 'foo' => 'bar' }, '/foo.md') } - - let(:mtime) { 200 } - let(:data) { 'stuffs' } - - before do - File.write(content.filename, data) - File.utime(mtime, mtime, content.filename) - end - - it { is_expected.to eql('Nanoc::Int::Item>,attributes=Hash=String,>,identifier=Nanoc::Identifier>>') } - end - - context 'recursive attributes' do - before do - obj.attributes[:foo] = obj - end - - it { is_expected.to eql('Nanoc::Int::Item>,attributes=Hash=Nanoc::Int::Item,>,identifier=Nanoc::Identifier>>') } - end - - context 'with checksum' do - let(:obj) { Nanoc::Int::Item.new('asdf', { 'foo' => 'bar' }, '/foo.md', checksum_data: 'abcdef') } - - it { is_expected.to eql('Nanoc::Int::Item') } - end - - context 'with content checksum' do - let(:obj) { Nanoc::Int::Item.new('asdf', { 'foo' => 'bar' }, '/foo.md', content_checksum_data: 'con-cs') } - - it { is_expected.to eql('Nanoc::Int::Item=String,>,identifier=Nanoc::Identifier>>') } - end - - context 'with attributes checksum' do - let(:obj) { Nanoc::Int::Item.new('asdf', { 'foo' => 'bar' }, '/foo.md', attributes_checksum_data: 'attr-cs') } - - it { is_expected.to eql('Nanoc::Int::Item>,attributes_checksum_data=attr-cs,identifier=Nanoc::Identifier>>') } - end - end - - context 'Nanoc::Int::Layout' do - let(:obj) { Nanoc::Int::Layout.new('asdf', { 'foo' => 'bar' }, '/foo.md') } - - it { is_expected.to eql('Nanoc::Int::Layout>,attributes=Hash=String,>,identifier=Nanoc::Identifier>>') } - - context 'recursive attributes' do - before do - obj.attributes[:foo] = obj - end - - it { is_expected.to eql('Nanoc::Int::Layout>,attributes=Hash=Nanoc::Int::Layout,>,identifier=Nanoc::Identifier>>') } - end - - context 'with checksum' do - let(:obj) { Nanoc::Int::Layout.new('asdf', { 'foo' => 'bar' }, '/foo.md', checksum_data: 'abcdef') } - - it { is_expected.to eql('Nanoc::Int::Layout') } - end - end - - context 'Nanoc::CompilationItemView' do - let(:obj) { Nanoc::CompilationItemView.new(item, nil) } - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') } - - it { is_expected.to eql('Nanoc::CompilationItemView>,attributes=Hash<>,identifier=Nanoc::Identifier>>>') } - end - - context 'Nanoc::Int::ItemRep' do - let(:obj) { Nanoc::Int::ItemRep.new(item, :pdf) } - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') } - - it { is_expected.to eql('Nanoc::Int::ItemRep>,attributes=Hash<>,identifier=Nanoc::Identifier>>,name=Symbol>') } - end - - context 'Nanoc::BasicItemRepView' do - let(:obj) { Nanoc::BasicItemRepView.new(rep, :_unused_context) } - let(:rep) { Nanoc::Int::ItemRep.new(item, :pdf) } - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') } - - it { is_expected.to eql('Nanoc::BasicItemRepView>,attributes=Hash<>,identifier=Nanoc::Identifier>>,name=Symbol>>') } - end - - context 'Nanoc::CompilationItemRepView' do - let(:obj) { Nanoc::CompilationItemRepView.new(rep, :_unused_context) } - let(:rep) { Nanoc::Int::ItemRep.new(item, :pdf) } - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') } - - it { is_expected.to eql('Nanoc::CompilationItemRepView>,attributes=Hash<>,identifier=Nanoc::Identifier>>,name=Symbol>>') } - end - - context 'Nanoc::BasicItemView' do - let(:obj) { Nanoc::BasicItemView.new(item, nil) } - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') } - - it { is_expected.to eql('Nanoc::BasicItemView>,attributes=Hash<>,identifier=Nanoc::Identifier>>>') } - end - - context 'Nanoc::LayoutView' do - let(:obj) { Nanoc::LayoutView.new(layout, nil) } - let(:layout) { Nanoc::Int::Layout.new('asdf', {}, '/foo.md') } - - it { is_expected.to eql('Nanoc::LayoutView>,attributes=Hash<>,identifier=Nanoc::Identifier>>>') } - end - - context 'Nanoc::ConfigView' do - let(:obj) { Nanoc::ConfigView.new(config, nil) } - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd, hash: { 'foo' => 'bar' }) } - - it { is_expected.to eql('Nanoc::ConfigView=String,>>') } - end - - context 'Nanoc::ItemCollectionWithRepsView' do - let(:obj) { Nanoc::ItemCollectionWithRepsView.new(wrapped, nil) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd, hash: { 'foo' => 'bar' }) } - - let(:wrapped) do - Nanoc::Int::ItemCollection.new( - config, - [ - Nanoc::Int::Item.new('foo', {}, '/foo.md'), - Nanoc::Int::Item.new('bar', {}, '/foo.md'), - ], - ) - end - - it { is_expected.to eql('Nanoc::ItemCollectionWithRepsView>,attributes=Hash<>,identifier=Nanoc::Identifier>>,Nanoc::Int::Item>,attributes=Hash<>,identifier=Nanoc::Identifier>>,>>') } - end - - context 'Nanoc::ItemCollectionWithoutRepsView' do - let(:obj) { Nanoc::ItemCollectionWithoutRepsView.new(wrapped, nil) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd, hash: { 'foo' => 'bar' }) } - - let(:wrapped) do - Nanoc::Int::ItemCollection.new( - config, - [ - Nanoc::Int::Item.new('foo', {}, '/foo.md'), - Nanoc::Int::Item.new('bar', {}, '/foo.md'), - ], - ) - end - - it { is_expected.to eql('Nanoc::ItemCollectionWithoutRepsView>,attributes=Hash<>,identifier=Nanoc::Identifier>>,Nanoc::Int::Item>,attributes=Hash<>,identifier=Nanoc::Identifier>>,>>') } - end - - context 'Nanoc::RuleDSL::CompilationRuleContext' do - let(:obj) { Nanoc::RuleDSL::CompilationRuleContext.new(rep: rep, site: site, recorder: recorder, view_context: view_context) } - - let(:rep) { Nanoc::Int::ItemRep.new(item, :pdf) } - let(:item) { Nanoc::Int::Item.new('stuff', {}, '/stuff.md') } - - let(:site) do - Nanoc::Int::Site.new( - config: config, - code_snippets: code_snippets, - data_source: Nanoc::Int::InMemDataSource.new(items, layouts), - ) - end - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd, hash: { 'foo' => 'bar' }) } - let(:code_snippets) { [Nanoc::Int::CodeSnippet.new('asdf', '/bob.rb')] } - let(:items) { Nanoc::Int::ItemCollection.new(config, [item]) } - let(:layouts) { [Nanoc::Int::Layout.new('asdf', {}, '/foo.md')] } - - let(:recorder) { Nanoc::RuleDSL::ActionRecorder.new(rep) } - let(:view_context) { Nanoc::ViewContextForPreCompilation.new(items: items) } - - let(:expected_item_checksum) { 'Nanoc::Int::Item>,attributes=Hash<>,identifier=Nanoc::Identifier>>' } - let(:expected_item_rep_checksum) { 'Nanoc::Int::ItemRep>' } - let(:expected_layout_checksum) { 'Nanoc::Int::Layout>,attributes=Hash<>,identifier=Nanoc::Identifier>>' } - let(:expected_config_checksum) { 'Nanoc::Int::Configuration=String,>' } - - let(:expected_checksum) do - [ - 'Nanoc::RuleDSL::CompilationRuleContext<', - 'item=', - 'Nanoc::BasicItemView<' + expected_item_checksum + '>', - ',rep=', - 'Nanoc::BasicItemRepView<' + expected_item_rep_checksum + '>', - ',items=', - 'Nanoc::ItemCollectionWithoutRepsView>', - ',layouts=', - 'Nanoc::LayoutCollectionView>', - ',config=', - 'Nanoc::ConfigView<' + expected_config_checksum + '>', - '>', - ].join('') - end - - it { is_expected.to eql(expected_checksum) } - end - - context 'Nanoc::Int::Context' do - let(:obj) { Nanoc::Int::Context.new(foo: 123) } - - it { is_expected.to match(/\ANanoc::Int::Context<@foo=(Fixnum|Integer)<123>,>\z/) } - end - - context 'Sass::Importers::Filesystem' do - let(:obj) { Sass::Importers::Filesystem.new('/foo') } - - before { require 'sass' } - - it { is_expected.to match(%r{\ASass::Importers::Filesystem\z}) } - end - - context 'other marshal-able classes' do - let(:obj) { klass.new('hello') } - - let(:klass) do - Class.new do - def initialize(arg) - @arg = arg - end - end - end - - it { is_expected.to match(/\A#<.*>\z/) } - end - - context 'other non-marshal-able classes' do - let(:obj) { proc {} } - it { is_expected.to match(/\AProc<#>\z/) } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/compiler_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/compiler_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/compiler_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/compiler_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Compiler do - let(:compiler) do - described_class.new( - site, - compiled_content_cache: compiled_content_cache, - checksum_store: checksum_store, - action_sequence_store: action_sequence_store, - action_provider: action_provider, - dependency_store: dependency_store, - outdatedness_store: outdatedness_store, - ) - end - - let(:checksum_store) { Nanoc::Int::ChecksumStore.new(config: config, objects: items) } - let(:action_sequence_store) { Nanoc::Int::ActionSequenceStore.new(config: config) } - - let(:dependency_store) { Nanoc::Int::DependencyStore.new(items, layouts, config) } - - let(:outdatedness_store) { Nanoc::Int::OutdatednessStore.new(config: config) } - let(:action_provider) { double(:action_provider) } - - let(:compiled_content_cache) do - Nanoc::Int::CompiledContentCache.new(config: config) - end - - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } - let(:item) { Nanoc::Int::Item.new('<%= 1 + 2 %>', {}, '/hi.md') } - - let(:other_rep) { Nanoc::Int::ItemRep.new(other_item, :default) } - let(:other_item) { Nanoc::Int::Item.new('other content', {}, '/other.md') } - - let(:site) do - Nanoc::Int::Site.new( - config: config, - code_snippets: code_snippets, - data_source: Nanoc::Int::InMemDataSource.new(items, layouts), - ) - end - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - let(:code_snippets) { [] } - - let(:items) do - Nanoc::Int::ItemCollection.new(config, [item, other_item]) - end - - let(:layouts) do - Nanoc::Int::LayoutCollection.new(config) - end - - let(:memory) do - actions = - [ - Nanoc::Int::ProcessingActions::Filter.new(:erb, {}), - Nanoc::Int::ProcessingActions::Snapshot.new([:last], []), - ] - - Nanoc::Int::ActionSequence.new(nil, actions: actions) - end - - let(:action_sequences) do - { rep => memory, other_rep => memory } - end - - before do - allow(Nanoc::Int::NotificationCenter).to receive(:post) - end - - describe '#compile_rep' do - let(:stage) { compiler.send(:compile_reps_stage, action_sequences, reps) } - - subject { stage.send(:compile_rep, rep, phase_stack: phase_stack, is_outdated: is_outdated) } - - let(:is_outdated) { true } - let(:phase_stack) { stage.send(:build_phase_stack) } - - let(:reps) do - Nanoc::Int::ItemRepRepo.new.tap do |rs| - rs << rep - rs << other_rep - - rs.each do |rep| - rep.snapshot_defs << Nanoc::Int::SnapshotDef.new(:last, binary: false) - end - end - end - - it 'generates expected output' do - reps = Nanoc::Int::ItemRepRepo.new - expect { subject } - .to change { compiler.compilation_context(reps: reps).snapshot_repo.get(rep, :last) } - .from(nil) - .to(some_textual_content('3')) - end - - it 'generates notifications in the proper order' do - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:compilation_started, rep).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:filtering_started, rep, :erb).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:filtering_ended, rep, :erb).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:compilation_ended, rep).ordered - - subject - end - - context 'interrupted compilation' do - let(:item) { Nanoc::Int::Item.new('other=<%= @items["/other.*"].compiled_content %>', {}, '/hi.md') } - - it 'generates expected output' do - reps = Nanoc::Int::ItemRepRepo.new - expect(compiler.compilation_context(reps: reps).snapshot_repo.get(rep, :last)).to be_nil - - expect { stage.send(:compile_rep, rep, phase_stack: phase_stack, is_outdated: true) } - .to raise_error(Nanoc::Int::Errors::UnmetDependency) - stage.send(:compile_rep, other_rep, phase_stack: phase_stack, is_outdated: true) - stage.send(:compile_rep, rep, phase_stack: phase_stack, is_outdated: true) - - expect(compiler.compilation_context(reps: reps).snapshot_repo.get(rep, :last).string).to eql('other=other content') - end - - it 'generates notifications in the proper order' do - # rep 1 - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:compilation_started, rep).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:filtering_started, rep, :erb).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:dependency_created, item, other_item).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:compilation_suspended, rep, anything).ordered - - # rep 2 - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:compilation_started, other_rep).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:filtering_started, other_rep, :erb).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:filtering_ended, other_rep, :erb).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:compilation_ended, other_rep).ordered - - # rep 1 (again) - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:compilation_started, rep).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:filtering_ended, rep, :erb).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:compilation_ended, rep).ordered - - expect { stage.send(:compile_rep, rep, phase_stack: phase_stack, is_outdated: true) } - .to raise_error(Nanoc::Int::Errors::UnmetDependency) - stage.send(:compile_rep, other_rep, phase_stack: phase_stack, is_outdated: true) - stage.send(:compile_rep, rep, phase_stack: phase_stack, is_outdated: true) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/core_ext/array_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/core_ext/array_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/core_ext/array_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/core_ext/array_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -describe 'Array#__nanoc_symbolize_keys_recursively' do - it 'should convert keys to symbols' do - array_old = [:abc, 'xyz', { 'foo' => 'bar', :baz => :qux }] - array_new = [:abc, 'xyz', { foo: 'bar', baz: :qux }] - expect(array_old.__nanoc_symbolize_keys_recursively).to eql(array_new) - end -end - -describe 'Array#__nanoc_stringify_keys_recursively' do - it 'should convert keys to strings' do - array_old = [:abc, 'xyz', { 'foo' => 'bar', baz: :qux }] - array_new = [:abc, 'xyz', { 'foo' => 'bar', 'baz' => :qux }] - expect(array_old.__nanoc_stringify_keys_recursively).to eql(array_new) - end -end - -describe 'Array#__nanoc_freeze_recursively' do - it 'should prevent first-level elements from being modified' do - array = [:a, %i[b c], :d] - array.__nanoc_freeze_recursively - - expect { array[0] = 123 }.to raise_frozen_error - end - - it 'should prevent second-level elements from being modified' do - array = [:a, %i[b c], :d] - array.__nanoc_freeze_recursively - - expect { array[1][0] = 123 }.to raise_frozen_error - end - - it 'should not freeze infinitely' do - a = [] - a << a - - a.__nanoc_freeze_recursively - - expect(a).to be_frozen - expect(a[0]).to be_frozen - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/core_ext/hash_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/core_ext/hash_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/core_ext/hash_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/core_ext/hash_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -# frozen_string_literal: true - -describe 'Hash#__nanoc_symbolize_keys_recursively' do - it 'should convert keys to symbols' do - hash_old = { 'foo' => 'bar' } - hash_new = { foo: 'bar' } - expect(hash_old.__nanoc_symbolize_keys_recursively).to eql(hash_new) - end - - it 'should not require string keys' do - hash_old = { Time.now => 'abc' } - hash_new = hash_old - expect(hash_old.__nanoc_symbolize_keys_recursively).to eql(hash_new) - end -end - -describe 'Hash#__nanoc_stringify_keys_recursively' do - it 'should convert keys to strings' do - hash_old = { foo: 'bar' } - hash_new = { 'foo' => 'bar' } - expect(hash_old.__nanoc_stringify_keys_recursively).to eql(hash_new) - end - - it 'should not require symbol keys' do - hash_old = { Time.now => 'abc' } - hash_new = hash_old - expect(hash_old.__nanoc_stringify_keys_recursively).to eql(hash_new) - end -end - -describe 'Hash#__nanoc_freeze_recursively' do - it 'should prevent first-level elements from being modified' do - hash = { a: { b: :c } } - hash.__nanoc_freeze_recursively - - expect { hash[:a] = 123 }.to raise_frozen_error - end - - it 'should prevent second-level elements from being modified' do - hash = { a: { b: :c } } - hash.__nanoc_freeze_recursively - - expect { hash[:a][:b] = 123 }.to raise_frozen_error - end - - it 'should not freeze infinitely' do - a = {} - a[:x] = a - - a.__nanoc_freeze_recursively - - expect(a).to be_frozen - expect(a[0]).to be_frozen - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/core_ext/string_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/core_ext/string_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/core_ext/string_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/core_ext/string_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -describe 'String#__nanoc_cleaned_identifier' do - it 'should not convert already clean paths' do - expect('/foo/bar/'.__nanoc_cleaned_identifier).to eql('/foo/bar/') - end - - it 'should prepend slash if necessary' do - expect('foo/bar/'.__nanoc_cleaned_identifier).to eql('/foo/bar/') - end - - it 'should append slash if necessary' do - expect('/foo/bar'.__nanoc_cleaned_identifier).to eql('/foo/bar/') - end - - it 'should remove double slashes at start' do - expect('//foo/bar/'.__nanoc_cleaned_identifier).to eql('/foo/bar/') - end - - it 'should remove double slashes at end' do - expect('/foo/bar//'.__nanoc_cleaned_identifier).to eql('/foo/bar/') - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/directed_graph_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/directed_graph_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/directed_graph_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/directed_graph_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,258 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::DirectedGraph do - subject(:graph) { described_class.new(%w[1 2 3]) } - - describe '#edges' do - subject { graph.edges } - - context 'empty graph' do - it { is_expected.to be_empty } - end - - context 'graph with vertices, but no edges' do - before do - graph.add_vertex('1') - graph.add_vertex('2') - end - - it { is_expected.to be_empty } - end - - context 'graph with edges from previously added vertices' do - before do - graph.add_vertex('1') - graph.add_vertex('2') - graph.add_vertex('3') - - graph.add_edge('1', '2') - graph.add_edge('1', '3') - end - - it { is_expected.to match_array([[0, 1, nil], [0, 2, nil]]) } - end - - context 'graph with edges from new vertices' do - before do - graph.add_edge('1', '2') - graph.add_edge('1', '3') - end - - it { is_expected.to match_array([[0, 1, nil], [0, 2, nil]]) } - end - - context 'graph with edge props' do - before do - graph.add_edge('1', '2', props: { name: 'Mr. C' }) - graph.add_edge('1', '3', props: { name: 'Cooper' }) - end - - it { is_expected.to match_array([[0, 1, { name: 'Mr. C' }], [0, 2, { name: 'Cooper' }]]) } - end - end - - it 'has correct examples' do - expect('Nanoc::Int::DirectedGraph') - .to have_correct_yard_examples - .in_file('nanoc/lib/nanoc/base/entities/directed_graph.rb') - end - - describe '#vertices' do - subject { graph.vertices } - - it { is_expected.to include('1') } - it { is_expected.not_to include('4') } - end - - describe '#add_edge' do - subject { graph.add_edge('1', '4') } - - it 'adds vertex' do - expect { subject } - .to change { graph.vertices.include?('4') } - .from(false) - .to(true) - end - - it 'changes direct predecessors' do - expect { subject } - .to change { graph.direct_predecessors_of('4') } - .from([]) - .to(['1']) - end - end - - describe '#props_for' do - subject { graph.props_for('1', '2') } - - context 'no edge' do - it { is_expected.to be_nil } - end - - context 'edge, but no props' do - before { graph.add_edge('1', '2') } - it { is_expected.to be_nil } - end - - context 'edge with props' do - before { graph.add_edge('1', '2', props: { name: 'Mr. C' }) } - it { is_expected.to eq(name: 'Mr. C') } - - context 'deleted edge (#delete_edges_to)' do - before { graph.delete_edges_to('2') } - it { is_expected.to be_nil } - end - end - end - - describe '#direct_predecessors_of' do - subject { graph.direct_predecessors_of('2') } - - context 'no edges' do - it { is_expected.to be_empty } - end - - context 'requested for non-existant vertex' do - subject { graph.direct_predecessors_of('12345') } - - it { is_expected.to be_empty } - it { is_expected.to be_a(Set) } - end - - context 'one edge to' do - before { graph.add_edge('1', '2') } - - it { is_expected.to match_array(['1']) } - it { is_expected.to be_a(Set) } - end - - context 'two edges to' do - before do - graph.add_edge('1', '2') - graph.add_edge('3', '2') - end - - it { is_expected.to match_array(%w[1 3]) } - it { is_expected.to be_a(Set) } - end - - context 'edge from' do - before { graph.add_edge('2', '3') } - - it { is_expected.to be_empty } - it { is_expected.to be_a(Set) } - end - end - - describe '#predecessors_of' do - subject { graph.predecessors_of('2') } - - context 'requested for non-existant vertex' do - subject { graph.predecessors_of('12345') } - - it { is_expected.to be_empty } - it { is_expected.to be_a(Set) } - end - - context 'no predecessors' do - before do - graph.add_edge('2', '3') - end - - it { is_expected.to be_empty } - end - - context 'direct predecessor' do - before do - graph.add_edge('2', '3') - graph.add_edge('1', '2') - end - - context 'no indirect predecessors' do - it { is_expected.to match_array(['1']) } - end - - context 'indirect predecessors' do - before { graph.add_edge('3', '1') } - it { is_expected.to match_array(%w[1 2 3]) } - end - end - end - - describe '#delete_edges_to' do - before do - graph.add_edge('1', '2') - graph.add_edge('2', '1') - graph.add_edge('2', '3') - graph.add_edge('3', '2') - graph.add_edge('1', '3') - graph.add_edge('3', '1') - end - - subject { graph.delete_edges_to('1') } - - it 'deletes edges to 1' do - expect { subject } - .to change { graph.direct_predecessors_of('1') } - .from(%w[2 3]) - .to([]) - end - - it 'keeps edges to 2' do - expect { subject } - .not_to change { graph.direct_predecessors_of('2') } - end - - it 'keeps edges to 3' do - expect { subject } - .not_to change { graph.direct_predecessors_of('3') } - end - - it 'keeps edges to 4' do - expect { subject } - .not_to change { graph.direct_predecessors_of('4') } - end - end - - describe '#inspect' do - subject { graph.inspect } - - context 'empty graph' do - it { is_expected.to eq('Nanoc::Int::DirectedGraph()') } - end - - context 'one edge, no props' do - before do - graph.add_edge('1', '2') - end - - it { is_expected.to eq('Nanoc::Int::DirectedGraph("1" -> "2" props=nil)') } - end - - context 'two edges, no props' do - before do - graph.add_edge('1', '2') - graph.add_edge('2', '3') - end - - it { is_expected.to eq('Nanoc::Int::DirectedGraph("1" -> "2" props=nil, "2" -> "3" props=nil)') } - end - - context 'one edge, props' do - before do - graph.add_edge('1', '2', props: 'giraffe') - end - - it { is_expected.to eq('Nanoc::Int::DirectedGraph("1" -> "2" props="giraffe")') } - end - - context 'two edges, props' do - before do - graph.add_edge('1', '2', props: 'donkey') - graph.add_edge('2', '3', props: 'zebra') - end - - it { is_expected.to eq('Nanoc::Int::DirectedGraph("1" -> "2" props="donkey", "2" -> "3" props="zebra")') } - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/action_sequence_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/action_sequence_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/action_sequence_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/action_sequence_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,297 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::ActionSequence do - let(:action_sequence) { raise 'override me' } - - let(:item) { Nanoc::Int::Item.new('foo', {}, '/foo.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } - - describe '#size' do - subject { action_sequence.size } - - context 'no actions' do - let(:action_sequence) do - described_class.build(rep) do |b| - end - end - - it { is_expected.to eql(0) } - end - - context 'some actions' do - let(:action_sequence) do - described_class.build(rep) do |b| - b.add_filter(:foo, {}) - end - end - - it { is_expected.to eql(1) } - end - end - - describe '#[]' do - subject { action_sequence[index] } - let(:index) { 0 } - - context 'no actions' do - let(:action_sequence) do - described_class.build(rep) do |b| - end - end - - it { is_expected.to be_nil } - end - - context 'some actions' do - let(:action_sequence) do - described_class.build(rep) do |b| - b.add_filter(:foo, {}) - end - end - - it { is_expected.to be_a(Nanoc::Int::ProcessingActions::Filter) } - end - end - - describe '#add_filter' do - let(:action_sequence) do - described_class.build(rep) do |b| - b.add_filter(:foo, donkey: 123) - end - end - - example do - expect(action_sequence.size).to eql(1) - expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Filter) - expect(action_sequence[0].filter_name).to eql(:foo) - expect(action_sequence[0].params).to eql(donkey: 123) - end - end - - describe '#add_layout' do - let(:action_sequence) do - described_class.build(rep) do |b| - b.add_layout('/foo.*', donkey: 123) - end - end - - example do - expect(action_sequence.size).to eql(1) - expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Layout) - expect(action_sequence[0].layout_identifier).to eql('/foo.*') - expect(action_sequence[0].params).to eql(donkey: 123) - end - end - - describe '#add_snapshot' do - context 'snapshot does not yet exist' do - let(:action_sequence) do - described_class.build(rep) do |b| - b.add_snapshot(:before_layout, '/foo.md') - end - end - - example do - expect(action_sequence.size).to eql(1) - expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) - expect(action_sequence[0].snapshot_names).to eql([:before_layout]) - expect(action_sequence[0].paths).to eql(['/foo.md']) - end - end - - context 'snapshot already exist' do - it 'raises' do - described_class.build(rep) do |b| - b.add_snapshot(:before_layout, '/bar.md') - expect { b.add_snapshot(:before_layout, '/foo.md') } - .to raise_error(Nanoc::Int::Errors::CannotCreateMultipleSnapshotsWithSameName) - end - end - end - end - - describe '#each' do - let(:action_sequence) do - described_class.build(rep) do |b| - b.add_filter(:erb, awesomeness: 'high') - b.add_snapshot(:bar, '/foo.md') - b.add_layout('/default.erb', somelayoutparam: 'yes') - end - end - - example do - actions = [] - action_sequence.each { |a| actions << a } - expect(actions.size).to eq(3) - end - end - - describe '#map' do - let(:action_sequence) do - described_class.build(rep) do |b| - b.add_filter(:erb, awesomeness: 'high') - b.add_snapshot(:bar, '/foo.md') - b.add_layout('/default.erb', somelayoutparam: 'yes') - end - end - - example do - res = action_sequence.map { Nanoc::Int::ProcessingActions::Filter.new(:donkey, {}) } - expect(res.to_a.size).to eq(3) - expect(res.to_a).to all(be_a(Nanoc::Int::ProcessingActions::Filter)) - end - end - - describe '#serialize' do - subject { action_sequence.serialize } - - let(:action_sequence) do - described_class.build(rep) do |b| - b.add_filter(:erb, awesomeness: 'high') - b.add_snapshot(:bar, '/foo.md') - b.add_layout('/default.erb', somelayoutparam: 'yes') - end - end - - example do - expect(subject).to eql( - [ - [:filter, :erb, 'PeWUm2PtXYtqeHJdTqnY7kkwAow='], - [:snapshot, [:bar], true, ['/foo.md']], - [:layout, '/default.erb', '97LAe1pYTLKczxBsu+x4MmvqdkU='], - ], - ) - end - end - - describe '#snapshots_defs' do - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } - - Class.new(Nanoc::Filter) do - identifier :RuleMemSpec_filter_b2b - type :binary => :binary # rubocop:disable Style/HashSyntax - - def run(content, params = {}); end - end - - Class.new(Nanoc::Filter) do - identifier :RuleMemSpec_filter_b2t - type :binary => :text # rubocop:disable Style/HashSyntax - - def run(content, params = {}); end - end - - Class.new(Nanoc::Filter) do - identifier :RuleMemSpec_filter_t2t - type :text => :text # rubocop:disable Style/HashSyntax - - def run(content, params = {}); end - end - - Class.new(Nanoc::Filter) do - identifier :RuleMemSpec_filter_t2b - type :text => :binary # rubocop:disable Style/HashSyntax - - def run(content, params = {}); end - end - - it 'has no snapshot defs by default' do - action_sequence = - described_class.build(rep) do |b| - end - - expect(action_sequence.snapshots_defs).to be_empty - end - - context 'textual item' do - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') } - - it 'generates initial textual snapshot def' do - action_sequence = - described_class.build(rep) do |b| - b.add_snapshot(:giraffe, nil) - end - - expect(action_sequence.snapshots_defs.size).to eq(1) - expect(action_sequence.snapshots_defs[0].name).to eq(:giraffe) - expect(action_sequence.snapshots_defs[0]).not_to be_binary - end - - it 'generated follow-up textual snapshot def if previous filter is textual' do - action_sequence = - described_class.build(rep) do |b| - b.add_snapshot(:giraffe, nil) - b.add_filter(:RuleMemSpec_filter_t2t, arguments: 'irrelevant') - b.add_snapshot(:zebra, nil) - end - - expect(action_sequence.snapshots_defs.size).to eq(2) - expect(action_sequence.snapshots_defs[0].name).to eq(:giraffe) - expect(action_sequence.snapshots_defs[0]).not_to be_binary - expect(action_sequence.snapshots_defs[1].name).to eq(:zebra) - expect(action_sequence.snapshots_defs[1]).not_to be_binary - end - - it 'generated follow-up binary snapshot def if previous filter is text-to-bianry' do - action_sequence = - described_class.build(rep) do |b| - b.add_snapshot(:giraffe, nil) - b.add_filter(:RuleMemSpec_filter_t2b, arguments: 'irrelevant') - b.add_snapshot(:zebra, nil) - end - - expect(action_sequence.snapshots_defs.size).to eq(2) - expect(action_sequence.snapshots_defs[0].name).to eq(:giraffe) - expect(action_sequence.snapshots_defs[0]).not_to be_binary - expect(action_sequence.snapshots_defs[1].name).to eq(:zebra) - expect(action_sequence.snapshots_defs[1]).to be_binary - end - end - - context 'binary item' do - let(:item) { Nanoc::Int::Item.new(Nanoc::Int::BinaryContent.new('/asdf.dat'), {}, '/foo.md') } - - it 'generates initial binary snapshot def' do - action_sequence = - described_class.build(rep) do |b| - b.add_snapshot(:giraffe, nil) - end - - expect(action_sequence.snapshots_defs.size).to eq(1) - expect(action_sequence.snapshots_defs[0].name).to eq(:giraffe) - expect(action_sequence.snapshots_defs[0]).to be_binary - end - - it 'generated follow-up binary snapshot def if previous filter is binary' do - action_sequence = - described_class.build(rep) do |b| - b.add_snapshot(:giraffe, nil) - b.add_filter(:RuleMemSpec_filter_b2b, arguments: 'irrelevant') - b.add_snapshot(:zebra, nil) - end - - expect(action_sequence.snapshots_defs.size).to eq(2) - expect(action_sequence.snapshots_defs[0].name).to eq(:giraffe) - expect(action_sequence.snapshots_defs[0]).to be_binary - expect(action_sequence.snapshots_defs[1].name).to eq(:zebra) - expect(action_sequence.snapshots_defs[1]).to be_binary - end - - it 'generated follow-up textual snapshot def if previous filter is binary-to-text' do - action_sequence = - described_class.build(rep) do |b| - b.add_snapshot(:giraffe, nil) - b.add_filter(:RuleMemSpec_filter_b2t, arguments: 'irrelevant') - b.add_snapshot(:zebra, nil) - end - - expect(action_sequence.snapshots_defs.size).to eq(2) - expect(action_sequence.snapshots_defs[0].name).to eq(:giraffe) - expect(action_sequence.snapshots_defs[0]).to be_binary - expect(action_sequence.snapshots_defs[1].name).to eq(:zebra) - expect(action_sequence.snapshots_defs[1]).not_to be_binary - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/code_snippet_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/code_snippet_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/code_snippet_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/code_snippet_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::CodeSnippet do - subject(:code_snippet) { described_class.new(data, 'lib/foo.rb') } - - describe '#load' do - subject { code_snippet.load } - - describe 'calling #include' do - let(:data) do - <<~EOS - module CodeSnippetSpecHelper1 - def fe345b48e4 - "fe345b48e4" - end - end - - include CodeSnippetSpecHelper1 - EOS - end - - it 'makes helper functions available everywhere' do - expect { subject } - .to change { [Nanoc::Int::Context.new({}).respond_to?(:fe345b48e4), Complex.respond_to?(:fe345b48e4)] } - .from([false, false]) - .to([true, true]) - end - end - - describe 'calling #use_helper' do - let(:data) do - <<~EOS - module CodeSnippetSpecHelper2 - def e0f0c30b5e - "e0f0c30b5e" - end - end - - use_helper CodeSnippetSpecHelper2 - EOS - end - - it 'makes helper functions available in helpers only' do - expect { subject } - .to change { [Nanoc::Int::Context.new({}).respond_to?(:e0f0c30b5e), Complex.respond_to?(:e0f0c30b5e)] } - .from([false, false]) - .to([true, false]) - end - end - - it 'defines at top level' do - @foo = 'meow' - - code_snippet = Nanoc::Int::CodeSnippet.new("@foo = 'woof'", 'dog.rb') - code_snippet.load - - expect(@foo).to eq('meow') - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/configuration_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/configuration_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/configuration_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/configuration_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,520 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Configuration do - let(:hash) { { foo: 'bar' } } - let(:config) { described_class.new(hash: hash, dir: Dir.getwd) } - - describe '#key?' do - subject { config.key?(key) } - - context 'non-existent key' do - let(:key) { :donkey } - it { is_expected.not_to be } - end - - context 'existent key' do - let(:key) { :foo } - it { is_expected.to be } - end - end - - describe '#with_defaults' do - subject { config.with_defaults } - - context 'no env' do - it 'has a default output_dir' do - expect(subject[:output_dir]).to eql('output') - end - end - - context 'env' do - let(:config) { described_class.new(hash: hash, dir: Dir.getwd, env_name: 'giraffes') } - - it 'retains the env name' do - expect(subject.env_name).to eql('giraffes') - end - end - end - - describe '#output_dir' do - subject { config.with_defaults.output_dir } - - context 'not explicitly defined' do - let(:hash) { { foo: 'bar' } } - it { is_expected.to eql(Dir.getwd + '/output') } - end - - context 'explicitly defined, top-level' do - let(:hash) { { foo: 'bar', output_dir: 'build' } } - it { is_expected.to eql(Dir.getwd + '/build') } - end - end - - describe '#output_dirs' do - subject { config.with_defaults.output_dirs } - - let(:hash) do - { - output_dir: 'output_toplevel', - environments: { - default: { - output_dir: 'output_default', - }, - production: { - output_dir: 'output_prod', - }, - staging: { - output_dir: 'output_staging', - }, - other: {}, - }, - } - end - - it 'contains both top-level and default output dir' do - expect(subject).to include(Dir.getwd + '/output_toplevel') - expect(subject).to include(Dir.getwd + '/output_default') - end - - it 'does not contain nil' do - expect(subject).not_to include(nil) - end - - it 'contains all other output dirs' do - expect(subject).to include(Dir.getwd + '/output_staging') - expect(subject).to include(Dir.getwd + '/output_prod') - end - end - - describe '#merge' do - let(:hash1) { { foo: { bar: 'baz', baz: ['biz'] } } } - let(:hash2) { { foo: { bar: :boz, biz: 'buz' } } } - let(:config1) { described_class.new(hash: hash1, dir: Dir.getwd) } - let(:config2) { described_class.new(hash: hash2, dir: Dir.getwd) } - - subject { config1.merge(config2).to_h } - - it 'contains the recursive merge of both configurations' do - expect(subject).to include(foo: { bar: :boz, baz: ['biz'], biz: 'buz' }) - end - end - - context 'with environments defined' do - let(:hash) { { foo: 'bar', environments: { test: { foo: 'test-bar' }, default: { foo: 'default-bar' } } } } - let(:config) { described_class.new(hash: hash, dir: Dir.getwd, env_name: env_name).with_environment } - - subject { config } - - context 'with existing environment' do - let(:env_name) { 'test' } - - it 'inherits options from given environment' do - expect(subject[:foo]).to eq('test-bar') - end - end - - context 'with unknown environment' do - let(:env_name) { 'wtf' } - - it 'does not inherits options from any environment' do - expect(subject[:foo]).to eq('bar') - end - end - - context 'without given environment' do - let(:env_name) { nil } - - it 'inherits options from default environment' do - expect(subject[:foo]).to eq('default-bar') - end - end - end - - describe 'validation' do - subject { config } - - context 'valid text_extensions' do - let(:hash) { { text_extensions: ['md'] } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'invalid text_extensions (not an array)' do - let(:hash) { { text_extensions: 123 } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid text_extensions (array, but with other things)' do - let(:hash) { { text_extensions: [123] } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'valid output_dir' do - let(:hash) { { output_dir: 'output' } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'invalid output_dir' do - let(:hash) { { output_dir: 123 } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'valid index_filenames' do - let(:hash) { { index_filenames: ['index.html'] } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'invalid index_filenames (not an array)' do - let(:hash) { { index_filenames: 123 } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid index_filenames (array, but with other things)' do - let(:hash) { { index_filenames: [123] } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'valid enable_output_diff' do - let(:hash) { { enable_output_diff: false } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'invalid enable_output_diff' do - let(:hash) { { enable_output_diff: 'nope' } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'valid prune (empty)' do - let(:hash) { { prune: {} } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'valid prune (full)' do - let(:hash) { { prune: { auto_prune: true, exclude: ['oink'] } } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'invalid prune (not a hash)' do - let(:hash) { { prune: 'please' } } - - it 'passes' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid prune (auto_prune has incorrect type)' do - let(:hash) { { prune: { auto_prune: 'please' } } } - - it 'passes' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid prune (exclude has incorrect type)' do - let(:hash) { { prune: { exclude: 'nothing' } } } - - it 'passes' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid prune (exclude has items of incorrect type)' do - let(:hash) { { prune: { exclude: [3000] } } } - - it 'passes' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'valid commands_dirs' do - let(:hash) { { commands_dirs: ['commands'] } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'invalid commands_dirs (not an array)' do - let(:hash) { { commands_dirs: 123 } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid commands_dirs (array, but with other things)' do - let(:hash) { { commands_dirs: [123] } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'valid lib_dirs' do - let(:hash) { { lib_dirs: ['lib'] } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'invalid lib_dirs (not an array)' do - let(:hash) { { lib_dirs: 123 } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid lib_dirs (array, but with other things)' do - let(:hash) { { lib_dirs: [123] } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'valid data_sources (full)' do - let(:hash) { { data_sources: [{ type: 'something', items_root: 'itemz/' }] } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'valid data_sources (null items_root)' do - let(:hash) { { data_sources: [{ type: 'something', items_root: nil }] } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'valid data_sources (null layouts_root)' do - let(:hash) { { data_sources: [{ type: 'something', layouts_root: nil }] } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'valid data_sources (empty list)' do - let(:hash) { { data_sources: [] } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'valid data_sources (list with empty hashes)' do - let(:hash) { { data_sources: [{}] } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'invalid data_sources (not an array)' do - let(:hash) { { data_sources: 'all of them please' } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid data_sources (items have invalid type)' do - let(:hash) { { data_sources: ['all of them please'] } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid data_sources (items have invalid type field)' do - let(:hash) { { data_sources: [{ type: 17 }] } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid data_sources (items have invalid items_root field)' do - let(:hash) { { data_sources: [{ items_root: 17 }] } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid data_sources (items have invalid layouts_root field)' do - let(:hash) { { data_sources: [{ layouts_root: 17 }] } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'valid string_pattern_type' do - let(:hash) { { string_pattern_type: 'glob' } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'invalid string_pattern_type (incorrect type)' do - let(:hash) { { string_pattern_type: 16 } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid string_pattern_type (not in enum)' do - let(:hash) { { string_pattern_type: 'pretty' } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'valid checks (full)' do - let(:hash) do - { - checks: { - internal_links: { - exclude: ['oink'], - }, - external_links: { - exclude: ['abc'], - exclude_files: ['xyz'], - }, - }, - } - end - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'invalid checks (invalid type)' do - let(:hash) do - { checks: 123 } - end - - it 'passes' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid checks (internal_links has invalid type)' do - let(:hash) do - { checks: { internal_links: 123 } } - end - - it 'passes' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid checks (internal_links.exclude has invalid type)' do - let(:hash) do - { checks: { internal_links: { exclude: 'everything' } } } - end - - it 'passes' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid checks (external_links has invalid type)' do - let(:hash) do - { checks: { external_links: 123 } } - end - - it 'passes' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid checks (external_links.exclude has invalid type)' do - let(:hash) do - { checks: { external_links: { exclude: 'everything' } } } - end - - it 'passes' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid checks (external_links.exclude_files has invalid type)' do - let(:hash) do - { checks: { external_links: { exclude_files: 'everything' } } } - end - - it 'passes' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'valid environments' do - let(:hash) { { environments: { production: {} } } } - - it 'passes' do - expect { subject }.not_to raise_error - end - end - - context 'invalid environments (not an object)' do - let(:hash) { { environments: nil } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - - context 'invalid environments (values are not objects)' do - let(:hash) { { environments: { production: nil } } } - - it 'fails' do - expect { subject }.to raise_error(JsonSchema::Error) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/content_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/content_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/content_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/content_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,195 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Content do - describe '.create' do - subject { described_class.create(arg, params) } - - let(:params) { {} } - - context 'nil arg' do - let(:arg) { nil } - - it 'raises' do - expect { subject }.to raise_error(ArgumentError) - end - end - - context 'content arg' do - let(:arg) { Nanoc::Int::TextualContent.new('foo') } - - it { is_expected.to eql(arg) } - end - - context 'with binary: true param' do - let(:arg) { '/foo.dat' } - let(:params) { { binary: true } } - - it 'returns binary content' do - expect(subject).to be_a(Nanoc::Int::BinaryContent) - expect(subject.filename).to eql('/foo.dat') - end - end - - context 'with binary: false param' do - context 'with filename param' do - let(:arg) { 'foo' } - let(:params) { { binary: false, filename: '/foo.md' } } - - it 'returns textual content' do - expect(subject).to be_a(Nanoc::Int::TextualContent) - expect(subject.string).to eql('foo') - expect(subject.filename).to eql('/foo.md') - end - end - - context 'without filename param' do - let(:arg) { 'foo' } - let(:params) { { binary: false } } - - it 'returns textual content' do - expect(subject).to be_a(Nanoc::Int::TextualContent) - expect(subject.string).to eql('foo') - expect(subject.filename).to be_nil - end - end - end - end -end - -describe Nanoc::Int::TextualContent do - describe '#initialize' do - context 'without filename' do - let(:content) { described_class.new('foo') } - - it 'sets string and filename' do - expect(content.string).to eq('foo') - expect(content.filename).to be_nil - end - end - - context 'with absolute filename' do - let(:content) { described_class.new('foo', filename: '/foo.md') } - - it 'sets string and filename' do - expect(content.string).to eq('foo') - expect(content.filename).to eq('/foo.md') - end - end - - context 'with relative filename' do - let(:content) { described_class.new('foo', filename: 'foo.md') } - - it 'errors' do - expect { content }.to raise_error(ArgumentError) - end - end - - context 'with proc' do - let(:content_proc) { -> { 'foo' } } - let(:content) { described_class.new(content_proc) } - - it 'does not call the proc immediately' do - expect(content_proc).not_to receive(:call) - - content - end - - it 'sets string' do - expect(content_proc).to receive(:call).once.and_return('dataz') - - expect(content.string).to eq('dataz') - end - - it 'only calls the proc once' do - expect(content_proc).to receive(:call).once.and_return('dataz') - - expect(content.string).to eq('dataz') - expect(content.string).to eq('dataz') - end - end - end - - describe '#binary?' do - subject { content.binary? } - let(:content) { described_class.new('foo') } - it { is_expected.to eql(false) } - end - - describe '#freeze' do - let(:content) { described_class.new('foo', filename: '/asdf.md') } - - before do - content.freeze - end - - it 'prevents changes to string' do - expect(content.string).to be_frozen - expect { content.string << 'asdf' }.to raise_frozen_error - end - - it 'prevents changes to filename' do - expect(content.filename).to be_frozen - expect { content.filename << 'asdf' }.to raise_frozen_error - end - - context 'with proc' do - let(:content) { described_class.new(proc { 'foo' }) } - - it 'prevents changes to string' do - expect(content.string).to be_frozen - expect { content.string << 'asdf' }.to raise_frozen_error - end - end - end - - describe 'marshalling' do - let(:content) { described_class.new('foo', filename: '/foo.md') } - - it 'dumps as an array' do - expect(content.marshal_dump).to eq(['/foo.md', 'foo']) - end - - it 'restores a dumped object' do - restored = Marshal.load(Marshal.dump(content)) - expect(restored.string).to eq('foo') - expect(restored.filename).to eq('/foo.md') - end - end -end - -describe Nanoc::Int::BinaryContent do - describe '#initialize' do - let(:content) { described_class.new('/foo.dat') } - - it 'sets filename' do - expect(content.filename).to eql('/foo.dat') - end - - context 'with relative filename' do - let(:content) { described_class.new('foo.dat') } - - it 'errors' do - expect { content }.to raise_error(ArgumentError) - end - end - end - - describe '#binary?' do - subject { content.binary? } - let(:content) { described_class.new('/foo.dat') } - it { is_expected.to eql(true) } - end - - describe '#freeze' do - let(:content) { described_class.new('/foo.dat') } - - before do - content.freeze - end - - it 'prevents changes' do - expect(content.filename).to be_frozen - expect { content.filename << 'asdf' }.to raise_frozen_error - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/context_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/context_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/context_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/context_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Context do - let(:context) do - Nanoc::Int::Context.new(foo: 'bar', baz: 'quux') - end - - it 'provides instance variables' do - expect(eval('@foo', context.get_binding)).to eq('bar') - end - - it 'provides instance methods' do - expect(eval('foo', context.get_binding)).to eq('bar') - end - - it 'supports #include' do - eval('include Nanoc::Helpers::HTMLEscape', context.get_binding) - expect(eval('h("<>")', context.get_binding)).to eq('<>') - end - - it 'has correct examples' do - expect('Nanoc::Int::Context#initialize') - .to have_correct_yard_examples - .in_file('nanoc/lib/nanoc/base/entities/context.rb') - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/document_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/document_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/document_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/document_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,332 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'a document' do - describe '#initialize' do - let(:content_arg) { 'Hello world' } - let(:attributes_arg) { { 'title' => 'Home' } } - let(:identifier_arg) { '/home.md' } - let(:checksum_data_arg) { 'abcdef' } - let(:content_checksum_data_arg) { 'con-cs' } - let(:attributes_checksum_data_arg) { 'attr-cs' } - - subject do - described_class.new( - content_arg, - attributes_arg, - identifier_arg, - checksum_data: checksum_data_arg, - content_checksum_data: content_checksum_data_arg, - attributes_checksum_data: attributes_checksum_data_arg, - ) - end - - describe 'content arg' do - context 'string' do - it 'converts content' do - expect(subject.content).to be_a(Nanoc::Int::TextualContent) - expect(subject.content.string).to eql('Hello world') - end - end - - context 'content' do - let(:content_arg) { Nanoc::Int::TextualContent.new('foo') } - - it 'reuses content' do - expect(subject.content).to equal(content_arg) - end - end - end - - describe 'attributes arg' do - context 'hash' do - it 'symbolizes attributes' do - expect(subject.attributes).to eq(title: 'Home') - end - end - - context 'proc' do - call_count = 0 - let(:attributes_arg) do - proc do - call_count += 1 - { 'title' => 'Home' } - end - end - - before do - call_count = 0 - end - - it 'does not call the proc immediately' do - expect(call_count).to eql(0) - end - - it 'symbolizes attributes' do - expect(subject.attributes).to eq(title: 'Home') - end - - it 'only calls the proc once' do - subject.attributes - subject.attributes - expect(call_count).to eql(1) - end - end - end - - describe 'identifier arg' do - context 'string' do - it 'converts identifier' do - expect(subject.identifier).to be_a(Nanoc::Identifier) - expect(subject.identifier.to_s).to eql('/home.md') - end - end - - context 'identifier' do - let(:identifier_arg) { Nanoc::Identifier.new('/foo.md') } - - it 'retains identifier' do - expect(subject.identifier).to equal(identifier_arg) - end - end - end - - describe 'checksum_data arg' do - it 'reuses checksum_data' do - expect(subject.checksum_data).to eql(checksum_data_arg) - end - end - - describe 'content_checksum_data arg' do - it 'reuses content_checksum_data' do - expect(subject.content_checksum_data).to eql(content_checksum_data_arg) - end - end - - describe 'attributes_checksum_data arg' do - it 'reuses attributes_checksum_data' do - expect(subject.attributes_checksum_data).to eql(attributes_checksum_data_arg) - end - end - end - - describe '#freeze' do - let(:content_arg) { 'Hallo' } - let(:attributes_arg) { { foo: { bar: 'asdf' } } } - let(:document) { described_class.new(content_arg, attributes_arg, '/foo.md') } - - before do - document.freeze - end - - it 'refuses changes to content' do - expect { document.instance_variable_set(:@content, 'hah') }.to raise_frozen_error - expect { document.content.string << 'hah' }.to raise_frozen_error - end - - it 'refuses to change attributes' do - expect { document.instance_variable_set(:@attributes, a: 'Hi') }.to raise_frozen_error - expect { document.attributes[:title] = 'Bye' }.to raise_frozen_error - expect { document.attributes[:foo][:bar] = 'fdsa' }.to raise_frozen_error - end - - it 'refuses to change identifier' do - expect { document.identifier = '/asdf' }.to raise_frozen_error - expect { document.identifier.to_s << '/omg' }.to raise_frozen_error - end - - context 'binary content' do - let(:content_arg) { Nanoc::Int::BinaryContent.new(File.expand_path('foo.dat')) } - - it 'refuses changes to content' do - expect { document.instance_variable_set(:@content, 'hah') }.to raise_frozen_error - expect { document.content.filename << 'hah' }.to raise_frozen_error - end - end - - context 'attributes block' do - let(:attributes_arg) { proc { { foo: { bar: 'asdf' } } } } - - it 'gives access to the attributes' do - expect(document.attributes).to eql(foo: { bar: 'asdf' }) - end - - it 'refuses to change attributes' do - expect { document.instance_variable_set(:@attributes, a: 'Hi') }.to raise_frozen_error - expect { document.attributes[:title] = 'Bye' }.to raise_frozen_error - expect { document.attributes[:foo][:bar] = 'fdsa' }.to raise_frozen_error - end - end - end - - describe 'equality' do - let(:content_arg_a) { 'Hello world' } - let(:content_arg_b) { 'Bye world' } - - let(:attributes_arg_a) { { 'title' => 'Home' } } - let(:attributes_arg_b) { { 'title' => 'About' } } - - let(:identifier_arg_a) { '/home.md' } - let(:identifier_arg_b) { '/home.md' } - - let(:document_a) { described_class.new(content_arg_a, attributes_arg_a, identifier_arg_a) } - let(:document_b) { described_class.new(content_arg_b, attributes_arg_b, identifier_arg_b) } - - subject { document_a == document_b } - - context 'same identifier' do - let(:identifier_arg_a) { '/home.md' } - let(:identifier_arg_b) { '/home.md' } - - it { is_expected.to eql(true) } - - it 'has same hashes' do - expect(document_a.hash).to eql(document_b.hash) - end - end - - context 'different identifier' do - let(:identifier_arg_a) { '/home.md' } - let(:identifier_arg_b) { '/about.md' } - - it { is_expected.to eql(false) } - - it 'has different hashes' do - expect(document_a.hash).not_to eql(document_b.hash) - end - end - - context 'comparing with non-document' do - let(:document_b) { nil } - - it { is_expected.to eql(false) } - - it 'has different hashes' do - expect(document_a.hash).not_to eql(document_b.hash) - end - end - end - - describe '#with_identifier_prefix' do - let(:document) { described_class.new('kontent', { at: 'ribut' }, '/donkey.md') } - - subject { document.with_identifier_prefix('/animals') } - - it 'does not mutate the original' do - document.freeze - subject - end - - it 'returns a new document with a prefixed identifier' do - expect(subject.identifier).to eq('/animals/donkey.md') - end - - it 'does not change other data' do - expect(subject.content).to be_some_textual_content('kontent') - expect(subject.attributes).to eq(at: 'ribut') - end - end - - describe '#identifier=' do - let(:document) { described_class.new('stuff', {}, '/foo.md') } - - it 'allows changing to a string that contains a full identifier' do - expect { document.identifier = '/thing' }.not_to raise_error - - expect(document.identifier).to eq('/thing') - expect(document.identifier).to be_full - end - - it 'refuses changing to a string that does not contain a full identifier' do - expect { document.identifier = '/thing/' } - .to raise_error(Nanoc::Identifier::InvalidFullIdentifierError) - end - - it 'allos changing to a full identifier' do - document.identifier = Nanoc::Identifier.new('/thing') - - expect(document.identifier.to_s).to eq('/thing') - expect(document.identifier).to be_full - end - - it 'allos changing to a legacy identifier' do - document.identifier = Nanoc::Identifier.new('/thing/', type: :legacy) - - expect(document.identifier).to eq('/thing/') - expect(document.identifier).to be_legacy - end - end - - describe '#content=' do - let(:document) do - described_class.new( - content_arg, - attributes_arg, - '/foo.md', - checksum_data: 'ch3cksum_d4t4', - content_checksum_data: 'c0nt3nt_ch3cksum_d4t4', - attributes_checksum_data: '4ttr_ch3cksum_d4t4', - ) - end - - let(:content_arg) { 'Hallo' } - let(:attributes_arg) { { foo: { bar: 'asdf' } } } - - subject { document.content = Nanoc::Int::TextualContent.new('New!') } - - it 'clears checksum' do - expect { subject } - .to change { document.checksum_data } - .from('ch3cksum_d4t4') - .to(nil) - end - - it 'clears content checksum' do - expect { subject } - .to change { document.content_checksum_data } - .from('c0nt3nt_ch3cksum_d4t4') - .to(nil) - end - - it 'does not clear attributes checksum data' do - expect { subject } - .not_to change { document.attributes_checksum_data } - end - end - - describe '#set_attribute' do - let(:document) do - described_class.new( - content_arg, - attributes_arg, - '/foo.md', - checksum_data: 'ch3cksum_d4t4', - content_checksum_data: 'c0nt3nt_ch3cksum_d4t4', - attributes_checksum_data: '4ttr_ch3cksum_d4t4', - ) - end - - let(:content_arg) { 'Hallo' } - let(:attributes_arg) { { foo: { bar: 'asdf' } } } - - subject { document.set_attribute(:key, 'value') } - - it 'clears checksum' do - expect { subject } - .to change { document.checksum_data } - .from('ch3cksum_d4t4') - .to(nil) - end - - it 'clears attributes checksum' do - expect { subject } - .to change { document.attributes_checksum_data } - .from('4ttr_ch3cksum_d4t4') - .to(nil) - end - - it 'does not clear content checksum data' do - expect { subject } - .not_to change { document.content_checksum_data } - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/identifiable_collection_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/identifiable_collection_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/identifiable_collection_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/identifiable_collection_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,209 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::IdentifiableCollection do - shared_examples 'a generic identifiable collection' do - subject(:identifiable_collection) { described_class.new(config, objects) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd) } - let(:objects) { [] } - - describe '#reject' do - subject { identifiable_collection.reject { |_| false } } - - it { is_expected.to be_a(described_class) } - end - - describe '#inspect' do - subject { identifiable_collection.inspect } - - it { is_expected.to eq("<#{described_class}>") } - end - - describe '#[]' do - let(:objects) do - [ - Nanoc::Int::Item.new('asdf', {}, Nanoc::Identifier.new('/one')), - Nanoc::Int::Item.new('asdf', {}, Nanoc::Identifier.new('/two')), - ] - end - - context 'string pattern style is glob' do - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - it 'handles glob' do - expect(identifiable_collection['/on*']).to equal(objects[0]) - expect(identifiable_collection['/*wo']).to equal(objects[1]) - end - end - - context 'string pattern style is glob' do - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd) } - - it 'does not handle glob' do - expect(identifiable_collection['/on*']).to be_nil - expect(identifiable_collection['/*wo']).to be_nil - end - end - - it 'handles identifier' do - expect(identifiable_collection['/one']).to equal(objects[0]) - expect(identifiable_collection['/two']).to equal(objects[1]) - end - - it 'handles malformed identifier' do - expect(identifiable_collection['one/']).to be_nil - expect(identifiable_collection['/one/']).to be_nil - expect(identifiable_collection['one']).to be_nil - expect(identifiable_collection['//one']).to be_nil - expect(identifiable_collection['/one//']).to be_nil - end - - it 'handles regex' do - expect(identifiable_collection[/one/]).to equal(objects[0]) - expect(identifiable_collection[/on/]).to equal(objects[0]) - expect(identifiable_collection[/\/o/]).to equal(objects[0]) - expect(identifiable_collection[/e$/]).to equal(objects[0]) - end - - context 'frozen' do - before { identifiable_collection.freeze } - - example do - expect(identifiable_collection['/one']).to equal(objects[0]) - expect(identifiable_collection['/fifty']).to be_nil - end - end - end - - describe '#find_all' do - let(:objects) do - [ - double(:identifiable, identifier: Nanoc::Identifier.new('/about.css')), - double(:identifiable, identifier: Nanoc::Identifier.new('/about.md')), - double(:identifiable, identifier: Nanoc::Identifier.new('/style.css')), - ] - end - - let(:arg) { raise 'override me' } - - subject { identifiable_collection.find_all(arg) } - - context 'with string' do - let(:arg) { '/*.css' } - - it 'contains objects' do - expect(subject.size).to eql(2) - expect(subject.find { |iv| iv.identifier == '/about.css' }).to eq(objects[0]) - expect(subject.find { |iv| iv.identifier == '/style.css' }).to eq(objects[2]) - end - end - - context 'with regex' do - let(:arg) { %r{\.css\z} } - - it 'contains objects' do - expect(subject.size).to eql(2) - expect(subject.find { |iv| iv.identifier == '/about.css' }).to eq(objects[0]) - expect(subject.find { |iv| iv.identifier == '/style.css' }).to eq(objects[2]) - end - end - end - - describe '#object_with_identifier' do - let(:objects) do - [ - Nanoc::Int::Item.new('stuff', {}, Nanoc::Identifier.new('/about.css')), - Nanoc::Int::Item.new('stuff', {}, Nanoc::Identifier.new('/about.md')), - Nanoc::Int::Item.new('stuff', {}, Nanoc::Identifier.new('/style.css')), - ] - end - - let(:arg) { raise 'override me' } - - subject { identifiable_collection.object_with_identifier(arg) } - - context 'with string' do - let(:arg) { '/about.css' } - it { is_expected.to eq(objects[0]) } - end - - context 'with identifier' do - let(:arg) { Nanoc::Identifier.new('/about.css') } - it { is_expected.to eq(objects[0]) } - end - - context 'with glob string' do - let(:arg) { '/about.*' } - it { is_expected.to be_nil } - end - end - - describe '#reference' do - subject { identifiable_collection.reference } - it { is_expected.to eql(expected_reference) } - end - - describe 'changing identifiers' do - let(:objects) do - [ - Nanoc::Int::Item.new('Foo', {}, '/foo'), - ] - end - - subject { objects[0].identifier = '/bar' } - - it 'makes /foo nil' do - expect { subject } - .to change { identifiable_collection['/foo'] } - .from(objects[0]) - .to(nil) - end - - it 'makes /bar non-nil' do - expect { subject } - .to change { identifiable_collection['/bar'] } - .from(nil) - .to(objects[0]) - end - end - - describe '#each' do - let(:objects) do - [ - Nanoc::Int::Item.new('Foo', {}, '/foo'), - Nanoc::Int::Item.new('Bar', {}, '/bar'), - ] - end - - it 'loops' do - res = [] - identifiable_collection.each { |i| res << i.identifier.to_s } - expect(res).to match_array(['/foo', '/bar']) - end - end - - describe '#map' do - let(:objects) do - [ - Nanoc::Int::Item.new('Foo', {}, '/foo'), - Nanoc::Int::Item.new('Bar', {}, '/bar'), - ] - end - - it 'loops' do - res = identifiable_collection.map { |i| i.identifier.to_s } - expect(res).to match_array(['/foo', '/bar']) - end - end - end - - describe Nanoc::Int::ItemCollection do - let(:expected_reference) { 'items' } - it_behaves_like 'a generic identifiable collection' - end - - describe Nanoc::Int::LayoutCollection do - let(:expected_reference) { 'layouts' } - it_behaves_like 'a generic identifiable collection' - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/identifier_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/identifier_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/identifier_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/identifier_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,506 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Identifier do - describe '.from' do - subject { described_class.from(arg) } - - context 'given an identifier' do - let(:arg) { Nanoc::Identifier.new('/foo.md') } - - it 'returns an identifier' do - expect(subject).to be_a(Nanoc::Identifier) - expect(subject.to_s).to eq('/foo.md') - expect(subject).to be_full - end - end - - context 'given a string' do - let(:arg) { '/foo.md' } - - it 'returns an identifier' do - expect(subject).to be_a(Nanoc::Identifier) - expect(subject.to_s).to eq('/foo.md') - expect(subject).to be_full - end - end - - context 'given something else' do - let(:arg) { 12_345 } - - it 'raises' do - expect { subject }.to raise_error(Nanoc::Identifier::NonCoercibleObjectError) - end - end - end - - describe '#initialize' do - context 'legacy type' do - it 'does not convert already clean paths' do - expect(described_class.new('/foo/bar/', type: :legacy).to_s).to eql('/foo/bar/') - end - - it 'prepends slash if necessary' do - expect(described_class.new('foo/bar/', type: :legacy).to_s).to eql('/foo/bar/') - end - - it 'appends slash if necessary' do - expect(described_class.new('/foo/bar', type: :legacy).to_s).to eql('/foo/bar/') - end - - it 'removes double slashes at start' do - expect(described_class.new('//foo/bar/', type: :legacy).to_s).to eql('/foo/bar/') - end - - it 'removes double slashes at end' do - expect(described_class.new('/foo/bar//', type: :legacy).to_s).to eql('/foo/bar/') - end - - it 'freezes' do - identifier = described_class.new('/foo/bar/', type: :legacy) - expect { identifier.to_s << 'bbq' }.to raise_frozen_error - end - end - - context 'full type' do - it 'refuses string not starting with a slash' do - expect { described_class.new('foo') } - .to raise_error(Nanoc::Identifier::InvalidIdentifierError) - end - - it 'refuses string ending with a slash' do - expect { described_class.new('/foo/') } - .to raise_error(Nanoc::Identifier::InvalidFullIdentifierError) - end - - it 'refuses string with only slash' do - expect { described_class.new('/') } - .to raise_error(Nanoc::Identifier::InvalidFullIdentifierError) - end - - it 'has proper string representation' do - expect(described_class.new('/foo').to_s).to eql('/foo') - end - - it 'freezes' do - identifier = described_class.new('/foo/bar') - expect { identifier.to_s << 'bbq' }.to raise_frozen_error - end - end - - context 'other type' do - it 'errors' do - expect { described_class.new('foo', type: :donkey) } - .to raise_error(Nanoc::Identifier::InvalidTypeError) - end - end - - context 'default type' do - it 'is full' do - expect(described_class.new('/foo')).to be_full - end - end - - context 'other args specified' do - it 'errors' do - expect { described_class.new('?', animal: :donkey) } - .to raise_error(ArgumentError) - end - end - end - - describe '#to_s' do - it 'returns immutable string' do - expect { described_class.new('foo/', type: :legacy).to_s << 'lols' }.to raise_frozen_error - expect { described_class.new('/foo').to_s << 'lols' }.to raise_frozen_error - end - end - - describe '#to_str' do - it 'returns immutable string' do - expect { described_class.new('/foo/bar').to_str << 'lols' }.to raise_frozen_error - end - end - - describe 'Comparable' do - it 'can be compared' do - expect(described_class.new('/foo/bar') <= '/qux').to eql(true) - end - end - - describe '#inspect' do - let(:identifier) { described_class.new('/foo/bar') } - - subject { identifier.inspect } - - it { should == '' } - end - - describe '#== and #eql?' do - context 'comparing with equal identifier' do - let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) } - let(:identifier_b) { described_class.new('/foo/bar//', type: :legacy) } - - it 'is ==' do - expect(identifier_a).to eq(identifier_b) - end - - it 'is eql?' do - expect(identifier_a).to eql(identifier_b) - end - end - - context 'comparing with equal string' do - let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) } - let(:identifier_b) { '/foo/bar/' } - - it 'is ==' do - expect(identifier_a).to eq(identifier_b.to_s) - end - - it 'is not eql?' do - expect(identifier_a).not_to eql(identifier_b.to_s) - end - end - - context 'comparing with different identifier' do - let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) } - let(:identifier_b) { described_class.new('/baz/qux//', type: :legacy) } - - it 'is not ==' do - expect(identifier_a).not_to eq(identifier_b) - end - - it 'is not eql?' do - expect(identifier_a).not_to eql(identifier_b) - end - end - - context 'comparing with different string' do - let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) } - let(:identifier_b) { '/baz/qux/' } - - it 'is not equal' do - expect(identifier_a).not_to eq(identifier_b) - end - - it 'is not eql?' do - expect(identifier_a).not_to eql(identifier_b) - end - end - - context 'comparing with something that is not an identifier' do - let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) } - let(:identifier_b) { :donkey } - - it 'is not equal' do - expect(identifier_a).not_to eq(identifier_b) - expect(identifier_a).not_to eql(identifier_b) - end - end - end - - describe '#hash' do - context 'equal identifiers' do - let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) } - let(:identifier_b) { described_class.new('/foo/bar//', type: :legacy) } - - it 'is the same' do - expect(identifier_a.hash == identifier_b.hash).to eql(true) - end - end - - context 'different identifiers' do - let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) } - let(:identifier_b) { described_class.new('/monkey/', type: :legacy) } - - it 'is different' do - expect(identifier_a.hash == identifier_b.hash).to eql(false) - end - end - end - - describe '#=~' do - let(:identifier) { described_class.new('/foo/bar') } - - subject { identifier =~ pat } - - context 'given a regex' do - context 'matching regex' do - let(:pat) { %r{\A/foo/bar} } - it { is_expected.to eql(0) } - end - - context 'non-matching regex' do - let(:pat) { %r{\A/qux/monkey} } - it { is_expected.to eql(nil) } - end - end - - context 'given a string' do - context 'matching string' do - let(:pat) { '/foo/*' } - it { is_expected.to eql(0) } - end - - context 'non-matching string' do - let(:pat) { '/qux/*' } - it { is_expected.to eql(nil) } - end - end - end - - describe '#match?' do - let(:identifier) { described_class.new('/foo/bar') } - - subject { identifier.match?(pat) } - - context 'given a regex' do - context 'matching regex' do - let(:pat) { %r{\A/foo/bar} } - it { is_expected.to be(true) } - example { expect { subject }.not_to change { Regexp.last_match } } - end - - context 'non-matching regex' do - let(:pat) { %r{\A/qux/monkey} } - it { is_expected.to be(false) } - example { expect { subject }.not_to change { Regexp.last_match } } - end - end - - context 'given a string' do - context 'matching string' do - let(:pat) { '/foo/*' } - it { is_expected.to be(true) } - example { expect { subject }.not_to change { Regexp.last_match } } - end - - context 'non-matching string' do - let(:pat) { '/qux/*' } - it { is_expected.to be(false) } - example { expect { subject }.not_to change { Regexp.last_match } } - end - end - end - - describe '#<=>' do - let(:identifier) { described_class.new('/foo/bar') } - - it 'compares by string' do - expect(identifier <=> '/foo/aarghh').to eql(1) - expect(identifier <=> '/foo/bar').to eql(0) - expect(identifier <=> '/foo/qux').to eql(-1) - end - end - - describe '#prefix' do - let(:identifier) { described_class.new('/foo') } - - subject { identifier.prefix(prefix) } - - context 'prefix not ending nor starting with a slash' do - let(:prefix) { 'asdf' } - - it 'raises an error' do - expect { subject }.to raise_error( - Nanoc::Identifier::InvalidPrefixError, - 'Invalid prefix (does not start with a slash): "asdf"', - ) - end - end - - context 'prefix ending with a slash' do - let(:prefix) { 'asdf/' } - - it 'raises an error' do - expect { subject }.to raise_error( - Nanoc::Identifier::InvalidPrefixError, - 'Invalid prefix (does not start with a slash): "asdf/"', - ) - end - end - - context 'prefix ending and starting with a slash' do - let(:prefix) { '/asdf/' } - - it 'returns a proper new identifier' do - expect(subject).to be_a(Nanoc::Identifier) - expect(subject.to_s).to eql('/asdf/foo') - end - end - - context 'prefix nstarting with a slash' do - let(:prefix) { '/asdf' } - - it 'returns a proper new identifier' do - expect(subject).to be_a(Nanoc::Identifier) - expect(subject.to_s).to eql('/asdf/foo') - end - end - end - - describe '#without_ext' do - subject { identifier.without_ext } - - context 'legacy type' do - let(:identifier) { described_class.new('/foo/', type: :legacy) } - - it 'raises an error' do - expect { subject }.to raise_error(Nanoc::Identifier::UnsupportedLegacyOperationError) - end - end - - context 'identifier with no extension' do - let(:identifier) { described_class.new('/foo') } - - it 'does nothing' do - expect(subject).to eql('/foo') - end - end - - context 'identifier with extension' do - let(:identifier) { described_class.new('/foo.md') } - - it 'removes the extension' do - expect(subject).to eql('/foo') - end - end - end - - describe '#ext' do - subject { identifier.ext } - - context 'legacy type' do - let(:identifier) { described_class.new('/foo/', type: :legacy) } - - it 'raises an error' do - expect { subject }.to raise_error(Nanoc::Identifier::UnsupportedLegacyOperationError) - end - end - - context 'identifier with no extension' do - let(:identifier) { described_class.new('/foo') } - - it { is_expected.to be_nil } - end - - context 'identifier with extension' do - let(:identifier) { described_class.new('/foo.md') } - - it { is_expected.to eql('md') } - end - end - - describe '#without_exts' do - subject { identifier.without_exts } - - context 'legacy type' do - let(:identifier) { described_class.new('/foo/', type: :legacy) } - - it 'raises an error' do - expect { subject }.to raise_error(Nanoc::Identifier::UnsupportedLegacyOperationError) - end - end - - context 'identifier with no extension' do - let(:identifier) { described_class.new('/foo') } - - it 'does nothing' do - expect(subject).to eql('/foo') - end - end - - context 'identifier with one extension' do - let(:identifier) { described_class.new('/foo.md') } - - it 'removes the extension' do - expect(subject).to eql('/foo') - end - end - - context 'identifier with multiple extensions' do - let(:identifier) { described_class.new('/foo.html.md') } - - it 'removes the extension' do - expect(subject).to eql('/foo') - end - end - end - - describe '#exts' do - subject { identifier.exts } - - context 'legacy type' do - let(:identifier) { described_class.new('/foo/', type: :legacy) } - - it 'raises an error' do - expect { subject }.to raise_error(Nanoc::Identifier::UnsupportedLegacyOperationError) - end - end - - context 'identifier with no extension' do - let(:identifier) { described_class.new('/foo') } - - it { is_expected.to be_empty } - end - - context 'identifier with one extension' do - let(:identifier) { described_class.new('/foo.md') } - - it { is_expected.to eql(['md']) } - end - - context 'identifier with multiple extensions' do - let(:identifier) { described_class.new('/foo.html.md') } - - it { is_expected.to eql(%w[html md]) } - end - end - - describe '#legacy?' do - subject { identifier.legacy? } - - context 'legacy type' do - let(:identifier) { described_class.new('/foo/', type: :legacy) } - it { is_expected.to eql(true) } - end - - context 'full type' do - let(:identifier) { described_class.new('/foo', type: :full) } - it { is_expected.to eql(false) } - end - end - - describe '#full?' do - subject { identifier.full? } - - context 'legacy type' do - let(:identifier) { described_class.new('/foo/', type: :legacy) } - it { is_expected.to eql(false) } - end - - context 'full type' do - let(:identifier) { described_class.new('/foo', type: :full) } - it { is_expected.to eql(true) } - end - end - - describe '#components' do - subject { identifier.components } - - context 'no components' do - let(:identifier) { described_class.new('/', type: :legacy) } - it { is_expected.to eql([]) } - end - - context 'one component' do - let(:identifier) { described_class.new('/foo.md') } - it { is_expected.to eql(['foo.md']) } - end - - context 'two components' do - let(:identifier) { described_class.new('/foo/bar.md') } - it { is_expected.to eql(['foo', 'bar.md']) } - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/item_rep_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/item_rep_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/item_rep_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/item_rep_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::ItemRep do - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :giraffe) } - - describe '#snapshot?' do - subject { rep.snapshot?(snapshot_name) } - - let(:snapshot_name) { raise 'override me' } - - before do - rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(:donkey, binary: false)] - end - - context 'snapshot does not exist' do - let(:snapshot_name) { :giraffe } - it { is_expected.not_to be } - end - - context 'snapshot exists' do - let(:snapshot_name) { :donkey } - it { is_expected.to be } - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/item_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/item_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/item_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/item_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Item do - it_behaves_like 'a document' - - describe '#reference' do - let(:item) { described_class.new('hi', {}, '/foo.md') } - - it 'has the proper reference' do - expect(item.reference).to eql('item:/foo.md') - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/layout_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/layout_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/layout_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/layout_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Layout do - it_behaves_like 'a document' - - describe '#reference' do - let(:layout) { described_class.new('hi', {}, '/foo.md') } - - it 'has the proper reference' do - expect(layout.reference).to eql('layout:/foo.md') - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/lazy_value_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/lazy_value_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/lazy_value_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/lazy_value_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,154 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::LazyValue do - describe '#value' do - let(:value_arg) { +'Hello world' } - let(:lazy_value) { described_class.new(value_arg) } - - subject { lazy_value.value } - - context 'object' do - it { is_expected.to equal(value_arg) } - end - - context 'proc' do - it 'does not call the proc immediately' do - expect(value_arg).not_to receive(:call) - - lazy_value - end - - it 'returns proc return value' do - expect(value_arg).to receive(:call).once.and_return('Hello proc') - - expect(subject).to eql('Hello proc') - end - - it 'only calls the proc once' do - expect(value_arg).to receive(:call).once.and_return('Hello proc') - - expect(subject).to eql('Hello proc') - expect(subject).to eql('Hello proc') - end - end - end - - describe '#map' do - let(:value_arg) { -> { 'Hello world' } } - let(:lazy_value) { described_class.new(value_arg) } - - subject { lazy_value.map(&:upcase) } - - it 'does not call the proc immediately' do - expect(value_arg).not_to receive(:call) - - subject - end - - it 'returns proc return value' do - expect(value_arg).to receive(:call).once.and_return('Hello proc') - - expect(subject.value).to eql('HELLO PROC') - end - - it 'only calls the proc once' do - expect(value_arg).to receive(:call).once.and_return('Hello proc') - - expect(subject.value).to eql('HELLO PROC') - expect(subject.value).to eql('HELLO PROC') - end - end - - describe '#freeze' do - let(:value_arg) { 'Hello world' } - - subject { described_class.new(value_arg) } - - context 'freeze before calling #value' do - before do - subject.freeze - end - - context 'object' do - it 'returns value' do - expect(subject.value).to equal(value_arg) - end - - it 'freezes value' do - expect(subject.value).to be_frozen - end - end - - context 'proc' do - call_count = 0 - let(:value_arg) do - proc do - call_count += 1 - 'Hello proc' - end - end - - before do - call_count = 0 - subject.freeze - end - - it 'does not call the proc immediately' do - expect(call_count).to eql(0) - end - - it 'returns proc return value' do - expect(subject.value).to eq('Hello proc') - end - - it 'freezes upon access' do - expect(subject.value).to be_frozen - end - end - end - - context 'freeze after calling #value' do - before do - subject.value - subject.freeze - end - - context 'object' do - it 'returns value' do - expect(subject.value).to equal(value_arg) - end - - it 'freezes value' do - expect(subject.value).to be_frozen - end - end - - context 'proc' do - call_count = 0 - let(:value_arg) do - proc do - call_count += 1 - 'Hello proc' - end - end - - before do - call_count = 0 - subject.freeze - end - - it 'does not call the proc immediately' do - expect(call_count).to eql(0) - end - - it 'returns proc return value' do - expect(subject.value).to eq('Hello proc') - end - - it 'freezes upon access' do - expect(subject.value).to be_frozen - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/outdatedness_status_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/outdatedness_status_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/outdatedness_status_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/outdatedness_status_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::OutdatednessStatus do - let(:status) { described_class.new } - - describe '#reasons' do - subject { status.reasons } - - context 'default' do - it { is_expected.to eql([]) } - end - - context 'one passed in' do - let(:reasons) do - [ - Nanoc::Int::OutdatednessReasons::CodeSnippetsModified, - ] - end - - let(:status) { described_class.new(reasons: reasons) } - - it { is_expected.to eql(reasons) } - end - - context 'two passed in' do - let(:reasons) do - [ - Nanoc::Int::OutdatednessReasons::CodeSnippetsModified, - Nanoc::Int::OutdatednessReasons::ContentModified, - ] - end - - let(:status) { described_class.new(reasons: reasons) } - - it { is_expected.to eql(reasons) } - end - end - - describe '#props' do - subject { status.props.active } - - context 'default' do - it { is_expected.to eql(Set.new) } - end - - context 'specific one passed in' do - let(:props) do - Nanoc::Int::Props.new(attributes: true) - end - - let(:status) { described_class.new(props: props) } - - it { is_expected.to eql(Set.new([:attributes])) } - end - end - - describe '#useful_to_apply' do - subject { status.useful_to_apply?(rule) } - - let(:status) { described_class.new(props: props) } - let(:props) { Nanoc::Int::Props.new } - let(:rule) { Nanoc::Int::OutdatednessRules::RulesModified } - - context 'no props' do - it { is_expected.to be } - end - - context 'some props' do - context 'same props' do - let(:props) { Nanoc::Int::Props.new(compiled_content: true, path: true) } - it { is_expected.not_to be } - end - - context 'different props' do - let(:props) { Nanoc::Int::Props.new(attributes: true) } - it { is_expected.to be } - end - end - - context 'all props' do - let(:props) { Nanoc::Int::Props.new(raw_content: true, attributes: true, compiled_content: true, path: true) } - it { is_expected.not_to be } - end - end - - describe '#update' do - subject { status.update(reason) } - - let(:reason) { Nanoc::Int::OutdatednessReasons::ContentModified } - - context 'no existing reason or props' do - it 'adds a reason' do - expect(subject.reasons).to eql([reason]) - end - end - - context 'existing reason' do - let(:status) { described_class.new(reasons: [old_reason]) } - - let(:old_reason) { Nanoc::Int::OutdatednessReasons::NotWritten } - - it 'adds a reason' do - expect(subject.reasons).to eql([old_reason, reason]) - end - end - - context 'existing props' do - let(:status) { described_class.new(props: Nanoc::Int::Props.new(attributes: true)) } - - it 'updates props' do - expect(subject.props.active).to eql(Set.new(%i[raw_content attributes compiled_content])) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/pattern_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/pattern_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/pattern_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/pattern_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,133 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Pattern do - describe '.from' do - it 'converts from string' do - pattern = described_class.from('/foo/x[ab]z/bar.*') - expect(pattern.match?('/foo/xaz/bar.html')).to eql(true) - expect(pattern.match?('/foo/xyz/bar.html')).to eql(false) - end - - it 'converts from regex' do - pattern = described_class.from(%r{\A/foo/x[ab]z/bar\..*\z}) - expect(pattern.match?('/foo/xaz/bar.html')).to eql(true) - expect(pattern.match?('/foo/xyz/bar.html')).to eql(false) - end - - it 'converts from pattern' do - pattern = described_class.from('/foo/x[ab]z/bar.*') - pattern = described_class.from(pattern) - expect(pattern.match?('/foo/xaz/bar.html')).to eql(true) - expect(pattern.match?('/foo/xyz/bar.html')).to eql(false) - end - - it 'converts from symbol' do - pattern = described_class.from(:'/foo/x[ab]z/bar.*') - expect(pattern.match?('/foo/xaz/bar.html')).to eql(true) - expect(pattern.match?('/foo/xyz/bar.html')).to eql(false) - end - - it 'errors on other inputs' do - expect { described_class.from(123) }.to raise_error(ArgumentError) - end - - it 'errors with a proper error message on other inputs' do - expect { described_class.from(nil) } - .to raise_error(ArgumentError, 'Do not know how to convert `nil` into a Nanoc::Pattern') - end - end - - describe '#initialize' do - it 'errors' do - expect { described_class.new('/stuff') } - .to raise_error(NotImplementedError) - end - end - - describe '#match?' do - it 'errors' do - expect { described_class.allocate.match?('/foo.md') } - .to raise_error(NotImplementedError) - end - end - - describe '#captures' do - it 'errors' do - expect { described_class.allocate.captures('/foo.md') } - .to raise_error(NotImplementedError) - end - end -end - -describe Nanoc::Int::RegexpPattern do - let(:pattern) { described_class.new(/the answer is (\d+)/) } - - describe '#match?' do - it 'matches' do - expect(pattern.match?('the answer is 42')).to eql(true) - expect(pattern.match?('the answer is donkey')).to eql(false) - end - end - - describe '#captures' do - it 'returns nil if it does not match' do - expect(pattern.captures('the answer is donkey')).to be_nil - end - - it 'returns array if it matches' do - expect(pattern.captures('the answer is 42')).to eql(['42']) - end - end - - describe '#to_s' do - subject { pattern.to_s } - - it 'returns the regex' do - expect(subject).to eq('(?-mix:the answer is (\d+))') - end - end -end - -describe Nanoc::Int::StringPattern do - describe '#match?' do - it 'matches simple strings' do - pattern = described_class.new('d*key') - - expect(pattern.match?('donkey')).to eql(true) - expect(pattern.match?('giraffe')).to eql(false) - end - - it 'matches with pathname option' do - pattern = described_class.new('/foo/*/bar/**/*.animal') - - expect(pattern.match?('/foo/x/bar/a/b/donkey.animal')).to eql(true) - expect(pattern.match?('/foo/x/bar/donkey.animal')).to eql(true) - expect(pattern.match?('/foo/x/railroad/donkey.animal')).to eql(false) - end - - it 'matches with extglob option' do - pattern = described_class.new('{b,gl}oat') - - expect(pattern.match?('boat')).to eql(true) - expect(pattern.match?('gloat')).to eql(true) - expect(pattern.match?('stoat')).to eql(false) - end - end - - describe '#captures' do - it 'returns nil' do - pattern = described_class.new('d*key') - expect(pattern.captures('donkey')).to be_nil - end - end - - describe '#to_s' do - let(:pattern) { described_class.new('/foo/*/bar/**/*.animal') } - - subject { pattern.to_s } - - it 'returns the regex' do - expect(subject).to eq('/foo/*/bar/**/*.animal') - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/processing_actions/filter_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/processing_actions/filter_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/processing_actions/filter_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/processing_actions/filter_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::ProcessingActions::Filter do - let(:action) { described_class.new(:foo, awesome: true) } - - describe '#serialize' do - subject { action.serialize } - it { is_expected.to eql([:filter, :foo, 'sJYzLjHGo1e4ytuDfnOLkqrt9QE=']) } - end - - describe '#to_s' do - subject { action.to_s } - it { is_expected.to eql('filter :foo, {:awesome=>true}') } - end - - describe '#inspect' do - subject { action.inspect } - it { is_expected.to eql('true}') } - end - - describe '#inspect' do - subject { action.inspect } - it { is_expected.to eql('') } - end - - describe '#update' do - context 'with nothing' do - subject { action.update } - its(:snapshot_names) { is_expected.to eql([:before_layout]) } - its(:paths) { is_expected.to eql(['/foo.md']) } - end - - context 'with snapshot name' do - subject { action.update(snapshot_names: [:zebra]) } - its(:snapshot_names) { is_expected.to eql(%i[before_layout zebra]) } - its(:paths) { is_expected.to eql(['/foo.md']) } - end - - context 'with paths' do - subject { action.update(paths: ['/donkey.md', '/giraffe.md']) } - its(:snapshot_names) { is_expected.to eql([:before_layout]) } - its(:paths) { is_expected.to eql(['/foo.md', '/donkey.md', '/giraffe.md']) } - end - end - - describe '#== and #eql?' do - context 'other action is equal' do - let(:action_a) { described_class.new([:erb], ['/foo.html']) } - let(:action_b) { described_class.new([:erb], ['/foo.html']) } - - it 'is ==' do - expect(action_a).to eq(action_b) - end - - it 'is eql?' do - expect(action_a).to eql(action_b) - end - end - - context 'other action has different name' do - let(:action_a) { described_class.new([:erb], ['/foo.html']) } - let(:action_b) { described_class.new([:haml], ['/foo.html']) } - - it 'is not ==' do - expect(action_a).not_to eq(action_b) - end - - it 'is not eql?' do - expect(action_a).not_to eql(action_b) - end - end - - context 'other action has different paths' do - let(:action_a) { described_class.new([:erb], ['/foo.html']) } - let(:action_b) { described_class.new([:erb], ['/foo.htm']) } - - it 'is not ==' do - expect(action_a).not_to eq(action_b) - end - - it 'is not eql?' do - expect(action_a).not_to eql(action_b) - end - end - - context 'other action is not a layout action' do - let(:action_a) { described_class.new([:erb], ['/foo.html']) } - let(:action_b) { :donkey } - - it 'is not ==' do - expect(action_a).not_to eq(action_b) - end - - it 'is not eql?' do - expect(action_a).not_to eql(action_b) - end - end - end - - describe '#hash' do - context 'other action is equal' do - let(:action_a) { described_class.new([:erb], ['/foo.html']) } - let(:action_b) { described_class.new([:erb], ['/foo.html']) } - - it 'is the same' do - expect(action_a.hash == action_b.hash).to eql(true) - end - end - - context 'other action has different name' do - let(:action_a) { described_class.new([:erb], ['/foo.html']) } - let(:action_b) { described_class.new([:haml], ['/foo.html']) } - - it 'is the same' do - expect(action_a.hash == action_b.hash).to eql(false) - end - end - - context 'other action has different paths' do - let(:action_a) { described_class.new([:erb], ['/foo.html']) } - let(:action_b) { described_class.new([:erb], ['/foo.htm']) } - - it 'is the same' do - expect(action_a.hash == action_b.hash).to eql(false) - end - end - - context 'other action is not a layout action' do - let(:action_a) { described_class.new([:erb], ['/foo.html']) } - let(:action_b) { :woof } - - it 'is the same' do - expect(action_a.hash == action_b.hash).to eql(false) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/processing_action_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/processing_action_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/processing_action_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/processing_action_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::ProcessingAction do - let(:action) { described_class.new } - - it 'is abstract' do - expect { action.serialize }.to raise_error(NotImplementedError) - expect { action.to_s }.to raise_error(NotImplementedError) - expect { action.inspect }.to raise_error(NotImplementedError) - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/props_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/props_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/props_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/props_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,436 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Props do - let(:props) { described_class.new } - - let(:props_all) do - described_class.new(raw_content: true, attributes: true, compiled_content: true, path: true) - end - - describe '#inspect' do - subject { props.inspect } - - context 'nothing active' do - it { is_expected.to eql('Props(____)') } - end - - context 'attributes active' do - let(:props) { described_class.new(attributes: true) } - it { is_expected.to eql('Props(_a__)') } - end - - context 'attributes and compiled_content active' do - let(:props) { described_class.new(attributes: true, compiled_content: true) } - it { is_expected.to eql('Props(_ac_)') } - end - - context 'compiled_content active' do - let(:props) { described_class.new(compiled_content: true) } - it { is_expected.to eql('Props(__c_)') } - end - end - - describe '#to_s' do - subject { props.to_s } - - context 'nothing active' do - it { is_expected.to eql('____') } - end - - context 'attributes active' do - let(:props) { described_class.new(attributes: true) } - it { is_expected.to eql('_a__') } - end - - context 'attributes and compiled_content active' do - let(:props) { described_class.new(attributes: true, compiled_content: true) } - it { is_expected.to eql('_ac_') } - end - - context 'compiled_content active' do - let(:props) { described_class.new(compiled_content: true) } - it { is_expected.to eql('__c_') } - end - end - - describe '#raw_content?' do - subject { props.raw_content? } - - context 'nothing active' do - it { is_expected.not_to be } - end - - context 'raw_content active' do - let(:props) { described_class.new(raw_content: true) } - it { is_expected.to be } - end - - context 'raw_content and compiled_content active' do - let(:props) { described_class.new(raw_content: true, compiled_content: true) } - it { is_expected.to be } - end - - context 'compiled_content active' do - let(:props) { described_class.new(compiled_content: true) } - it { is_expected.not_to be } - end - - context 'all active' do - let(:props) { described_class.new(raw_content: true, attributes: true, compiled_content: true, path: true) } - it { is_expected.to be } - end - - context 'raw_content is empty list' do - let(:props) { described_class.new(raw_content: []) } - it { is_expected.not_to be } - end - - context 'raw_content is non-empty list' do - let(:props) { described_class.new(raw_content: ['/asdf.*']) } - it { is_expected.to be } - end - end - - describe '#attributes?' do - subject { props.attributes? } - - context 'nothing active' do - it { is_expected.not_to be } - end - - context 'attributes active' do - let(:props) { described_class.new(attributes: true) } - it { is_expected.to be } - end - - context 'attributes and compiled_content active' do - let(:props) { described_class.new(attributes: true, compiled_content: true) } - it { is_expected.to be } - end - - context 'compiled_content active' do - let(:props) { described_class.new(compiled_content: true) } - it { is_expected.not_to be } - end - - context 'all active' do - let(:props) { described_class.new(raw_content: true, attributes: true, compiled_content: true, path: true) } - it { is_expected.to be } - end - - context 'attributes is empty list' do - let(:props) { described_class.new(attributes: []) } - it { is_expected.not_to be } - end - - context 'attributes is non-empty list' do - let(:props) { described_class.new(attributes: [:donkey]) } - it { is_expected.to be } - end - end - - describe '#compiled_content?' do - # … - end - - describe '#path?' do - # … - end - - describe '#merge' do - subject { props.merge(other_props).active } - - context 'nothing + nothing' do - let(:props) { described_class.new } - let(:other_props) { described_class.new } - - it { is_expected.to eql(Set.new) } - end - - context 'nothing + some' do - let(:props) { described_class.new } - let(:other_props) { described_class.new(raw_content: true) } - - it { is_expected.to eql(Set.new([:raw_content])) } - end - - context 'nothing + all' do - let(:props) { described_class.new } - let(:other_props) { props_all } - - it { is_expected.to eql(Set.new(%i[raw_content attributes compiled_content path])) } - end - - context 'some + nothing' do - let(:props) { described_class.new(compiled_content: true) } - let(:other_props) { described_class.new } - - it { is_expected.to eql(Set.new([:compiled_content])) } - end - - context 'some + others' do - let(:props) { described_class.new(compiled_content: true) } - let(:other_props) { described_class.new(raw_content: true) } - - it { is_expected.to eql(Set.new(%i[raw_content compiled_content])) } - end - - context 'some + all' do - let(:props) { described_class.new(compiled_content: true) } - let(:other_props) { props_all } - - it { is_expected.to eql(Set.new(%i[raw_content attributes compiled_content path])) } - end - - context 'all + nothing' do - let(:props) { props_all } - let(:other_props) { described_class.new } - - it { is_expected.to eql(Set.new(%i[raw_content attributes compiled_content path])) } - end - - context 'some + all' do - let(:props) { props_all } - let(:other_props) { described_class.new(compiled_content: true) } - - it { is_expected.to eql(Set.new(%i[raw_content attributes compiled_content path])) } - end - - context 'all + all' do - let(:props) { props_all } - let(:other_props) { props_all } - - it { is_expected.to eql(Set.new(%i[raw_content attributes compiled_content path])) } - end - end - - describe '#merge_attributes' do - let(:props_attrs_true) do - described_class.new(attributes: true) - end - - let(:props_attrs_false) do - described_class.new(attributes: false) - end - - let(:props_attrs_list_a) do - described_class.new(attributes: %i[donkey giraffe]) - end - - let(:props_attrs_list_b) do - described_class.new(attributes: %i[giraffe zebra]) - end - - subject { props.merge(other_props).attributes } - - context 'false + false' do - let(:props) { props_attrs_false } - let(:other_props) { props_attrs_false } - - it { is_expected.to be(false) } - end - - context 'false + true' do - let(:props) { props_attrs_false } - let(:other_props) { props_attrs_true } - - it { is_expected.to be(true) } - end - - context 'false + list' do - let(:props) { props_attrs_false } - let(:other_props) { props_attrs_list_a } - - it { is_expected.to be_a(Set) } - it { is_expected.to match_array(%i[donkey giraffe]) } - end - - context 'true + false' do - let(:props) { props_attrs_true } - let(:other_props) { props_attrs_false } - - it { is_expected.to be(true) } - end - - context 'true + true' do - let(:props) { props_attrs_true } - let(:other_props) { props_attrs_true } - - it { is_expected.to be(true) } - end - - context 'true + list' do - let(:props) { props_attrs_true } - let(:other_props) { props_attrs_list_a } - - it { is_expected.to be(true) } - end - - context 'list + false' do - let(:props) { props_attrs_list_a } - let(:other_props) { props_attrs_false } - - it { is_expected.to be_a(Set) } - it { is_expected.to match_array(%i[donkey giraffe]) } - end - - context 'list + true' do - let(:props) { props_attrs_list_a } - let(:other_props) { props_attrs_true } - - it { is_expected.to be(true) } - end - - context 'list + list' do - let(:props) { props_attrs_list_a } - let(:other_props) { props_attrs_list_b } - - it { is_expected.to be_a(Set) } - it { is_expected.to match_array(%i[donkey giraffe zebra]) } - end - end - - describe '#merge_raw_content' do - let(:props_raw_content_true) do - described_class.new(raw_content: true) - end - - let(:props_raw_content_false) do - described_class.new(raw_content: false) - end - - let(:props_raw_content_list_a) do - described_class.new(raw_content: %w[donkey giraffe]) - end - - let(:props_raw_content_list_b) do - described_class.new(raw_content: %w[giraffe zebra]) - end - - subject { props.merge(other_props).raw_content } - - context 'false + false' do - let(:props) { props_raw_content_false } - let(:other_props) { props_raw_content_false } - - it { is_expected.to be(false) } - end - - context 'false + true' do - let(:props) { props_raw_content_false } - let(:other_props) { props_raw_content_true } - - it { is_expected.to be(true) } - end - - context 'false + list' do - let(:props) { props_raw_content_false } - let(:other_props) { props_raw_content_list_a } - - it { is_expected.to be_a(Set) } - it { is_expected.to match_array(%w[donkey giraffe]) } - end - - context 'true + false' do - let(:props) { props_raw_content_true } - let(:other_props) { props_raw_content_false } - - it { is_expected.to be(true) } - end - - context 'true + true' do - let(:props) { props_raw_content_true } - let(:other_props) { props_raw_content_true } - - it { is_expected.to be(true) } - end - - context 'true + list' do - let(:props) { props_raw_content_true } - let(:other_props) { props_raw_content_list_a } - - it { is_expected.to be(true) } - end - - context 'list + false' do - let(:props) { props_raw_content_list_a } - let(:other_props) { props_raw_content_false } - - it { is_expected.to be_a(Set) } - it { is_expected.to match_array(%w[donkey giraffe]) } - end - - context 'list + true' do - let(:props) { props_raw_content_list_a } - let(:other_props) { props_raw_content_true } - - it { is_expected.to be(true) } - end - - context 'list + list' do - let(:props) { props_raw_content_list_a } - let(:other_props) { props_raw_content_list_b } - - it { is_expected.to be_a(Set) } - it { is_expected.to match_array(%w[donkey giraffe zebra]) } - end - end - - describe '#active' do - subject { props.active } - - context 'nothing active' do - let(:props) { described_class.new } - it { is_expected.to eql(Set.new) } - end - - context 'raw_content active' do - let(:props) { described_class.new(raw_content: true) } - it { is_expected.to eql(Set.new([:raw_content])) } - end - - context 'attributes active' do - let(:props) { described_class.new(attributes: true) } - it { is_expected.to eql(Set.new([:attributes])) } - end - - context 'compiled_content active' do - let(:props) { described_class.new(compiled_content: true) } - it { is_expected.to eql(Set.new([:compiled_content])) } - end - - context 'path active' do - let(:props) { described_class.new(path: true) } - it { is_expected.to eql(Set.new([:path])) } - end - - context 'attributes and compiled_content active' do - let(:props) { described_class.new(attributes: true, compiled_content: true) } - it { is_expected.to eql(Set.new(%i[attributes compiled_content])) } - end - - context 'all active' do - let(:props) { described_class.new(raw_content: true, attributes: true, compiled_content: true, path: true) } - it { is_expected.to eql(Set.new(%i[raw_content attributes compiled_content path])) } - end - end - - describe '#to_h' do - subject { props.to_h } - - context 'nothing' do - let(:props) { described_class.new } - it { is_expected.to eql(raw_content: false, attributes: false, compiled_content: false, path: false) } - end - - context 'some' do - let(:props) { described_class.new(attributes: true, compiled_content: true) } - it { is_expected.to eql(raw_content: false, attributes: true, compiled_content: true, path: false) } - end - - context 'all' do - let(:props) { props_all } - it { is_expected.to eql(raw_content: true, attributes: true, compiled_content: true, path: true) } - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/entities/site_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/entities/site_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/entities/site_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/entities/site_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Site do - describe '#freeze' do - let(:site) do - described_class.new( - config: config, - code_snippets: code_snippets, - data_source: Nanoc::Int::InMemDataSource.new(items, layouts), - ) - end - - let(:config) do - Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults - end - - let(:code_snippets) do - [ - Nanoc::Int::CodeSnippet.new('FOO = 123', 'hello.rb'), - Nanoc::Int::CodeSnippet.new('BAR = 123', 'hi.rb'), - ] - end - - let(:items) do - Nanoc::Int::ItemCollection.new( - config, - [ - Nanoc::Int::Item.new('foo', {}, '/foo.md'), - Nanoc::Int::Item.new('bar', {}, '/bar.md'), - ], - ) - end - - let(:layouts) do - Nanoc::Int::LayoutCollection.new( - config, - [ - Nanoc::Int::Layout.new('foo', {}, '/foo.md'), - Nanoc::Int::Layout.new('bar', {}, '/bar.md'), - ], - ) - end - - before do - site.freeze - end - - it 'freezes the configuration' do - expect(site.config).to be_frozen - end - - it 'freezes the configuration contents' do - expect(site.config.output_dir).to be_frozen - end - - it 'freezes items collection' do - expect(site.items).to be_frozen - end - - it 'freezes individual items' do - expect(site.items).to all(be_frozen) - end - - it 'freezes layouts collection' do - expect(site.layouts).to be_frozen - end - - it 'freezes individual layouts' do - expect(site.layouts).to all(be_frozen) - end - - it 'freezes code snippets collection' do - expect(site.code_snippets).to be_frozen - end - - it 'freezes individual code snippets' do - expect(site.code_snippets).to all(be_frozen) - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/errors/dependency_cycle_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/errors/dependency_cycle_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/errors/dependency_cycle_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/errors/dependency_cycle_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,6 +1,6 @@ # frozen_string_literal: true -describe Nanoc::Int::Errors::DependencyCycle do +describe Nanoc::Core::Errors::DependencyCycle do subject(:error) { described_class.new(stack) } let(:stack) do @@ -14,11 +14,11 @@ ] end - let(:rep_a) { Nanoc::Int::ItemRep.new(Nanoc::Int::Item.new('a', {}, '/a.md'), :default) } - let(:rep_b) { Nanoc::Int::ItemRep.new(Nanoc::Int::Item.new('b', {}, '/b.md'), :default) } - let(:rep_c) { Nanoc::Int::ItemRep.new(Nanoc::Int::Item.new('c', {}, '/c.md'), :default) } - let(:rep_d) { Nanoc::Int::ItemRep.new(Nanoc::Int::Item.new('d', {}, '/d.md'), :default) } - let(:rep_e) { Nanoc::Int::ItemRep.new(Nanoc::Int::Item.new('e', {}, '/e.md'), :default) } + let(:rep_a) { Nanoc::Core::ItemRep.new(Nanoc::Core::Item.new('a', {}, '/a.md'), :default) } + let(:rep_b) { Nanoc::Core::ItemRep.new(Nanoc::Core::Item.new('b', {}, '/b.md'), :default) } + let(:rep_c) { Nanoc::Core::ItemRep.new(Nanoc::Core::Item.new('c', {}, '/c.md'), :default) } + let(:rep_d) { Nanoc::Core::ItemRep.new(Nanoc::Core::Item.new('d', {}, '/d.md'), :default) } + let(:rep_e) { Nanoc::Core::ItemRep.new(Nanoc::Core::Item.new('e', {}, '/e.md'), :default) } it 'has an informative error message' do expected = <<~EOS diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/feature_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/feature_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/feature_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/feature_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Feature do - describe '.enabled?' do - subject { described_class.enabled?(feature_name) } - - let(:feature_name) { 'magic' } - - before do - Nanoc::Feature.reset_caches - ENV['NANOC_FEATURES'] = +'' - end - - context 'not set' do - it { is_expected.not_to be } - end - - context 'set to list not including feature' do - before { ENV['NANOC_FEATURES'] = 'foo,bar' } - it { is_expected.not_to be } - end - - context 'set to all' do - before { ENV['NANOC_FEATURES'] = 'all' } - it { is_expected.to be } - end - - context 'set to list including feature' do - before { ENV['NANOC_FEATURES'] = 'foo,magic,bar' } - it { is_expected.to be } - end - end - - describe '.enable' do - subject do - described_class.enable(feature_name) do - Nanoc::Feature.enabled?(feature_name) - end - end - - let(:feature_name) { 'magic' } - - before do - Nanoc::Feature.reset_caches - ENV['NANOC_FEATURES'] = +'' - end - - context 'not set' do - it { is_expected.to be } - - it 'unsets afterwards' do - expect(Nanoc::Feature.enabled?(feature_name)).not_to be - end - end - - context 'set to list not including feature' do - before { ENV['NANOC_FEATURES'] = 'foo,bar' } - it { is_expected.to be } - - it 'unsets afterwards' do - expect(Nanoc::Feature.enabled?(feature_name)).not_to be - end - end - - context 'set to all' do - before { ENV['NANOC_FEATURES'] = 'all' } - it { is_expected.to be } - end - - context 'set to list including feature' do - before { ENV['NANOC_FEATURES'] = 'foo,magic,bar' } - it { is_expected.to be } - end - end - - describe '.all_outdated' do - it 'refuses outdated features' do - # If this spec fails, there are features marked as experimental in the previous minor or major - # release, but not in the current one. Either remove the feature, or mark it as experimental - # in the current release. - expect(Nanoc::Feature.all_outdated).to be_empty - end - - describe 'fake outdated features' do - before { Nanoc::Feature.define('abc', version: '4.2.x') } - after { Nanoc::Feature.undefine('abc') } - - it 'detects outdated features' do - expect(Nanoc::Feature.all_outdated).to eq(['abc']) - end - end - end - - describe '.define and .undefine' do - let(:feature_name) { 'testing123' } - after { Nanoc::Feature.undefine(feature_name) if defined?(Nanoc::Feature::TESTING123) } - - it 'can define' do - Nanoc::Feature.define(feature_name, version: '4.3.x') - expect(Nanoc::Feature::TESTING123).not_to be_nil - end - - it 'can undefine' do - Nanoc::Feature.define(feature_name, version: '4.3.x') - Nanoc::Feature.undefine(feature_name) - expect { Nanoc::Feature::TESTING123 }.to raise_error(NameError) - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/filter_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/filter_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/filter_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/filter_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,275 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Filter do - describe '.define' do - context 'simple filter' do - let(:filter_name) { :b5355bbb4d772b9853d21be57da614dba521dbbb } - let(:filter_class) { Nanoc::Filter.named(filter_name) } - - before do - Nanoc::Filter.define(filter_name) do |content, _params| - content.upcase - end - end - - it 'defines a filter' do - expect(filter_class).not_to be_nil - end - - it 'defines a callable filter' do - expect(filter_class.new.run('foo', {})).to eql('FOO') - end - end - - context 'filter that accesses assigns' do - let(:filter_name) { :d7ed105d460e99a3d38f46af023d9490c140fdd9 } - let(:filter_class) { Nanoc::Filter.named(filter_name) } - let(:filter) { filter_class.new(assigns) } - let(:assigns) { { animal: 'Giraffe' } } - - before do - Nanoc::Filter.define(filter_name) do |_content, _params| - @animal - end - end - - it 'can access assigns' do - expect(filter.setup_and_run(:__irrelevant__, {})).to eq('Giraffe') - end - end - end - - describe '.named!' do - it 'returns filter if exists' do - expect(Nanoc::Filter.named!(:erb)).not_to be_nil - expect(Nanoc::Filter.named!(:erb).identifier).to eq(:erb) - end - - it 'raises if non-existent' do - expect { Nanoc::Filter.named!(:ajklsdfklasjflkd) } - .to raise_error( - Nanoc::Int::Errors::UnknownFilter, - 'The requested filter, “ajklsdfklasjflkd”, does not exist.', - ) - end - end - - describe 'assigns' do - context 'no assigns given' do - subject { described_class.new } - - it 'has empty assigns' do - expect(subject.instance_eval { @assigns }).to eq({}) - end - end - - context 'assigns given' do - subject { described_class.new(foo: 'bar') } - - it 'has assigns' do - expect(subject.instance_eval { @assigns }).to eq(foo: 'bar') - end - - it 'can access assigns with @' do - expect(subject.instance_eval { @foo }).to eq('bar') - end - - it 'can access assigns without @' do - expect(subject.instance_eval { foo }).to eq('bar') - end - end - end - - describe '#run' do - context 'no subclass' do - subject { described_class.new.run('stuff') } - - it 'errors' do - expect { subject }.to raise_error(NotImplementedError) - end - end - - context 'subclass' do - # TODO - end - end - - describe '#filename' do - subject { described_class.new(assigns).filename } - - context 'assigns contains item + item rep' do - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/donkey.md') } - let(:item_rep) { Nanoc::Int::ItemRep.new(item, :animal) } - let(:assigns) { { item: item, item_rep: item_rep } } - - it { is_expected.to eq('item /donkey.md (rep animal)') } - end - - context 'assigns contains layout' do - let(:layout) { Nanoc::Int::Layout.new('asdf', {}, '/donkey.md') } - let(:assigns) { { layout: layout } } - - it { is_expected.to eq('layout /donkey.md') } - end - - context 'assigns contains neither' do - let(:assigns) { {} } - - it { is_expected.to eq('?') } - end - end - - describe '.always_outdated? + .always_outdated' do - context 'not always outdated' do - let(:filter_class) do - Class.new(Nanoc::Filter) do - identifier :bea22a356b6b031cea1e615087179803818c6a53 - - def run(content, _params) - content.upcase - end - end - end - - it 'is not always outdated' do - expect(filter_class).not_to be_always_outdated - end - end - - context 'always outdated' do - let(:filter_class) do - Class.new(Nanoc::Filter) do - identifier :d7413fa71223e5e69b03a0abfa25806e07e14f3a - - always_outdated - - def run(content, _params) - content.upcase - end - end - end - - it 'is always outdated' do - expect(filter_class).to be_always_outdated - end - end - end - - describe '#depend_on' do - subject { filter.depend_on(item_views) } - - let(:filter) { Nanoc::Filters::ERB.new(assigns) } - let(:item_views) { [item_view] } - - let(:item) { Nanoc::Int::Item.new('foo', {}, '/stuff.md') } - let(:item_view) { Nanoc::CompilationItemView.new(item, view_context) } - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } - - let(:view_context) do - Nanoc::ViewContextForCompilation.new( - reps: reps, - items: Nanoc::Int::ItemCollection.new(config), - dependency_tracker: dependency_tracker, - compilation_context: double(:compilation_context), - snapshot_repo: double(:snapshot_repo), - ) - end - - let(:dependency_tracker) { Nanoc::Int::DependencyTracker.new(dependency_store) } - let(:dependency_store) { Nanoc::Int::DependencyStore.new(empty_items, empty_layouts, config) } - - let(:empty_items) { Nanoc::Int::ItemCollection.new(config) } - let(:empty_layouts) { Nanoc::Int::LayoutCollection.new(config) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - let(:reps) { Nanoc::Int::ItemRepRepo.new } - - let(:assigns) do - { - item: item_view, - } - end - - context 'reps exist' do - before { reps << rep } - - context 'rep is compiled' do - before do - rep.compiled = true - end - - example do - expect { subject }.not_to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency)) - end - - it 'creates dependency' do - expect { subject } - .to create_dependency_on(item_view) - end - end - - context 'rep is not compiled' do - example do - fiber = Fiber.new { subject } - - # resume 1 - res = fiber.resume - expect(res).to be_a(Nanoc::Int::Errors::UnmetDependency) - expect(res.rep).to eql(rep) - - # resume 2 - expect(fiber.resume).not_to be_a(Nanoc::Int::Errors::UnmetDependency) - end - end - - context 'multiple reps exist' do - let(:other_rep) { Nanoc::Int::ItemRep.new(item, :default) } - - before do - reps << other_rep - rep.compiled = false - other_rep.compiled = false - end - - it 'yields an unmet dependency error twice' do - fiber = Fiber.new { subject } - - # resume 1 - res = fiber.resume - expect(res).to be_a(Nanoc::Int::Errors::UnmetDependency) - expect(res.rep).to eql(rep) - - # resume 2 - res = fiber.resume - expect(res).to be_a(Nanoc::Int::Errors::UnmetDependency) - expect(res.rep).to eql(other_rep) - - # resume 3 - expect(fiber.resume).not_to be_a(Nanoc::Int::Errors::UnmetDependency) - end - end - end - - context 'no reps exist' do - context 'textual' do - it 'creates dependency' do - expect { subject } - .to create_dependency_on(item_view) - end - end - - context 'binary' do - let(:item) { Nanoc::Int::Item.new(content, {}, '/stuff.md') } - - let(:filename) { File.expand_path('foo.dat') } - let(:content) { Nanoc::Int::BinaryContent.new(filename) } - - it 'creates dependency' do - expect { subject } - .to create_dependency_on(item_view) - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/item_rep_writer_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/item_rep_writer_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/item_rep_writer_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/item_rep_writer_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,149 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::ItemRepWriter do - describe '#write' do - let(:raw_path) { Dir.getwd + '/output/blah.dat' } - - let(:item) { Nanoc::Int::Item.new(orig_content, {}, '/foo') } - - let(:item_rep) do - Nanoc::Int::ItemRep.new(item, :default).tap do |ir| - ir.raw_paths = raw_paths - end - end - - let(:snapshot_contents) do - { - last: Nanoc::Int::TextualContent.new('last content'), - donkey: Nanoc::Int::TextualContent.new('donkey content'), - } - end - - let(:snapshot_name) { :donkey } - - let(:raw_paths) do - { snapshot_name => [raw_path] } - end - - let(:snapshot_repo) { Nanoc::Int::SnapshotRepo.new } - - let(:written_paths) { [] } - - subject { described_class.new.write(item_rep, snapshot_repo, snapshot_name, written_paths) } - - before do - expect(File.directory?('output')).to be_falsy - - snapshot_contents.each_pair do |key, value| - snapshot_repo.set(item_rep, key, value) - end - end - - context 'binary item rep' do - let(:orig_content) { Nanoc::Int::BinaryContent.new(File.expand_path('foo.dat')) } - - let(:snapshot_contents) do - { - last: Nanoc::Int::BinaryContent.new(File.expand_path('input-last.dat')), - donkey: Nanoc::Int::BinaryContent.new(File.expand_path('input-donkey.dat')), - } - end - - before do - File.write(snapshot_contents[:last].filename, 'binary last stuff') - File.write(snapshot_contents[:donkey].filename, 'binary donkey stuff') - end - - it 'copies contents' do - expect(Nanoc::Int::NotificationCenter).to receive(:post) - .with(:rep_write_started, item_rep, Dir.getwd + '/output/blah.dat') - expect(Nanoc::Int::NotificationCenter).to receive(:post) - .with(:rep_write_ended, item_rep, true, Dir.getwd + '/output/blah.dat', true, true) - - subject - - expect(File.read('output/blah.dat')).to eql('binary donkey stuff') - end - - it 'uses hard links' do - subject - - input = File.stat(snapshot_contents[:donkey].filename) - output = File.stat('output/blah.dat') - - expect(input.ino).to eq(output.ino) - end - - context 'output file already exists' do - let(:old_mtime) { Time.at((Time.now - 600).to_i) } - - before do - FileUtils.mkdir_p('output') - File.write('output/blah.dat', old_content) - FileUtils.touch('output/blah.dat', mtime: old_mtime) - end - - context 'file is identical' do - let(:old_content) { 'binary donkey stuff' } - - it 'keeps mtime' do - subject - expect(File.mtime('output/blah.dat')).to eql(old_mtime) - end - end - - context 'file is not identical' do - let(:old_content) { 'other binary donkey stuff' } - - it 'updates mtime' do - subject - expect(File.mtime('output/blah.dat')).to be > (Time.now - 1) - end - end - end - end - - context 'textual item rep' do - let(:orig_content) { Nanoc::Int::TextualContent.new('Hallo Welt') } - - it 'writes' do - expect(Nanoc::Int::NotificationCenter).to receive(:post) - .with(:rep_write_started, item_rep, Dir.getwd + '/output/blah.dat') - expect(Nanoc::Int::NotificationCenter).to receive(:post) - .with(:rep_write_ended, item_rep, false, Dir.getwd + '/output/blah.dat', true, true) - - subject - - expect(File.read('output/blah.dat')).to eql('donkey content') - end - - context 'output file already exists' do - let(:old_mtime) { Time.at((Time.now - 600).to_i) } - - before do - FileUtils.mkdir_p('output') - File.write('output/blah.dat', old_content) - FileUtils.touch('output/blah.dat', mtime: old_mtime) - end - - context 'file is identical' do - let(:old_content) { 'donkey content' } - - it 'keeps mtime' do - subject - expect(File.mtime('output/blah.dat')).to eql(old_mtime) - end - end - - context 'file is not identical' do - let(:old_content) { 'other donkey content' } - - it 'updates mtime' do - subject - expect(File.mtime('output/blah.dat')).to be > (Time.now - 1) - end - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/repos/aggregate_data_source_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/repos/aggregate_data_source_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/repos/aggregate_data_source_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/repos/aggregate_data_source_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::AggregateDataSource, stdio: true do - let(:klass_1) do - Class.new(Nanoc::DataSource) do - def items - [Nanoc::Int::Item.new('One', {}, '/one.md')] - end - - def item_changes - %i[one_foo one_bar] - end - - def layouts - [Nanoc::Int::Layout.new('One', {}, '/one.md')] - end - - def layout_changes - %i[one_foo one_bar] - end - end - end - - let(:klass_2) do - Class.new(Nanoc::DataSource) do - def items - [Nanoc::Int::Item.new('Two', {}, '/two.md')] - end - - def item_changes - %i[two_foo two_bar] - end - - def layouts - [Nanoc::Int::Layout.new('Two', {}, '/two.md')] - end - - def layout_changes - %i[two_foo two_bar] - end - end - end - - let(:data_source_1) do - klass_1.new({}, nil, nil, {}) - end - - let(:data_source_2) do - klass_2.new({}, nil, nil, {}) - end - - subject(:data_source) do - described_class.new([data_source_1, data_source_2], {}) - end - - describe '#items' do - subject { data_source.items } - - it 'contains all items' do - expect(subject).to match_array(data_source_1.items + data_source_2.items) - end - end - - describe '#layouts' do - subject { data_source.layouts } - - it 'contains all layouts' do - expect(subject).to match_array(data_source_1.layouts + data_source_2.layouts) - end - end - - describe '#item_changes' do - subject { data_source.item_changes } - - it 'yields changes from both' do - expect(subject).to match_array(data_source_1.item_changes + data_source_2.item_changes) - end - end - - describe '#layout_changes' do - subject { data_source.layout_changes } - - it 'yields changes from both' do - expect(subject).to match_array(data_source_1.layout_changes + data_source_2.layout_changes) - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/repos/checksum_store_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/repos/checksum_store_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/repos/checksum_store_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/repos/checksum_store_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::ChecksumStore do - let(:store) { described_class.new(config: config, objects: objects) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - let(:objects) { [item, code_snippet] } - - let(:item) { Nanoc::Int::Item.new('asdf', item_attributes, '/foo.md') } - let(:other_item) { Nanoc::Int::Item.new('asdf', other_item_attributes, '/sneaky.md') } - - let(:item_attributes) { {} } - let(:other_item_attributes) { {} } - - let(:code_snippet) { Nanoc::Int::CodeSnippet.new('def hi ; end', 'lib/foo.rb') } - let(:other_code_snippet) { Nanoc::Int::CodeSnippet.new('def ho ; end', 'lib/bar.rb') } - - context 'nothing added' do - it 'has no checksum' do - expect(store[item]).to be_nil - end - - it 'has no content checksum' do - expect(store.content_checksum_for(item)).to be_nil - end - - it 'has no attributes checksum' do - expect(store.attributes_checksum_for(item)).to be_nil - end - end - - context 'setting content on known non-document' do - before { store.add(code_snippet) } - - it 'has checksum' do - expect(store[code_snippet]).not_to be_nil - end - - it 'has no content checksum' do - expect(store.content_checksum_for(code_snippet)).to be_nil - end - - it 'has no attributes checksum' do - expect(store.attributes_checksum_for(code_snippet)).to be_nil - end - - context 'after storing and loading' do - before do - store.store - store.load - end - - it 'has checksum' do - expect(store[code_snippet]).not_to be_nil - end - end - end - - context 'setting content on unknown non-document' do - before { store.add(other_code_snippet) } - - it 'has checksum' do - expect(store[other_code_snippet]).not_to be_nil - end - - it 'has no content checksum' do - expect(store.content_checksum_for(other_code_snippet)).to be_nil - end - - it 'has no attributes checksum' do - expect(store.attributes_checksum_for(other_code_snippet)).to be_nil - end - - context 'after storing and loading' do - before do - store.store - store.load - end - - it 'has no checksum' do - expect(store[other_code_snippet]).to be_nil - end - end - end - - context 'setting content on known item' do - before { store.add(item) } - - it 'has checksum' do - expect(store[item]).not_to be_nil - end - - it 'has content checksum' do - expect(store.content_checksum_for(item)).not_to be_nil - end - - it 'has attributes checksum' do - expect(store.attributes_checksum_for(item)).not_to be_nil - expect(store.attributes_checksum_for(item)).to eq({}) - end - - context 'item has attributes' do - let(:item_attributes) { { animal: 'donkey' } } - - it 'has attribute checksum for specified attribute' do - expect(store.attributes_checksum_for(item)).to have_key(:animal) - end - end - - context 'after storing and loading' do - before do - store.store - store.load - end - - it 'has checksum' do - expect(store[item]).not_to be_nil - end - end - end - - context 'setting content on unknown item' do - before { store.add(other_item) } - - it 'has checksum' do - expect(store[other_item]).not_to be_nil - end - - it 'has content checksum' do - expect(store.content_checksum_for(other_item)).not_to be_nil - end - - it 'has attributes checksum' do - expect(store.attributes_checksum_for(other_item)).not_to be_nil - end - - context 'item has attributes' do - let(:other_item_attributes) { { location: 'Bernauer Str.' } } - - it 'has attribute checksum for specified attribute' do - expect(store.attributes_checksum_for(other_item)).to have_key(:location) - end - end - - context 'after storing and loading' do - before do - store.store - store.load - end - - it 'has no checksum' do - expect(store[other_item]).to be_nil - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/repos/compiled_content_cache_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/repos/compiled_content_cache_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/repos/compiled_content_cache_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/repos/compiled_content_cache_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::CompiledContentCache do - let(:cache) { described_class.new(config: config) } - - let(:items) { [item] } - - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') } - let(:item_rep) { Nanoc::Int::ItemRep.new(item, :default) } - - let(:other_item) { Nanoc::Int::Item.new('asdf', {}, '/sneaky.md') } - let(:other_item_rep) { Nanoc::Int::ItemRep.new(other_item, :default) } - - let(:content) { Nanoc::Int::Content.create('omg') } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - it 'has no content by default' do - expect(cache[item_rep]).to be_nil - end - - context 'setting content on known item' do - before { cache[item_rep] = { last: content } } - - it 'has content' do - expect(cache[item_rep][:last].string).to eql('omg') - end - - context 'after storing and loading' do - before do - cache.store - cache.load - end - - it 'has content' do - expect(cache[item_rep][:last].string).to eql('omg') - end - end - end - - context 'setting content on unknown item' do - before { cache[other_item_rep] = { last: content } } - - it 'has content' do - expect(cache[other_item_rep][:last].string).to eql('omg') - end - - context 'after storing and loading' do - before do - cache.store - cache.load - end - - it 'has content' do - expect(cache[other_item_rep][:last].string).to eql('omg') - end - end - - context 'after pruning' do - before do - cache.prune(items: items) - end - - it 'has no content' do - expect(cache[other_item_rep]).to be_nil - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/repos/config_loader_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/repos/config_loader_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/repos/config_loader_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/repos/config_loader_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,298 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::ConfigLoader do - let(:loader) { described_class.new } - - describe '#new_from_cwd' do - subject { loader.new_from_cwd } - - context 'no config file present' do - it 'errors' do - expect { subject }.to raise_error( - Nanoc::Int::ConfigLoader::NoConfigFileFoundError, - ) - end - end - - context 'YAML config file present' do - before do - File.write('nanoc.yaml', YAML.dump(foo: 'bar')) - end - - it 'returns a configuration' do - expect(subject).to be_a(Nanoc::Int::Configuration) - end - - it 'has the defaults' do - expect(subject[:output_dir]).to eq('output') - end - - it 'has the custom option' do - expect(subject[:foo]).to eq('bar') - end - end - - context 'TOML config file present' do - around do |ex| - Nanoc::Feature.enable(Nanoc::Feature::TOML) do - ex.run - end - end - - before do - File.write('nanoc.toml', 'foo = "bar"') - end - - it 'returns a configuration' do - expect(subject).to be_a(Nanoc::Int::Configuration) - end - - it 'has the defaults' do - expect(subject[:output_dir]).to eq('output') - end - - it 'has the custom option' do - expect(subject[:foo]).to eq('bar') - end - end - - context 'YAML config file and YAML parent present' do - before do - File.write('nanoc.yaml', YAML.dump(parent_config_file: 'parent.yaml')) - File.write('parent.yaml', YAML.dump(foo: 'bar')) - end - - it 'returns the configuration' do - expect(subject).to be_a(Nanoc::Int::Configuration) - end - - it 'has the defaults' do - expect(subject[:output_dir]).to eq('output') - end - - it 'has the custom option' do - expect(subject[:foo]).to eq('bar') - end - - it 'does not include parent config option' do - expect(subject[:parent_config_file]).to be_nil - end - end - - context 'TOML config file and TOML parent present' do - around do |ex| - Nanoc::Feature.enable(Nanoc::Feature::TOML) do - ex.run - end - end - - before do - File.write('nanoc.toml', 'parent_config_file = "parent.toml"') - File.write('parent.toml', 'foo = "bar"') - end - - it 'returns the configuration' do - expect(subject).to be_a(Nanoc::Int::Configuration) - end - - it 'has the defaults' do - expect(subject[:output_dir]).to eq('output') - end - - it 'has the custom option' do - expect(subject[:foo]).to eq('bar') - end - - it 'does not include parent config option' do - expect(subject[:parent_config_file]).to be_nil - end - end - - context 'config file present, environment defined' do - let(:active_env_name) { 'default' } - - let(:config) do - { - foo: 'bar', - tofoo: 'bar', - environments: { - test: { foo: 'test-bar' }, - default: { foo: 'default-bar' }, - }, - } - end - - before do - File.write('nanoc.yaml', YAML.dump(config)) - end - - before do - expect(ENV).to receive(:fetch).with('NANOC_ENV', 'default').and_return(active_env_name) - end - - it 'returns the configuration' do - expect(subject).to be_a(Nanoc::Int::Configuration) - end - - it 'has option defined not within environments' do - expect(subject[:tofoo]).to eq('bar') - end - - context 'current env is test' do - let(:active_env_name) { 'test' } - - it 'has the test environment custom option' do - expect(subject[:foo]).to eq('test-bar') - end - end - - it 'has the default environment custom option' do - expect(subject[:foo]).to eq('default-bar') - end - end - end - - describe '.cwd_is_nanoc_site? + .config_filename_for_cwd' do - context 'no config files' do - it 'is not considered a nanoc site dir' do - expect(described_class.cwd_is_nanoc_site?).to eq(false) - expect(described_class.config_filename_for_cwd).to be_nil - end - end - - context 'nanoc.yaml config file' do - before do - File.write('nanoc.yaml', 'stuff') - end - - it 'is considered a nanoc site dir' do - expect(described_class.cwd_is_nanoc_site?).to eq(true) - expect(described_class.config_filename_for_cwd).to eq(File.expand_path('nanoc.yaml')) - end - end - - context 'config.yaml config file' do - before do - File.write('config.yaml', 'stuff') - end - - it 'is considered a nanoc site dir' do - expect(described_class.cwd_is_nanoc_site?).to eq(true) - expect(described_class.config_filename_for_cwd).to eq(File.expand_path('config.yaml')) - end - end - end - - describe '#apply_parent_config' do - subject { loader.apply_parent_config(config, processed_paths) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd, hash: { foo: 'bar' }) } - - let(:processed_paths) { ['nanoc.yaml'] } - - context 'no parent_config_file' do - it 'returns self' do - expect(subject).to eq(config) - end - end - - context 'parent config file is set' do - let(:config) do - Nanoc::Int::Configuration.new(dir: Dir.getwd, hash: { parent_config_file: 'foo.yaml', foo: 'bar' }) - end - - context 'parent config file is not present' do - it 'errors' do - expect { subject }.to raise_error( - Nanoc::Int::ConfigLoader::NoParentConfigFileFoundError, - ) - end - end - - context 'parent config file is present' do - context 'parent-child cycle' do - before do - File.write('foo.yaml', 'parent_config_file: bar.yaml') - File.write('bar.yaml', 'parent_config_file: foo.yaml') - end - - it 'errors' do - expect { subject }.to raise_error( - Nanoc::Int::ConfigLoader::CyclicalConfigFileError, - ) - end - end - - context 'self parent-child cycle' do - before do - File.write('foo.yaml', 'parent_config_file: foo.yaml') - end - - it 'errors' do - expect { subject }.to raise_error( - Nanoc::Int::ConfigLoader::CyclicalConfigFileError, - ) - end - end - - context 'no parent-child cycle' do - before do - File.write('foo.yaml', 'animal: giraffe') - end - - it 'returns a configuration' do - expect(subject).to be_a(Nanoc::Int::Configuration) - end - - it 'has no defaults (added in #new_from_cwd only)' do - expect(subject[:output_dir]).to be_nil - end - - it 'inherits options from parent' do - expect(subject[:animal]).to eq('giraffe') - end - - it 'takes options from child' do - expect(subject[:foo]).to eq('bar') - end - - it 'does not include parent config option' do - expect(subject[:parent_config_file]).to be_nil - end - end - - context 'long parent chain' do - before do - File.write('foo.yaml', "parrots: 43\nparent_config_file: bar.yaml\n") - File.write('bar.yaml', "day_one: lasers\nslugs: false\n") - end - - it 'returns a configuration' do - expect(subject).to be_a(Nanoc::Int::Configuration) - end - - it 'has no defaults (added in #new_from_cwd only)' do - expect(subject[:output_dir]).to be_nil - end - - it 'inherits options from grandparent' do - expect(subject[:day_one]).to eq('lasers') - expect(subject[:slugs]).to eq(false) - end - - it 'inherits options from parent' do - expect(subject[:parrots]).to eq(43) - end - - it 'takes options from child' do - expect(subject[:foo]).to eq('bar') - end - - it 'does not include parent config option' do - expect(subject[:parent_config_file]).to be_nil - end - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/repos/data_source_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/repos/data_source_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/repos/data_source_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/repos/data_source_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::DataSource, stdio: true do - subject(:data_source) do - described_class.new({}, nil, nil, {}) - end - - it 'has an empty #up implementation' do - data_source.up - end - - it 'has an empty #down implementation' do - data_source.down - end - - it 'returns empty #items' do - expect(data_source.items).to be_empty - end - - it 'returns empty #layouts' do - expect(data_source.layouts).to be_empty - end - - describe '#new_item' do - it 'supports checksum data' do - item = data_source.new_item('stuff', { title: 'Stuff!' }, '/asdf', checksum_data: 'abcdef') - - expect(item.content.string).to eql('stuff') - expect(item.attributes[:title]).to eql('Stuff!') - expect(item.identifier).to eql(Nanoc::Identifier.new('/asdf')) - expect(item.checksum_data).to eql('abcdef') - end - - it 'supports content/attributes checksum data' do - item = data_source.new_item('stuff', { title: 'Stuff!' }, '/asdf', content_checksum_data: 'con-cs', attributes_checksum_data: 'attr-cs') - - expect(item.content.string).to eql('stuff') - expect(item.attributes[:title]).to eql('Stuff!') - expect(item.identifier).to eql(Nanoc::Identifier.new('/asdf')) - expect(item.content_checksum_data).to eql('con-cs') - expect(item.attributes_checksum_data).to eql('attr-cs') - end - end - - describe '#new_layout' do - it 'supports checksum data' do - layout = data_source.new_layout('stuff', { title: 'Stuff!' }, '/asdf', checksum_data: 'abcdef') - - expect(layout.content.string).to eql('stuff') - expect(layout.attributes[:title]).to eql('Stuff!') - expect(layout.identifier).to eql(Nanoc::Identifier.new('/asdf')) - expect(layout.checksum_data).to eql('abcdef') - end - - it 'supports content/attributes checksum data' do - layout = data_source.new_layout('stuff', { title: 'Stuff!' }, '/asdf', content_checksum_data: 'con-cs', attributes_checksum_data: 'attr-cs') - - expect(layout.content.string).to eql('stuff') - expect(layout.attributes[:title]).to eql('Stuff!') - expect(layout.identifier).to eql(Nanoc::Identifier.new('/asdf')) - expect(layout.content_checksum_data).to eql('con-cs') - expect(layout.attributes_checksum_data).to eql('attr-cs') - end - end - - describe '#item_changes' do - subject { data_source.item_changes } - - it 'warns' do - expect { subject }.to output("Caution: Data source nil does not implement #item_changes; live compilation will not pick up changes in this data source.\n").to_stderr - end - - it 'never yields anything' do - q = SizedQueue.new(1) - Thread.new { subject.each { |c| q << c } } - sleep 0.1 - expect { q.pop(true) }.to raise_error(ThreadError) - end - end - - describe '#layout_changes' do - subject { data_source.layout_changes } - - it 'warns' do - expect { subject }.to output("Caution: Data source nil does not implement #layout_changes; live compilation will not pick up changes in this data source.\n").to_stderr - end - - it 'never yields anything' do - q = SizedQueue.new(1) - Thread.new { subject.each { |c| q << c } } - sleep 0.1 - expect { q.pop(true) }.to raise_error(ThreadError) - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/repos/dependency_store_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/repos/dependency_store_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/repos/dependency_store_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/repos/dependency_store_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,515 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::DependencyStore do - let(:store) { described_class.new(items, layouts, config) } - - let(:item_a) { Nanoc::Int::Item.new('a', {}, '/a.md') } - let(:item_b) { Nanoc::Int::Item.new('b', {}, '/b.md') } - let(:item_c) { Nanoc::Int::Item.new('c', {}, '/c.md') } - - let(:layout_a) { Nanoc::Int::Layout.new('la', {}, '/la.md') } - let(:layout_b) { Nanoc::Int::Layout.new('lb', {}, '/lb.md') } - - let(:items) { Nanoc::Int::ItemCollection.new(config, [item_a, item_b, item_c]) } - let(:layouts) { Nanoc::Int::LayoutCollection.new(config, [layout_a, layout_b]) } - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - it 'is empty by default' do - expect(store.objects_causing_outdatedness_of(item_a)).to be_empty - expect(store.objects_causing_outdatedness_of(item_b)).to be_empty - expect(store.objects_causing_outdatedness_of(item_c)).to be_empty - expect(store.objects_causing_outdatedness_of(layout_a)).to be_empty - expect(store.objects_causing_outdatedness_of(layout_b)).to be_empty - end - - describe '#dependencies_causing_outdatedness_of' do - context 'no dependencies' do - it 'returns nothing for each' do - expect(store.dependencies_causing_outdatedness_of(item_a)).to be_empty - expect(store.dependencies_causing_outdatedness_of(item_b)).to be_empty - expect(store.dependencies_causing_outdatedness_of(item_c)).to be_empty - end - end - - context 'one dependency' do - context 'dependency on config, no props' do - before do - store.record_dependency(item_a, config) - end - - it 'returns one dependency' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps.size).to eql(1) - end - - it 'returns dependency from a onto config' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps[0].from).to eql(config) - expect(deps[0].to).to eql(item_a) - end - - it 'returns true for all props by default' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps[0].props.raw_content?).to eq(true) - expect(deps[0].props.attributes?).to eq(true) - expect(deps[0].props.compiled_content?).to eq(true) - expect(deps[0].props.path?).to eq(true) - end - - it 'returns nothing for the others' do - expect(store.dependencies_causing_outdatedness_of(item_b)).to be_empty - expect(store.dependencies_causing_outdatedness_of(item_c)).to be_empty - end - end - - context 'dependency on config, generic attributes prop' do - before do - store.record_dependency(item_a, config, attributes: true) - end - - it 'returns false for all unspecified props' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps[0].props.raw_content?).to eq(false) - expect(deps[0].props.compiled_content?).to eq(false) - expect(deps[0].props.path?).to eq(false) - end - - it 'returns the specified props' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps[0].props.attributes?).to eq(true) - end - end - - context 'dependency on config, specific attributes prop' do - before do - store.record_dependency(item_a, config, attributes: [:donkey]) - end - - it 'returns false for all unspecified props' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps[0].props.raw_content?).to eq(false) - expect(deps[0].props.compiled_content?).to eq(false) - expect(deps[0].props.path?).to eq(false) - end - - it 'returns the specified props' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps[0].props.attributes?).to eq(true) - expect(deps[0].props.attributes).to contain_exactly(:donkey) - end - end - - context 'dependency on items, generic prop' do - before do - store.record_dependency(item_a, items) - end - - it 'creates one dependency' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps.size).to eql(1) - end - - it 'returns true for all props' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps[0].props.raw_content?).to be - expect(deps[0].props.compiled_content?).to be - expect(deps[0].props.path?).to be - expect(deps[0].props.attributes?).to be - end - end - - context 'no props' do - before do - store.record_dependency(item_a, item_b) - end - - it 'returns one dependency' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps.size).to eql(1) - end - - it 'returns dependency from b to a' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps[0].from).to eql(item_b) - expect(deps[0].to).to eql(item_a) - end - - it 'returns true for all props by default' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps[0].props.raw_content?).to eq(true) - expect(deps[0].props.attributes?).to eq(true) - expect(deps[0].props.compiled_content?).to eq(true) - expect(deps[0].props.path?).to eq(true) - end - - it 'returns nothing for the others' do - expect(store.dependencies_causing_outdatedness_of(item_b)).to be_empty - expect(store.dependencies_causing_outdatedness_of(item_c)).to be_empty - end - end - - context 'one prop' do - before do - store.record_dependency(item_a, item_b, compiled_content: true) - end - - it 'returns false for all unspecified props' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps[0].props.raw_content?).to eq(false) - expect(deps[0].props.attributes?).to eq(false) - expect(deps[0].props.path?).to eq(false) - end - - it 'returns the specified props' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps[0].props.compiled_content?).to eq(true) - end - end - - context 'two props' do - before do - store.record_dependency(item_a, item_b, compiled_content: true) - store.record_dependency(item_a, item_b, attributes: true) - end - - it 'returns false for all unspecified props' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps[0].props.raw_content?).to eq(false) - expect(deps[0].props.path?).to eq(false) - end - - it 'returns the specified props' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps[0].props.attributes?).to eq(true) - expect(deps[0].props.compiled_content?).to eq(true) - end - end - end - - context 'two dependency in a chain' do - before do - store.record_dependency(item_a, item_b) - store.record_dependency(item_b, item_c) - end - - it 'returns one dependency for object A' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps.size).to eql(1) - expect(deps[0].from).to eql(item_b) - end - - it 'returns one dependency for object B' do - deps = store.dependencies_causing_outdatedness_of(item_b) - expect(deps.size).to eql(1) - expect(deps[0].from).to eql(item_c) - end - - it 'returns nothing for the others' do - expect(store.dependencies_causing_outdatedness_of(item_c)).to be_empty - end - end - end - - describe 'reloading - item a -> b' do - before do - store.record_dependency(item_a, item_b, compiled_content: true) - store.record_dependency(item_a, item_b, attributes: true) - - store.store - end - - let(:reloaded_store) do - described_class.new(items_after, layouts, config).tap(&:load) - end - - context 'no new items' do - let(:items_after) { items } - - it 'has the right dependencies for item A' do - deps = reloaded_store.dependencies_causing_outdatedness_of(item_a) - expect(deps.size).to eql(1) - - expect(deps[0].from).to eql(item_b) - expect(deps[0].to).to eql(item_a) - - expect(deps[0].props.raw_content?).to eq(false) - expect(deps[0].props.attributes?).to eq(true) - expect(deps[0].props.compiled_content?).to eq(true) - expect(deps[0].props.path?).to eq(false) - end - - it 'has the right dependencies for item B' do - deps = reloaded_store.dependencies_causing_outdatedness_of(item_b) - expect(deps).to be_empty - end - - it 'has the right dependencies for item C' do - deps = reloaded_store.dependencies_causing_outdatedness_of(item_c) - expect(deps).to be_empty - end - end - - context 'one new item' do - let(:items_after) do - Nanoc::Int::ItemCollection.new(config, [item_a, item_b, item_c, item_d]) - end - - let(:item_d) { Nanoc::Int::Item.new('d', {}, '/d.md') } - - it 'does not mark items as outdated' do - expect(reloaded_store.objects_causing_outdatedness_of(item_a)).not_to include(item_d) - expect(reloaded_store.objects_causing_outdatedness_of(item_b)).not_to include(item_d) - expect(reloaded_store.objects_causing_outdatedness_of(item_c)).not_to include(item_d) - expect(reloaded_store.objects_causing_outdatedness_of(item_d)).not_to include(item_d) - end - end - - context 'unrelated item removed' do - let(:items_after) do - Nanoc::Int::ItemCollection.new(config, [item_a, item_b]) - end - - it 'does not mark items as outdated' do - expect(reloaded_store.objects_causing_outdatedness_of(item_a)).to eq([item_b]) - expect(reloaded_store.objects_causing_outdatedness_of(item_b)).to be_empty - expect(reloaded_store.objects_causing_outdatedness_of(item_c)).to be_empty - end - end - - context 'related item removed' do - let(:items_after) do - Nanoc::Int::ItemCollection.new(config, [item_a, item_c]) - end - - it 'does not mark items as outdated' do - expect(reloaded_store.objects_causing_outdatedness_of(item_a)).to eq([nil]) - expect(reloaded_store.objects_causing_outdatedness_of(item_b)).to be_empty - expect(reloaded_store.objects_causing_outdatedness_of(item_c)).to be_empty - end - end - end - - describe 'reloading - item a -> config' do - before do - store.record_dependency(item_a, config, attributes: [:donkey]) - - store.store - store.load - end - - it 'has the right dependencies for item A' do - deps = store.dependencies_causing_outdatedness_of(item_a) - expect(deps.size).to eql(1) - - expect(deps[0].from).to eql(config) - expect(deps[0].to).to eql(item_a) - - expect(deps[0].props.raw_content?).to eq(false) - expect(deps[0].props.attributes?).to eq(true) - expect(deps[0].props.attributes).to contain_exactly(:donkey) - expect(deps[0].props.compiled_content?).to eq(false) - expect(deps[0].props.path?).to eq(false) - end - - it 'has the right dependencies for item B' do - deps = store.dependencies_causing_outdatedness_of(item_b) - expect(deps).to be_empty - end - - it 'has the right dependencies for item C' do - deps = store.dependencies_causing_outdatedness_of(item_c) - expect(deps).to be_empty - end - end - - shared_examples 'records dependencies' do - context 'no props' do - subject { store.record_dependency(source_obj, item_b) } - - it 'records a dependency' do - expect { subject } - .to change { store.objects_causing_outdatedness_of(source_obj) } - .from([]) - .to([item_b]) - end - - it 'ignores all other objects' do - subject - expect(other_items).to all(satisfy { |o| store.dependencies_causing_outdatedness_of(o).empty? }) - end - - context 'dependency on self' do - subject { store.record_dependency(source_obj, item_a) } - - it 'does not create dependency on self' do - expect { subject } - .not_to change { store.objects_causing_outdatedness_of(source_obj) } - end - end - - context 'two dependencies' do - subject do - store.record_dependency(source_obj, item_b) - store.record_dependency(source_obj, item_b) - end - - it 'does not create duplicate dependencies' do - expect { subject } - .to change { store.objects_causing_outdatedness_of(source_obj) } - .from([]) - .to([item_b]) - end - end - - context 'dependency to nil' do - subject { store.record_dependency(source_obj, nil) } - - it 'creates a dependency to nil' do - expect { subject } - .to change { store.objects_causing_outdatedness_of(source_obj) } - .from([]) - .to([nil]) - end - end - - context 'dependency from nil' do - subject { store.record_dependency(nil, item_b) } - - it 'does not create a dependency from nil' do - expect { subject } - .not_to change { store.objects_causing_outdatedness_of(item_b) } - end - end - end - - context 'compiled content prop' do - subject { store.record_dependency(source_obj, target_obj, compiled_content: true) } - - it 'records a dependency' do - expect { subject } - .to change { store.objects_causing_outdatedness_of(source_obj) } - .from([]) - .to([target_obj]) - end - - it 'records a dependency with the right props' do - subject - deps = store.dependencies_causing_outdatedness_of(source_obj) - - expect(deps.first.props.attributes?).not_to be - expect(deps.first.props.compiled_content?).to be - end - - it 'ignores all other objects' do - subject - expect(other_items).to all(satisfy { |o| store.dependencies_causing_outdatedness_of(o).empty? }) - end - end - - context 'attribute prop (true)' do - subject { store.record_dependency(source_obj, target_obj, attributes: true) } - - it 'records a dependency' do - expect { subject } - .to change { store.objects_causing_outdatedness_of(source_obj) } - .from([]) - .to([target_obj]) - end - - it 'records a dependency with the right props' do - subject - deps = store.dependencies_causing_outdatedness_of(source_obj) - - expect(deps.first.props.attributes?).to be - expect(deps.first.props.attributes).to be - expect(deps.first.props.compiled_content?).not_to be - end - - it 'ignores all other objects' do - subject - expect(other_items).to all(satisfy { |o| store.dependencies_causing_outdatedness_of(o).empty? }) - end - end - - context 'attribute prop (true)' do - subject { store.record_dependency(source_obj, target_obj, attributes: [:giraffe]) } - - it 'records a dependency' do - expect { subject } - .to change { store.objects_causing_outdatedness_of(source_obj) } - .from([]) - .to([target_obj]) - end - - it 'records a dependency with the right props' do - subject - deps = store.dependencies_causing_outdatedness_of(source_obj) - - expect(deps.first.props.attributes?).to be - expect(deps.first.props.attributes).to match_array([:giraffe]) - expect(deps.first.props.compiled_content?).not_to be - end - - it 'ignores all other objects' do - subject - expect(other_items).to all(satisfy { |o| store.dependencies_causing_outdatedness_of(o).empty? }) - end - end - end - - describe '#record_dependency' do - context 'item on item' do - let(:source_obj) { item_a } - let(:target_obj) { item_b } - let(:other_items) { [item_c] } - - include_examples 'records dependencies' - end - - context 'item on layout' do - let(:source_obj) { item_a } - let(:target_obj) { layout_a } - let(:other_items) { [item_b, item_c] } - - include_examples 'records dependencies' - end - - context 'item on config' do - let(:source_obj) { item_a } - let(:target_obj) { config } - let(:other_items) { [item_b, item_c] } - - include_examples 'records dependencies' - end - end - - describe '#forget_dependencies_for' do - before do - store.record_dependency(item_a, item_b) - store.record_dependency(item_a, item_c) - store.record_dependency(item_b, item_a) - store.record_dependency(item_b, item_c) - store.record_dependency(item_c, item_a) - store.record_dependency(item_c, item_b) - end - - subject { store.forget_dependencies_for(item_b) } - - it 'removes dependencies from item_a' do - expect { subject } - .not_to change { store.objects_causing_outdatedness_of(item_a) } - end - - it 'removes dependencies from item_b' do - expect { subject } - .to change { store.objects_causing_outdatedness_of(item_b) } - .from(match_array([item_a, item_c])) - .to(be_empty) - end - - it 'removes dependencies from item_c' do - expect { subject } - .not_to change { store.objects_causing_outdatedness_of(item_c) } - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/repos/in_mem_data_source_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/repos/in_mem_data_source_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/repos/in_mem_data_source_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/repos/in_mem_data_source_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::InMemDataSource, stdio: true do - let(:klass) do - Class.new(Nanoc::DataSource) do - def item_changes - %i[one_foo one_bar] - end - - def layout_changes - %i[one_foo one_bar] - end - end - end - - let(:original_data_source) do - klass.new({}, nil, nil, {}) - end - - subject(:data_source) do - described_class.new([], [], original_data_source) - end - - describe '#item_changes' do - subject { data_source.item_changes } - - it 'yields changes from the original' do - expect(subject).to eq(original_data_source.item_changes) - end - end - - describe '#layout_changes' do - subject { data_source.layout_changes } - - it 'yields changes from the original' do - expect(subject).to eq(original_data_source.layout_changes) - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/repos/outdatedness_store_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/repos/outdatedness_store_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/repos/outdatedness_store_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/repos/outdatedness_store_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::OutdatednessStore do - subject(:store) { described_class.new(config: config) } - - let(:item) { Nanoc::Int::Item.new('foo', {}, '/foo.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :foo) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - let(:items) { [] } - let(:layouts) { [] } - let(:code_snippets) { [] } - - describe '#include?, #add and #remove' do - subject { store.include?(rep) } - - context 'nothing added' do - it { is_expected.not_to be } - end - - context 'rep added' do - before { store.add(rep) } - it { is_expected.to be } - end - - context 'rep added and removed' do - before do - store.add(rep) - store.remove(rep) - end - - it { is_expected.not_to be } - end - - context 'rep added, removed, and added again' do - before do - store.add(rep) - store.remove(rep) - store.add(rep) - end - - it { is_expected.to be } - end - end - - describe 'reloading' do - subject do - store.store - store.load - store.include?(rep) - end - - context 'not added' do - it { is_expected.not_to be } - end - - context 'added' do - before { store.add(rep) } - it { is_expected.to be } - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/repos/prefixed_data_source_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/repos/prefixed_data_source_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/repos/prefixed_data_source_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/repos/prefixed_data_source_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::PrefixedDataSource, stdio: true do - let(:klass) do - Class.new(Nanoc::DataSource) do - def item_changes - %i[one_foo one_bar] - end - - def layout_changes - %i[one_foo one_bar] - end - end - end - - let(:original_data_source) do - klass.new({}, nil, nil, {}) - end - - subject(:data_source) do - described_class.new(original_data_source, '/itemz', '/layoutz') - end - - describe '#item_changes' do - subject { data_source.item_changes } - - it 'yields changes from the original' do - expect(subject).to eq(original_data_source.item_changes) - end - end - - describe '#layout_changes' do - subject { data_source.layout_changes } - - it 'yields changes from the original' do - expect(subject).to eq(original_data_source.layout_changes) - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/repos/site_loader_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/repos/site_loader_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/repos/site_loader_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/repos/site_loader_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,219 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::SiteLoader do - let(:loader) { described_class.new } - - describe '#new_from_cwd' do - subject { loader.new_from_cwd } - - context 'no config file' do - it 'errors' do - expect { subject }.to raise_error( - Nanoc::Int::ConfigLoader::NoConfigFileFoundError, - ) - end - end - - shared_examples 'a directory with a config file' do - it 'has the default configuration' do - expect(subject.config).to be_a(Nanoc::Int::Configuration) - expect(subject.config[:index_filenames]).to eq(['index.html']) - expect(subject.config[:foo]).to eq('bar') - end - - it 'has no code snippets' do - expect(subject.code_snippets).to be_empty - end - - it 'has no items' do - expect(subject.items).to be_empty - end - - it 'has no layouts' do - expect(subject.layouts).to be_empty - end - - context 'some items, layouts, and code snippets' do - before do - FileUtils.mkdir_p('lib') - File.write('lib/foo.rb', '$spirit_animal = :donkey') - - FileUtils.mkdir_p('content') - File.write('content/about.md', 'I am Denis!') - - FileUtils.mkdir_p('layouts') - File.write('layouts/page.erb', '<%= yield %>') - end - - it 'has a code snippet' do - expect(subject.code_snippets.size).to eq(1) - expect(subject.code_snippets[0].data).to eq('$spirit_animal = :donkey') - end - - it 'has an item' do - expect(subject.items.size).to eq(1) - expect(subject.items['/about.md'].content).to be_a(Nanoc::Int::TextualContent) - expect(subject.items['/about.md'].content.string).to eq('I am Denis!') - expect(subject.items['/about.md'].attributes[:content_filename]) - .to eq('content/about.md') - expect(subject.items['/about.md'].attributes[:extension]) - .to eq('md') - expect(subject.items['/about.md'].attributes[:filename]) - .to eq('content/about.md') - expect(subject.items['/about.md'].attributes[:meta_filename]) - .to be_nil - expect(subject.items['/about.md'].attributes[:mtime]) - .to be > Time.now - 5 - expect(subject.items['/about.md'].identifier.to_s).to eq('/about.md') - end - - it 'has a layout' do - expect(subject.layouts.size).to eq(1) - expect(subject.layouts['/page.erb'].content).to be_a(Nanoc::Int::TextualContent) - expect(subject.layouts['/page.erb'].content.string).to eq('<%= yield %>') - expect(subject.layouts['/page.erb'].attributes[:content_filename]) - .to eq('layouts/page.erb') - expect(subject.layouts['/page.erb'].attributes[:extension]) - .to eq('erb') - expect(subject.layouts['/page.erb'].attributes[:filename]) - .to eq('layouts/page.erb') - expect(subject.layouts['/page.erb'].attributes[:meta_filename]) - .to be_nil - expect(subject.layouts['/page.erb'].attributes[:mtime]) - .to be > Time.now - 5 - expect(subject.layouts['/page.erb'].identifier.to_s).to eq('/page.erb') - end - end - end - - context 'nanoc.yaml config file' do - before do - File.write('nanoc.yaml', "---\nfoo: bar\n") - end - - it_behaves_like 'a directory with a config file' - end - - context 'config.yaml config file' do - before do - File.write('config.yaml', "---\nfoo: bar\n") - end - - it_behaves_like 'a directory with a config file' - end - - context 'configuration has non-existant data source' do - before do - File.write('nanoc.yaml', <<-EOS.gsub(/^ {10}/, '')) - data_sources: - - type: eenvaleed - EOS - end - - it 'raises an error' do - expect { subject }.to raise_error(Nanoc::Int::Errors::UnknownDataSource) - end - end - - context 'environments defined' do - before do - File.write('nanoc.yaml', <<-EOS.gsub(/^ {10}/, '')) - animal: donkey - environments: - staging: - animal: giraffe - EOS - end - - before do - expect(ENV).to receive(:fetch).with('NANOC_ENV', 'default').and_return('staging') - end - - it 'does not load environment' do - expect(subject.config[:animal]).to eq('giraffe') - end - end - - context 'code snippet with data source implementation' do - before do - FileUtils.mkdir_p('lib') - File.write('lib/foo_data_source.rb', <<-EOS.gsub(/^ {10}/, '')) - class FooDataSource < Nanoc::DataSource - identifier :site_loader_spec_sample - - def items - [ - Nanoc::Int::Item.new( - 'Generated content!', - { generated: true }, - '/generated.txt', - ) - ] - end - end - EOS - - File.write('nanoc.yaml', <<-EOS.gsub(/^ {10}/, '')) - data_sources: - - type: site_loader_spec_sample - EOS - end - - it 'loads code snippets before items/layouts' do - expect(subject.items.size).to eq(1) - expect(subject.items['/generated.txt'].content).to be_a(Nanoc::Int::TextualContent) - expect(subject.items['/generated.txt'].content.string).to eq('Generated content!') - expect(subject.items['/generated.txt'].attributes).to eq(generated: true) - expect(subject.items['/generated.txt'].identifier.to_s).to eq('/generated.txt') - end - end - end - - describe '#code_snippets_from_config' do - subject { loader.send(:code_snippets_from_config, config) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - before { FileUtils.mkdir_p('lib') } - - context 'no explicit encoding specified' do - example do - File.write('lib/asdf.rb', 'hi 🔥', encoding: 'utf-8') - expect(subject.size).to eq(1) - expect(subject.first.data).to eq('hi 🔥') - end - end - - context '# encoding: x specified' do - example do - File.write('lib/asdf.rb', "# encoding: iso-8859-1\n\nBRØKEN", encoding: 'iso-8859-1') - expect(subject.size).to eq(1) - expect(subject.first.data).to eq('BRØKEN') - end - end - - context '# coding: x specified' do - example do - File.write('lib/asdf.rb', "# coding: iso-8859-1\n\nBRØKEN", encoding: 'iso-8859-1') - expect(subject.size).to eq(1) - expect(subject.first.data).to eq('BRØKEN') - end - end - - context '# -*- encoding: x -*- specified' do - example do - File.write('lib/asdf.rb', "# -*- encoding: iso-8859-1 -*-\n\nBRØKEN", encoding: 'iso-8859-1') - expect(subject.size).to eq(1) - expect(subject.first.data).to eq('BRØKEN') - end - end - - context '# -*- coding: x -*- specified' do - example do - File.write('lib/asdf.rb', "# -*- coding: iso-8859-1 -*-\n\nBRØKEN", encoding: 'iso-8859-1') - expect(subject.size).to eq(1) - expect(subject.first.data).to eq('BRØKEN') - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/repos/snapshot_repo_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/repos/snapshot_repo_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/repos/snapshot_repo_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/repos/snapshot_repo_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,316 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::SnapshotRepo do - subject(:repo) { described_class.new } - - describe '#get' do - subject { repo.get(rep, snapshot_name) } - - let(:item) { Nanoc::Int::Item.new('contentz', {}, '/foo.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :foo) } - let(:snapshot_name) { :donkey } - - context 'rep does not exist in repo' do - it { is_expected.to be_nil } - end - - context 'rep exists in repo' do - before { repo.set(rep, :foobar, Nanoc::Int::TextualContent.new('other content')) } - - context 'snapshot does not exist in repo' do - it { is_expected.to be_nil } - end - - context 'snapshot exists in repo' do - before { repo.set(rep, :donkey, Nanoc::Int::TextualContent.new('donkey')) } - it { is_expected.to be_some_textual_content('donkey') } - end - end - end - - describe '#get_all' do - subject { repo.get_all(rep) } - - let(:item) { Nanoc::Int::Item.new('contentz', {}, '/foo.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :foo) } - - context 'rep does not exist in repo' do - it { is_expected.to eq({}) } - end - - context 'rep exists in repo' do - before { repo.set(rep, :foobar, Nanoc::Int::TextualContent.new('donkey')) } - it { is_expected.to match(foobar: some_textual_content('donkey')) } - end - end - - describe '#set' do - subject { repo.set(rep, snapshot_name, contents) } - - let(:item) { Nanoc::Int::Item.new('contentz', {}, '/foo.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :foo) } - let(:snapshot_name) { :donkey } - let(:contents) { Nanoc::Int::TextualContent.new('donkey') } - - it 'changes the given rep+snapshot' do - expect { subject } - .to change { repo.get(rep, snapshot_name) } - .from(nil) - .to(some_textual_content('donkey')) - end - end - - describe '#set_all' do - subject { repo.set_all(rep, contents_by_snapshot) } - - let(:other_item) { Nanoc::Int::Item.new('contentz', {}, '/foo.md') } - let(:other_rep) { Nanoc::Int::ItemRep.new(other_item, :foo) } - - let(:item) { Nanoc::Int::Item.new('contentz', {}, '/foo.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :foo) } - let(:contents_by_snapshot) { { donkey: Nanoc::Int::TextualContent.new('donkey') } } - - it 'changes the given rep+snapshot' do - expect { subject } - .to change { repo.get(rep, :donkey) } - .from(nil) - .to(some_textual_content('donkey')) - end - - it 'leaves other reps intact' do - expect { subject } - .not_to change { repo.get(other_rep, :donkey) } - end - - it 'leaves other snapshots intact' do - expect { subject } - .not_to change { repo.get(rep, :giraffe) } - end - end - - describe '#compiled_content' do - subject { repo.compiled_content(rep: rep, snapshot: snapshot_name) } - - let(:snapshot_name) { raise 'override me' } - - let(:item) { Nanoc::Int::Item.new('contentz', {}, '/foo.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :foo) } - - shared_examples 'a non-moving snapshot with content' do - context 'no snapshot def' do - it 'raises' do - expect { subject }.to raise_error(Nanoc::Int::Errors::NoSuchSnapshot) - end - end - - context 'snapshot def exists' do - before do - rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name, binary: false)] - repo.set_all(rep, snapshot_name => content) - end - - context 'content is textual' do - let(:content) { Nanoc::Int::TextualContent.new('hellos') } - it { is_expected.to eql('hellos') } - end - - context 'content is binary' do - before { File.write('donkey.dat', 'binary data') } - let(:content) { Nanoc::Int::BinaryContent.new(File.expand_path('donkey.dat')) } - - it 'raises' do - expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetCompiledContentOfBinaryItem, 'You cannot access the compiled content of a binary item representation (but you can access the path). The offending item rep is /foo.md (rep name :foo).') - end - end - end - end - - shared_examples 'a non-moving snapshot' do - include_examples 'a non-moving snapshot with content' - - context 'snapshot def exists, but not content' do - before do - rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name, binary: false)] - repo.set_all(rep, {}) - end - - it 'errors' do - expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency)) - end - end - end - - shared_examples 'snapshot :last' do - context 'no snapshot def' do - it 'errors' do - expect { subject }.to raise_error(Nanoc::Int::Errors::NoSuchSnapshot) - end - end - - context 'snapshot exists' do - context 'snapshot is not final' do - before do - rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name, binary: false)] - end - - context 'snapshot content does not exist' do - before do - repo.set_all(rep, {}) - end - - it 'errors' do - expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency)) - end - end - - context 'snapshot content exists' do - context 'content is textual' do - before do - repo.set(rep, snapshot_name, Nanoc::Int::TextualContent.new('hellos')) - end - - context 'not compiled' do - before { rep.compiled = false } - - it 'raises' do - expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency)) - end - end - - context 'compiled' do - before { rep.compiled = true } - - it { is_expected.to eql('hellos') } - end - end - - context 'content is binary' do - before do - File.write('donkey.dat', 'binary data') - repo.set(rep, snapshot_name, Nanoc::Int::BinaryContent.new(File.expand_path('donkey.dat'))) - end - - context 'not compiled' do - before { rep.compiled = false } - - it 'raises' do - expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency)) - end - end - - context 'compiled' do - before { rep.compiled = true } - - it 'raises' do - expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetCompiledContentOfBinaryItem, 'You cannot access the compiled content of a binary item representation (but you can access the path). The offending item rep is /foo.md (rep name :foo).') - end - end - end - end - end - - context 'snapshot is final' do - before do - rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name, binary: false)] - end - - context 'snapshot content does not exist' do - before do - repo.set_all(rep, {}) - end - - it 'errors' do - expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency)) - end - end - - context 'snapshot content exists' do - context 'content is textual' do - before do - repo.set(rep, snapshot_name, Nanoc::Int::TextualContent.new('hellos')) - end - - context 'not compiled' do - before { rep.compiled = false } - - it 'errors' do - expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency)) - end - end - - context 'compiled' do - before { rep.compiled = true } - - it { is_expected.to eql('hellos') } - end - end - - context 'content is binary' do - before do - File.write('donkey.dat', 'binary data') - repo.set(rep, snapshot_name, Nanoc::Int::BinaryContent.new(File.expand_path('donkey.dat'))) - end - - context 'not compiled' do - before { rep.compiled = false } - - it 'raises' do - expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency)) - end - end - - context 'compiled' do - before { rep.compiled = true } - - it 'raises' do - expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetCompiledContentOfBinaryItem, 'You cannot access the compiled content of a binary item representation (but you can access the path). The offending item rep is /foo.md (rep name :foo).') - end - end - end - end - end - end - end - - context 'snapshot nil' do - let(:snapshot_name) { :last } - subject { repo.compiled_content(rep: rep, snapshot: nil) } - include_examples 'snapshot :last' - end - - context 'snapshot not specified' do - subject { repo.compiled_content(rep: rep) } - - context 'pre exists' do - before { repo.set(rep, :pre, Nanoc::Int::TextualContent.new('omg')) } - let(:snapshot_name) { :pre } - include_examples 'a non-moving snapshot with content' - end - - context 'pre does not exist' do - let(:snapshot_name) { :last } - include_examples 'snapshot :last' - end - end - - context 'snapshot :pre specified' do - let(:snapshot_name) { :pre } - include_examples 'a non-moving snapshot' - end - - context 'snapshot :post specified' do - let(:snapshot_name) { :post } - include_examples 'a non-moving snapshot' - end - - context 'snapshot :last specified' do - let(:snapshot_name) { :last } - include_examples 'snapshot :last' - end - - context 'snapshot :donkey specified' do - let(:snapshot_name) { :donkey } - include_examples 'a non-moving snapshot' - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/repos/store_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/repos/store_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/repos/store_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/repos/store_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Store do - describe '#tmp_path_for' do - context 'passing config' do - subject { described_class.tmp_path_for(config: config, store_name: 'giraffes') } - - let(:code_snippets) { [] } - let(:items) { [] } - let(:layouts) { [] } - - def gen_hash(path) - Digest::SHA1.hexdigest(File.absolute_path(path))[0..12] - end - - let(:hash_output) { gen_hash('output') } - let(:hash_output_default) { gen_hash('output-default') } - let(:hash_output_staging) { gen_hash('output-staging') } - let(:hash_output_production) { gen_hash('output-production') } - - context 'no env specified' do - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd, hash: config_hash).with_defaults.with_environment } - - context 'output dir is unspecified' do - let(:config_hash) { {} } - it { is_expected.to eql(Dir.getwd + "/tmp/nanoc/#{hash_output}/giraffes") } - end - - context 'output dir at root is specified' do - let(:config_hash) { { output_dir: 'output-default' } } - it { is_expected.to eql(Dir.getwd + "/tmp/nanoc/#{hash_output_default}/giraffes") } - end - - context 'output dir in default env is specified' do - let(:config_hash) { { environments: { default: { output_dir: 'output-default' } } } } - it { is_expected.to eql(Dir.getwd + "/tmp/nanoc/#{hash_output_default}/giraffes") } - end - - context 'output dir in other env is specified' do - let(:config_hash) { { environments: { production: { output_dir: 'output-production' } } } } - it { is_expected.to eql(Dir.getwd + "/tmp/nanoc/#{hash_output}/giraffes") } - end - end - - context 'env specified' do - let(:config) { Nanoc::Int::Configuration.new(env_name: 'staging', dir: Dir.getwd, hash: config_hash).with_defaults.with_environment } - - context 'output dir is unspecified' do - let(:config_hash) { {} } - it { is_expected.to eql(Dir.getwd + "/tmp/nanoc/#{hash_output}/giraffes") } - end - - context 'output dir at root is specified' do - let(:config_hash) { { output_dir: 'output-default' } } - it { is_expected.to eql(Dir.getwd + "/tmp/nanoc/#{hash_output_default}/giraffes") } - end - - context 'output dir in given env is specified' do - let(:config_hash) { { environments: { staging: { output_dir: 'output-staging' } } } } - it { is_expected.to eql(Dir.getwd + "/tmp/nanoc/#{hash_output_staging}/giraffes") } - end - - context 'output dir in other env is specified' do - let(:config_hash) { { environments: { production: { output_dir: 'output-production' } } } } - it { is_expected.to eql(Dir.getwd + "/tmp/nanoc/#{hash_output}/giraffes") } - end - end - end - end - - let(:test_store_klass) do - Class.new(Nanoc::Int::Store) do - def data - @data - end - - def data=(new_data) - @data = new_data - end - end - end - - it 'deletes and reloads on error' do - store = test_store_klass.new('test.db', 1) - - # Create - store.load - store.data = { fun: 'sure' } - store.store - - # Test stored values - store = test_store_klass.new('test.db', 1) - store.load - expect(store.data).to eq(fun: 'sure') - - # Mess up - File.write('test.db', 'Damn {}#}%@}$^)@&$&*^#@ broken stores!!!') - - # Reload - store = test_store_klass.new('test.db', 1) - store.load - expect(store.data).to be_nil - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/action_sequence_builder_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/action_sequence_builder_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/action_sequence_builder_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/action_sequence_builder_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::ActionSequenceBuilder do - let(:builder) { described_class.new(item_rep) } - - let(:item_rep) { Nanoc::Int::ItemRep.new(item, :default) } - let(:item) { Nanoc::Int::Item.new('some content', {}, '/foo.md') } - - describe '#add_filter' do - subject { builder.add_filter(:erb, foo: :bar) } - - it 'adds an action' do - expect { subject } - .to change { builder.action_sequence.actions } - .from([]) - .to([Nanoc::Int::ProcessingActions::Filter.new(:erb, foo: :bar)]) - end - end - - describe '#add_layout' do - subject { builder.add_layout('/oink.erb', foo: :bar) } - - it 'adds an action' do - expect { subject } - .to change { builder.action_sequence.actions } - .from([]) - .to([Nanoc::Int::ProcessingActions::Layout.new('/oink.erb', foo: :bar)]) - end - end - - describe '#add_snapshot' do - context 'add one snapshot' do - subject { builder.add_snapshot(:last, '/foo.html') } - - it 'adds an action' do - expect { subject } - .to change { builder.action_sequence.actions } - .from([]) - .to([Nanoc::Int::ProcessingActions::Snapshot.new([:last], ['/foo.html'])]) - end - end - - context 'add two snapshots with same name' do - subject do - builder.add_snapshot(:last, '/foo.html') - builder.add_snapshot(:last, '/foo.htm') - end - - it 'raises' do - expect { subject } - .to raise_error(Nanoc::Int::Errors::CannotCreateMultipleSnapshotsWithSameName, 'Attempted to create a snapshot with a duplicate name :last for the item rep /foo.md (rep name :default)') - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/checksummer_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/checksummer_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/checksummer_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/checksummer_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +# NOTE: this spec checks all the bits that aren’t in Core. + +describe Nanoc::Core::Checksummer do + subject { described_class.calc(obj, Nanoc::Core::Checksummer::VerboseDigest) } + + context 'Nanoc::RuleDSL::RulesCollection' do + let(:obj) do + Nanoc::RuleDSL::RulesCollection.new.tap { |rc| rc.data = data } + end + + let(:data) { 'STUFF!' } + + it { is_expected.to eql('Nanoc::RuleDSL::RulesCollection>') } + end + + context 'Nanoc::RuleDSL::CompilationRuleContext' do + let(:obj) { Nanoc::RuleDSL::CompilationRuleContext.new(rep: rep, site: site, recorder: recorder, view_context: view_context) } + + let(:rep) { Nanoc::Core::ItemRep.new(item, :pdf) } + let(:item) { Nanoc::Core::Item.new('stuff', {}, '/stuff.md') } + + let(:site) do + Nanoc::Core::Site.new( + config: config, + code_snippets: code_snippets, + data_source: Nanoc::Core::InMemoryDataSource.new(items, layouts), + ) + end + + let(:config) { Nanoc::Core::Configuration.new(dir: Dir.getwd, hash: { 'foo' => 'bar' }) } + let(:code_snippets) { [Nanoc::Core::CodeSnippet.new('asdf', '/bob.rb')] } + let(:items) { Nanoc::Core::ItemCollection.new(config, [item]) } + let(:layouts) { Nanoc::Core::LayoutCollection.new(config, [Nanoc::Core::Layout.new('asdf', {}, '/foo.md')]) } + + let(:recorder) { Nanoc::RuleDSL::ActionRecorder.new(rep) } + let(:view_context) { Nanoc::Core::ViewContextForPreCompilation.new(items: items) } + + let(:expected_item_checksum) { 'Nanoc::Core::Item>,attributes=Hash<>,identifier=Nanoc::Core::Identifier>>' } + let(:expected_item_rep_checksum) { 'Nanoc::Core::ItemRep>' } + let(:expected_layout_checksum) { 'Nanoc::Core::Layout>,attributes=Hash<>,identifier=Nanoc::Core::Identifier>>' } + let(:expected_config_checksum) { 'Nanoc::Core::Configuration=String,>' } + + let(:expected_checksum) do + [ + 'Nanoc::RuleDSL::CompilationRuleContext<', + 'item=', + 'Nanoc::Core::BasicItemView<' + expected_item_checksum + '>', + ',rep=', + 'Nanoc::Core::BasicItemRepView<' + expected_item_rep_checksum + '>', + ',items=', + 'Nanoc::Core::ItemCollectionWithoutRepsView>', + ',layouts=', + 'Nanoc::Core::LayoutCollectionView>', + ',config=', + 'Nanoc::Core::ConfigView<' + expected_config_checksum + '>', + '>', + ].join('') + end + + it { is_expected.to eql(expected_checksum) } + end + + context 'Sass::Importers::Filesystem' do + let(:obj) { Sass::Importers::Filesystem.new('/foo') } + + before { require 'sass' } + + it { is_expected.to match(%r{\ASass::Importers::Filesystem\z}) } + end +end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/phases/abstract_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/phases/abstract_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/phases/abstract_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/phases/abstract_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Compiler::Phases::Abstract do - subject(:phase) do - described_class.new(wrapped: wrapped) - end - - let(:item) { Nanoc::Int::Item.new('foo', {}, '/stuff.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } - - let(:wrapped) { nil } - - describe '#run' do - subject { phase.run(rep, is_outdated: false) {} } - - it 'raises' do - expect { subject }.to raise_error(NotImplementedError) - end - end - - describe '#call' do - subject { phase.call(rep, is_outdated: false) } - - let(:phase_class) do - Class.new(described_class) do - def self.to_s - 'AbstractSpec::MyTestingPhaseClass' - end - - def run(_rep, is_outdated:) # rubocop:disable Lint/UnusedMethodArgument - yield - end - end - end - - let(:phase) { phase_class.new(wrapped: wrapped) } - - let(:wrapped_class) do - Class.new(described_class) do - def self.to_s - 'AbstractSpec::MyTestingWrappedPhaseClass' - end - - def run(_rep, is_outdated:); end - end - end - - let(:wrapped) { wrapped_class.new(wrapped: nil) } - - it 'sends the proper notifications' do - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_started, 'MyTestingPhaseClass', rep).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_yielded, 'MyTestingPhaseClass', rep).ordered - - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_started, 'MyTestingWrappedPhaseClass', rep).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_ended, 'MyTestingWrappedPhaseClass', rep).ordered - - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_resumed, 'MyTestingPhaseClass', rep).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_ended, 'MyTestingPhaseClass', rep).ordered - - subject - end - end - - describe '#start' do - subject { phase.start } - - context 'with wrapped' do - let(:wrapped) { described_class.new(wrapped: nil) } - - it 'starts wrapped' do - expect(wrapped).to receive(:start) - subject - end - end - - context 'without wrapped' do - let(:wrapped) { nil } - - it 'does not start wrapped' do - subject - end - end - end - - describe '#stop' do - subject { phase.stop } - - context 'with wrapped' do - let(:wrapped) { described_class.new(wrapped: nil) } - - it 'stops wrapped' do - expect(wrapped).to receive(:stop) - subject - end - end - - context 'without wrapped' do - let(:wrapped) { nil } - - it 'does not stop wrapped' do - subject - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/phases/cache_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/phases/cache_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/phases/cache_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/phases/cache_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,150 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Compiler::Phases::Cache do - subject(:phase) do - described_class.new( - compiled_content_cache: compiled_content_cache, - snapshot_repo: snapshot_repo, - wrapped: wrapped, - ) - end - - let(:compiled_content_cache) do - Nanoc::Int::CompiledContentCache.new(config: config) - end - - let(:snapshot_repo) { Nanoc::Int::SnapshotRepo.new } - - let(:wrapped_class) do - Class.new(Nanoc::Int::Compiler::Phases::Abstract) do - def initialize(snapshot_repo) - @snapshot_repo = snapshot_repo - end - - def run(rep, is_outdated:) # rubocop:disable Lint/UnusedMethodArgument - @snapshot_repo.set(rep, :last, Nanoc::Int::TextualContent.new('wrapped content')) - end - end - end - - let(:wrapped) { wrapped_class.new(snapshot_repo) } - - let(:item) { Nanoc::Int::Item.new('item content', {}, '/donkey.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :latex) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - describe '#run' do - subject { phase.call(rep, is_outdated: is_outdated) } - - let(:is_outdated) { raise 'override me' } - - before do - allow(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_started, anything, anything) - allow(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_yielded, anything, anything) - allow(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_resumed, anything, anything) - allow(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_ended, anything, anything) - end - - shared_examples 'calls wrapped' do - it 'delegates to wrapped' do - expect(wrapped).to receive(:run).with(rep, is_outdated: is_outdated) - subject - end - - it 'marks rep as compiled' do - expect { subject } - .to change { rep.compiled? } - .from(false) - .to(true) - end - - it 'sends no other notifications' do - subject - end - - it 'updates compiled content cache' do - expect { subject } - .to change { compiled_content_cache[rep] } - .from(nil) - .to(last: some_textual_content('wrapped content')) - end - end - - context 'outdated' do - let(:is_outdated) { true } - include_examples 'calls wrapped' - end - - context 'not outdated' do - let(:is_outdated) { false } - - context 'textual cached compiled content available' do - before do - compiled_content_cache[rep] = { last: Nanoc::Int::TextualContent.new('cached') } - end - - it 'writes content to cache' do - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:cached_content_used, rep) - expect { subject } - .to change { snapshot_repo.get(rep, :last) } - .from(nil) - .to(some_textual_content('cached')) - end - - it 'marks rep as compiled' do - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:cached_content_used, rep) - expect { subject } - .to change { rep.compiled? } - .from(false) - .to(true) - end - - it 'does not change compiled content cache' do - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:cached_content_used, rep) - expect { subject } - .not_to change { compiled_content_cache[rep] } - end - end - - context 'binary cached compiled content available' do - let(:binary_content) { 'b1n4ry' } - let(:binary_filename) { Tempfile.open('test') { |fn| fn << binary_content }.path } - - before do - compiled_content_cache[rep] = { last: Nanoc::Int::BinaryContent.new(binary_filename) } - end - - it 'writes content to cache' do - expect { subject } - .to change { snapshot_repo.get(rep, :last) } - .from(nil) - .to(some_textual_content('wrapped content')) - end - - it 'marks rep as compiled' do - expect { subject } - .to change { rep.compiled? } - .from(false) - .to(true) - end - - it 'changes compiled content cache' do - expect { subject } - .to change { compiled_content_cache[rep] } - .from(last: some_binary_content(binary_content)) - .to(last: some_textual_content('wrapped content')) - end - - it 'does not send notification' do - expect(Nanoc::Int::NotificationCenter).not_to receive(:post).with(:cached_content_used, rep) - subject - end - end - - context 'no cached compiled content available' do - include_examples 'calls wrapped' - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/stages/calculate_checksums_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/stages/calculate_checksums_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/stages/calculate_checksums_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/stages/calculate_checksums_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Compiler::Stages::CalculateChecksums do - let(:stage) do - described_class.new(items: items, layouts: layouts, code_snippets: code_snippets, config: config) - end - - let(:config) do - Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults - end - - let(:code_snippets) do - [code_snippet] - end - - let(:items) do - Nanoc::Int::ItemCollection.new(config, [item]) - end - - let(:layouts) do - Nanoc::Int::LayoutCollection.new(config, [layout]) - end - - let(:code_snippet) do - Nanoc::Int::CodeSnippet.new('woof!', 'dog.rb') - end - - let(:item) do - Nanoc::Int::Item.new('hello there', {}, '/hi.md') - end - - let(:layout) do - Nanoc::Int::Layout.new('t3mpl4t3', {}, '/page.erb') - end - - describe '#run' do - subject { stage.run } - - it 'checksums items' do - expect(subject.checksum_for(item)) - .to eq(Nanoc::Int::Checksummer.calc(item)) - - expect(subject.content_checksum_for(item)) - .to eq(Nanoc::Int::Checksummer.calc_for_content_of(item)) - - expect(subject.attributes_checksum_for(item)) - .to eq(Nanoc::Int::Checksummer.calc_for_each_attribute_of(item)) - end - - it 'checksums layouts' do - expect(subject.checksum_for(layout)) - .to eq(Nanoc::Int::Checksummer.calc(layout)) - - expect(subject.content_checksum_for(layout)) - .to eq(Nanoc::Int::Checksummer.calc_for_content_of(layout)) - - expect(subject.attributes_checksum_for(layout)) - .to eq(Nanoc::Int::Checksummer.calc_for_each_attribute_of(layout)) - end - - it 'checksums config' do - expect(subject.checksum_for(config)) - .to eq(Nanoc::Int::Checksummer.calc(config)) - - expect(subject.attributes_checksum_for(config)) - .to eq(Nanoc::Int::Checksummer.calc_for_each_attribute_of(config)) - end - - it 'checksums code snippets' do - expect(subject.checksum_for(code_snippet)) - .to eq(Nanoc::Int::Checksummer.calc(code_snippet)) - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/stages/cleanup_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/stages/cleanup_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/stages/cleanup_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/stages/cleanup_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Compiler::Stages::Cleanup do - let(:stage) { described_class.new(config.output_dirs) } - - let(:config) do - Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults - end - - describe '#run' do - subject { stage.run } - - def gen_hash(path) - Digest::SHA1.hexdigest(File.absolute_path(path))[0..12] - end - - it 'removes temporary binary items' do - a = Nanoc::Int::TempFilenameFactory.instance.create(Nanoc::Filter::TMP_BINARY_ITEMS_DIR) - File.write(a, 'hello there') - - expect { subject } - .to change { File.file?(a) } - .from(true).to(false) - end - - it 'removes temporary textual items' do - a = Nanoc::Int::TempFilenameFactory.instance.create(Nanoc::Int::ItemRepWriter::TMP_TEXT_ITEMS_DIR) - File.write(a, 'hello there') - - expect { subject } - .to change { File.file?(a) } - .from(true).to(false) - end - - shared_examples 'an old store' do - it 'removes the old store' do - FileUtils.mkdir_p('tmp') - File.write('tmp/' + store_name, 'stuff') - - expect { subject } - .to change { File.file?('tmp/' + store_name) } - .from(true).to(false) - end - end - - context 'tmp/checksums' do - let(:store_name) { 'checksums' } - it_behaves_like 'an old store' - end - - context 'tmp/compiled_content' do - let(:store_name) { 'compiled_content' } - it_behaves_like 'an old store' - end - - context 'tmp/dependencies' do - let(:store_name) { 'dependencies' } - it_behaves_like 'an old store' - end - - context 'tmp/outdatedness' do - let(:store_name) { 'outdatedness' } - it_behaves_like 'an old store' - end - - context 'tmp/action_sequence' do - let(:store_name) { 'action_sequence' } - it_behaves_like 'an old store' - end - - context 'tmp/somethingelse' do - it 'does not removes the store' do - FileUtils.mkdir_p('tmp') - File.write('tmp/somethingelse', 'stuff') - - expect { subject } - .not_to change { File.file?('tmp/somethingelse') } - end - end - - it 'removes stores for unused output paths' do - default_dir = "tmp/nanoc/#{gen_hash(Dir.getwd + '/output')}" - prod_dir = "tmp/nanoc/#{gen_hash(Dir.getwd + '/output_production')}" - staging_dir = "tmp/nanoc/#{gen_hash(Dir.getwd + '/output_staging')}" - - FileUtils.mkdir_p(default_dir) - FileUtils.mkdir_p(prod_dir) - FileUtils.mkdir_p(staging_dir) - - expect { subject } - .to change { Dir.glob('tmp/nanoc/*').sort } - .from([default_dir, prod_dir, staging_dir].sort) - .to([default_dir]) - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/stages/compile_reps_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/stages/compile_reps_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/stages/compile_reps_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/stages/compile_reps_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Compiler::Stages::CompileReps do - let(:stage) do - described_class.new( - reps: reps, - outdatedness_store: outdatedness_store, - dependency_store: dependency_store, - action_sequences: action_sequences, - compilation_context: compilation_context, - compiled_content_cache: compiled_content_cache, - ) - end - - let(:compilation_context) do - Nanoc::Int::CompilationContext.new( - action_provider: action_provider, - reps: reps, - site: site, - compiled_content_cache: compiled_content_cache, - snapshot_repo: snapshot_repo, - ) - end - - let(:action_provider) { double(:action_provider) } - let(:action_sequences) { double(:action_sequences) } - let(:reps) { Nanoc::Int::ItemRepRepo.new } - let(:compiled_content_cache) { Nanoc::Int::CompiledContentCache.new(config: config) } - let(:snapshot_repo) { Nanoc::Int::SnapshotRepo.new } - - let(:outdatedness_store) { Nanoc::Int::OutdatednessStore.new(config: config) } - let(:dependency_store) { Nanoc::Int::DependencyStore.new(items, layouts, config) } - - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } - let(:item) { Nanoc::Int::Item.new('<%= 1 + 2 %>', {}, '/hi.md') } - - let(:other_rep) { Nanoc::Int::ItemRep.new(other_item, :default) } - let(:other_item) { Nanoc::Int::Item.new('other content', {}, '/other.md') } - - let(:site) do - Nanoc::Int::Site.new( - config: config, - code_snippets: code_snippets, - data_source: Nanoc::Int::InMemDataSource.new(items, layouts), - ) - end - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - let(:code_snippets) { [] } - - let(:layouts) do - Nanoc::Int::LayoutCollection.new(config) - end - - let(:items) do - Nanoc::Int::ItemCollection.new( - config, - [item, other_item], - ) - end - - let(:memory) do - actions = - [ - Nanoc::Int::ProcessingActions::Filter.new(:erb, {}), - Nanoc::Int::ProcessingActions::Snapshot.new([:last], []), - ] - - Nanoc::Int::ActionSequence.new(nil, actions: actions) - end - - before do - reps << rep - reps << other_rep - - reps.each do |rep| - rep.snapshot_defs << Nanoc::Int::SnapshotDef.new(:last, binary: false) - end - - allow(action_sequences).to receive(:[]).with(rep).and_return(memory) - allow(action_sequences).to receive(:[]).with(other_rep).and_return(memory) - end - - describe '#compile_reps' do - subject { stage.run } - - let(:snapshot_defs_for_rep) do - [Nanoc::Int::SnapshotDef.new(:last, binary: false)] - end - - let(:snapshot_defs_for_other_rep) do - [Nanoc::Int::SnapshotDef.new(:last, binary: false)] - end - - context 'rep not in outdatedness store' do - before do - # Needed for consistency - compiled_content_cache[rep] = { last: Nanoc::Int::TextualContent.new('asdf') } - compiled_content_cache[other_rep] = { last: Nanoc::Int::TextualContent.new('asdf') } - end - - it 'keeps the item rep out of the outdatedness store' do - expect(outdatedness_store.include?(rep)).not_to be - expect { subject }.not_to change { outdatedness_store.include?(rep) } - end - end - - context 'rep in outdatedness store' do - before { outdatedness_store.add(rep) } - - before do - # Needed for consistency - compiled_content_cache[other_rep] = { last: Nanoc::Int::TextualContent.new('asdf') } - end - - it 'compiles individual reps' do - expect { subject }.to change { snapshot_repo.get(rep, :last) } - .from(nil) - .to(some_textual_content('3')) - end - - it 'removes the item rep from the outdatedness store' do - expect { subject }.to change { outdatedness_store.include?(rep) }.from(true).to(false) - end - - context 'exception' do - let(:item) { Nanoc::Int::Item.new('<%= \'invalid_ruby %>', {}, '/hi.md') } - - it 'wraps exception' do - expect { subject }.to raise_error(Nanoc::Int::Errors::CompilationError) - end - - it 'contains the right item rep in the wrapped exception' do - expect { subject }.to raise_error do |err| - expect(err.item_rep).to eql(rep) - end - end - - it 'contains the right wrapped exception' do - expect { subject }.to raise_error do |err| - expect(err.unwrap).to be_a(SyntaxError) - expect(err.unwrap.message).to start_with('item /hi.md (rep default):1: unterminated string meets end of file') - end - end - - it 'keeps the item rep in the outdatedness store' do - expect(outdatedness_store.include?(rep)).to be - expect { subject rescue nil }.not_to change { outdatedness_store.include?(rep) } - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/stages/determine_outdatedness_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/stages/determine_outdatedness_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/stages/determine_outdatedness_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/stages/determine_outdatedness_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,151 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Compiler::Stages::DetermineOutdatedness do - let(:stage) do - described_class.new( - reps: reps, - outdatedness_checker: outdatedness_checker, - outdatedness_store: outdatedness_store, - ) - end - - let(:reps) do - Nanoc::Int::ItemRepRepo.new - end - - let(:outdatedness_checker) do - double(:outdatedness_checker) - end - - let(:outdatedness_store) do - Nanoc::Int::OutdatednessStore.new(config: config) - end - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - let(:code_snippets) { [] } - - describe '#run' do - subject { stage.run } - - context 'outdatedness store is empty' do - let(:item) do - Nanoc::Int::Item.new('', {}, '/hi.md') - end - - let(:rep) do - Nanoc::Int::ItemRep.new(item, :woof) - end - - let(:other_rep) do - Nanoc::Int::ItemRep.new(item, :bark) - end - - context 'outdatedness checker thinks rep is outdated' do - before do - reps << rep - reps << other_rep - - expect(outdatedness_checker) - .to receive(:outdated?).with(rep).and_return(true) - - expect(outdatedness_checker) - .to receive(:outdated?).with(other_rep).and_return(false) - end - - it 'adds the rep' do - expect { subject } - .to change { outdatedness_store.include?(rep) } - .from(false) - .to(true) - end - - it 'also adds the other rep' do - expect { subject } - .to change { outdatedness_store.include?(other_rep) } - .from(false) - .to(true) - end - - it 'returns a list with the known rep’s item' do - expect(subject).to eq([rep.item]) - end - end - - context 'outdatedness checker thinks rep is not outdated' do - it 'keeps the outdatedness store empty' do - expect { subject } - .not_to change { outdatedness_store.empty? } - end - - it 'returns an empty list' do - expect(subject).to be_empty - end - end - end - - context 'outdatedness store contains known rep' do - let(:item) do - Nanoc::Int::Item.new('', {}, '/hi.md') - end - - let(:rep) do - Nanoc::Int::ItemRep.new(item, :woof) - end - - let(:other_rep) do - Nanoc::Int::ItemRep.new(item, :bark) - end - - before do - reps << rep - reps << other_rep - - outdatedness_store.add(rep) - - expect(outdatedness_checker) - .to receive(:outdated?).with(other_rep).and_return(false) - end - - it 'keeps the rep' do - expect { subject } - .not_to change { outdatedness_store.include?(rep) } - end - - it 'also adds the other rep' do - expect { subject } - .to change { outdatedness_store.include?(other_rep) } - .from(false) - .to(true) - end - - it 'returns a list with the known rep’s item' do - expect(subject).to eq([rep.item]) - end - end - - context 'outdatedness store contains unknown rep' do - let(:item) do - Nanoc::Int::Item.new('', {}, '/hi.md') - end - - let(:unknown_rep) do - Nanoc::Int::ItemRep.new(item, :woof) - end - - before do - outdatedness_store.add(unknown_rep) - end - - it 'removes the unknown rep' do - expect { subject } - .to change { outdatedness_store.include?(unknown_rep) } - .from(true) - .to(false) - end - - it 'returns an empty list' do - expect(subject).to be_empty - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/stages/preprocess_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/stages/preprocess_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/stages/preprocess_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/stages/preprocess_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,110 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Compiler::Stages::Preprocess do - let(:stage) do - described_class.new( - action_provider: action_provider, - site: site, - dependency_store: dependency_store, - checksum_store: checksum_store, - ) - end - - let(:action_provider) do - double(:action_provider) - end - - let(:site) do - Nanoc::Int::Site.new( - config: config, - code_snippets: [], - data_source: data_source, - ) - end - - let(:data_source) { Nanoc::Int::InMemDataSource.new(items, layouts) } - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - let(:items) { Nanoc::Int::ItemCollection.new(config) } - let(:layouts) { Nanoc::Int::LayoutCollection.new(config) } - - let(:dependency_store) do - Nanoc::Int::DependencyStore.new(items, layouts, config) - end - - let(:checksum_store) do - Nanoc::Int::ChecksumStore.new(config: config, objects: items.to_a + layouts.to_a) - end - - describe '#run' do - subject { stage.run } - - context 'no preprocessing needed' do - before do - expect(action_provider).to receive(:need_preprocessing?).and_return(false) - end - - it 'marks the site as preprocessed' do - expect { subject } - .to change { site.preprocessed? } - .from(false) - .to(true) - end - - it 'freezes the site' do - subject - end - end - - context 'preprocessing needed' do - let(:new_item) { Nanoc::Int::Item.new('new item', {}, '/new.md') } - let(:new_layout) { Nanoc::Int::Layout.new('new layout', {}, '/new.md') } - - before do - expect(action_provider).to receive(:need_preprocessing?).and_return(true) - - expect(action_provider).to receive(:preprocess) do |site| - site.data_source = - Nanoc::Int::InMemDataSource.new( - Nanoc::Int::ItemCollection.new(config, [new_item]), - Nanoc::Int::LayoutCollection.new(config, [new_layout]), - ) - end - end - - it 'marks the site as preprocessed' do - expect { subject } - .to change { site.preprocessed? } - .from(false) - .to(true) - end - - it 'freezes the site' do - expect { subject } - .to change { site.config.frozen? } - .from(false) - .to(true) - end - - it 'sets items on dependency store' do - expect { subject } - .to change { dependency_store.items.to_a } - .from([]) - .to([new_item]) - end - - it 'sets layouts on dependency store' do - expect { subject } - .to change { dependency_store.layouts.to_a } - .from([]) - .to([new_layout]) - end - - it 'sets data on checksum store' do - expect { subject } - .to change { checksum_store.objects.to_a } - .from([]) - .to(match_array([new_item, new_layout, config])) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/stage_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/stage_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/compiler/stage_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/compiler/stage_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Compiler::Stage do - subject(:stage) { klass.new } - - let(:klass) { described_class } - - before { Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) } - after { Timecop.return } - - describe '#call' do - subject { stage.call } - - it 'raises error' do - expect { subject }.to raise_error(NotImplementedError) - end - - context 'actual implementation' do - let(:klass) do - Class.new(described_class) do - def run - Timecop.freeze(Time.now + 13.57) - end - end - end - - it 'sends notification' do - expect { subject } - .to send_notification(:stage_ran, 13.57, klass) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/dependency_tracker_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/dependency_tracker_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/dependency_tracker_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/dependency_tracker_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,245 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::DependencyTracker do - let(:tracker) { described_class.new(store) } - - let(:store) { Nanoc::Int::DependencyStore.new(empty_items, empty_layouts, config) } - - let(:item_a) { Nanoc::Int::Item.new('a', {}, '/a.md') } - let(:item_b) { Nanoc::Int::Item.new('b', {}, '/b.md') } - let(:item_c) { Nanoc::Int::Item.new('c', {}, '/c.md') } - - let(:empty_items) { Nanoc::Int::ItemCollection.new(config) } - let(:empty_layouts) { Nanoc::Int::LayoutCollection.new(config) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - shared_examples 'a null dependency tracker' do - let(:tracker) { Nanoc::Int::DependencyTracker::Null.new } - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_a) } - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_b) } - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_c) } - end - - example do - expect { subject }.not_to change { store.dependencies_causing_outdatedness_of(item_a) } - end - - example do - expect { subject }.not_to change { store.dependencies_causing_outdatedness_of(item_b) } - end - - example do - expect { subject }.not_to change { store.dependencies_causing_outdatedness_of(item_c) } - end - end - - describe '#enter and #exit' do - context 'enter' do - subject do - tracker.enter(item_a) - end - - it_behaves_like 'a null dependency tracker' - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_a) } - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_b) } - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_c) } - end - end - - context 'enter + enter' do - subject do - tracker.enter(item_a) - tracker.enter(item_b) - end - - it_behaves_like 'a null dependency tracker' - - it 'changes predecessors of item A' do - expect { subject }.to change { store.objects_causing_outdatedness_of(item_a) } - .from([]).to([item_b]) - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_b) } - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_c) } - end - end - - context 'enter + enter with props' do - subject do - tracker.enter(item_a) - tracker.enter(item_b, compiled_content: true) - end - - it_behaves_like 'a null dependency tracker' - - it 'changes predecessors of item A' do - expect { subject }.to change { store.objects_causing_outdatedness_of(item_a) } - .from([]).to([item_b]) - end - - it 'changes dependencies causing outdatedness of item A' do - expect { subject }.to change { store.dependencies_causing_outdatedness_of(item_a).size } - .from(0).to(1) - end - - it 'creates correct new dependency causing outdatedness of item A' do - subject - dep = store.dependencies_causing_outdatedness_of(item_a)[0] - - expect(dep.from).to eql(item_b) - expect(dep.to).to eql(item_a) - end - - it 'creates dependency with correct props causing outdatedness of item A' do - subject - dep = store.dependencies_causing_outdatedness_of(item_a)[0] - - expect(dep.props.compiled_content?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.attributes?).to eq(false) - expect(dep.props.path?).to eq(false) - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_b) } - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_c) } - end - - example do - expect { subject }.not_to change { store.dependencies_causing_outdatedness_of(item_b) } - end - - example do - expect { subject }.not_to change { store.dependencies_causing_outdatedness_of(item_c) } - end - end - - context 'enter + enter with prop + exit + enter with prop' do - subject do - tracker.enter(item_a) - tracker.enter(item_b, compiled_content: true) - tracker.exit - tracker.enter(item_b, attributes: true) - end - - it_behaves_like 'a null dependency tracker' - - it 'changes predecessors of item A' do - expect { subject }.to change { store.objects_causing_outdatedness_of(item_a) } - .from([]).to([item_b]) - end - - it 'changes dependencies causing outdatedness of item A' do - expect { subject }.to change { store.dependencies_causing_outdatedness_of(item_a).size } - .from(0).to(1) - end - - it 'creates correct new dependency causing outdatedness of item A' do - subject - dep = store.dependencies_causing_outdatedness_of(item_a)[0] - - expect(dep.from).to eql(item_b) - expect(dep.to).to eql(item_a) - end - - it 'creates dependency with correct props causing outdatedness of item A' do - subject - dep = store.dependencies_causing_outdatedness_of(item_a)[0] - - expect(dep.props.compiled_content?).to eq(true) - expect(dep.props.attributes?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.path?).to eq(false) - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_b) } - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_c) } - end - - example do - expect { subject }.not_to change { store.dependencies_causing_outdatedness_of(item_b) } - end - - example do - expect { subject }.not_to change { store.dependencies_causing_outdatedness_of(item_c) } - end - end - - context 'enter + enter + exit + enter' do - subject do - tracker.enter(item_a) - tracker.enter(item_b) - tracker.exit - tracker.enter(item_c) - end - - it_behaves_like 'a null dependency tracker' - - it 'changes predecessors of item A' do - expect { subject }.to change { store.objects_causing_outdatedness_of(item_a) } - .from([]).to([item_b, item_c]) - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_b) } - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_c) } - end - end - - context 'enter + bounce + enter' do - subject do - tracker.enter(item_a) - tracker.bounce(item_b) - tracker.enter(item_c) - end - - it_behaves_like 'a null dependency tracker' - - it 'changes predecessors of item A' do - expect { subject }.to change { store.objects_causing_outdatedness_of(item_a) } - .from([]).to([item_b, item_c]) - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_b) } - end - - example do - expect { subject }.not_to change { store.objects_causing_outdatedness_of(item_c) } - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/executor_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/executor_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/executor_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/executor_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,686 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::Executor do - let(:executor) { described_class.new(rep, compilation_context, dependency_tracker) } - - let(:compilation_context) do - Nanoc::Int::CompilationContext.new( - action_provider: action_provider, - reps: reps, - site: site, - compiled_content_cache: compiled_content_cache, - snapshot_repo: snapshot_repo, - ) - end - - let(:item) { Nanoc::Int::Item.new(content, {}, '/index.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :donkey) } - let(:content) { Nanoc::Int::TextualContent.new('Donkey Power').tap(&:freeze) } - - let(:action_provider) { double(:action_provider) } - let(:reps) { double(:reps) } - let(:site) { double(:site) } - let(:compiled_content_cache) { double(:compiled_content_cache) } - let(:snapshot_repo) { Nanoc::Int::SnapshotRepo.new } - - let(:dependency_tracker) { Nanoc::Int::DependencyTracker.new(double(:dependency_store)) } - - describe '#filter' do - let(:assigns) { {} } - - let(:content) { Nanoc::Int::TextualContent.new('<%= "Donkey" %> Power') } - - before do - allow(compilation_context).to receive(:assigns_for) { assigns } - end - - context 'normal flow with textual rep' do - subject { executor.filter(:erb) } - - before do - expect(Nanoc::Int::NotificationCenter) - .to receive(:post).with(:filtering_started, rep, :erb) - expect(Nanoc::Int::NotificationCenter) - .to receive(:post).with(:filtering_ended, rep, :erb) - - snapshot_repo.set(rep, :last, content) - end - - it 'does not set :pre on rep' do - expect(snapshot_repo.get(rep, :pre)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :pre) } - end - - it 'does not set :post on rep' do - expect(snapshot_repo.get(rep, :post)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :post) } - end - - it 'updates :last on rep' do - expect { subject } - .to change { snapshot_repo.get(rep, :last).string } - .from('<%= "Donkey" %> Power') - .to('Donkey Power') - end - - it 'does not set :pre in repo' do - expect(snapshot_repo.get(rep, :pre)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :pre) } - end - - it 'does not set :post in repo' do - expect(snapshot_repo.get(rep, :post)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :post) } - end - - it 'updates :last in repo' do - expect { subject } - .to change { snapshot_repo.get(rep, :last).string } - .from('<%= "Donkey" %> Power') - .to('Donkey Power') - end - - it 'returns frozen data' do - executor.filter(:erb) - - expect(snapshot_repo.get(rep, :last)).to be_frozen - end - end - - context 'normal flow with binary rep' do - subject { executor.filter(:whatever) } - - let(:content) { Nanoc::Int::BinaryContent.new(File.expand_path('foo.dat')) } - - before do - expect(Nanoc::Int::NotificationCenter) - .to receive(:post).with(:filtering_started, rep, :whatever) - expect(Nanoc::Int::NotificationCenter) - .to receive(:post).with(:filtering_ended, rep, :whatever) - - File.write(content.filename, 'Foo Data') - - filter_class = Class.new(::Nanoc::Filter) do - type :binary - - def run(filename, _params = {}) - File.write(output_filename, "Compiled data for #{filename}") - end - end - - expect(Nanoc::Filter).to receive(:named).with(:whatever) { filter_class } - - snapshot_repo.set(rep, :last, content) - end - - it 'does not set :pre on rep' do - expect(snapshot_repo.get(rep, :pre)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :pre) } - end - - it 'does not set :post on rep' do - expect(snapshot_repo.get(rep, :post)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :post) } - end - - it 'updates :last on rep' do - expect { subject } - .to change { snapshot_repo.get(rep, :last) } - .from(some_binary_content('Foo Data')) - .to(some_binary_content(/\ACompiled data for (C:)?\/.*\/foo.dat\z/)) - end - - it 'does not set :pre in repo' do - expect(snapshot_repo.get(rep, :pre)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :pre) } - end - - it 'does not set :post in repo' do - expect(snapshot_repo.get(rep, :post)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :post) } - end - - it 'updates :last in repo' do - expect { subject } - .to change { File.read(snapshot_repo.get(rep, :last).filename) } - .from('Foo Data') - .to(/\ACompiled data for (C:)?\/.*\/foo.dat\z/) - end - - it 'returns frozen data' do - executor.filter(:whatever) - - expect(snapshot_repo.get(rep, :last)).to be_frozen - end - end - - context 'normal flow with binary rep and binary-to-text filter' do - subject { executor.filter(:whatever) } - - let(:content) { Nanoc::Int::BinaryContent.new(File.expand_path('foo.dat')) } - - before do - expect(Nanoc::Int::NotificationCenter) - .to receive(:post).with(:filtering_started, rep, :whatever) - expect(Nanoc::Int::NotificationCenter) - .to receive(:post).with(:filtering_ended, rep, :whatever) - - File.write(content.filename, 'Foo Data') - - filter_class = Class.new(::Nanoc::Filter) do - type binary: :text - - def run(filename, _params = {}) - "Compiled data for #{filename}" - end - end - - expect(Nanoc::Filter).to receive(:named).with(:whatever) { filter_class } - - snapshot_repo.set(rep, :last, content) - end - - it 'does not set :pre on rep' do - expect(snapshot_repo.get(rep, :pre)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :pre) } - end - - it 'does not set :post on rep' do - expect(snapshot_repo.get(rep, :post)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :post) } - end - - it 'updates :last on rep' do - expect { subject } - .to change { snapshot_repo.get(rep, :last) } - .from(some_binary_content('Foo Data')) - .to(some_textual_content(/\ACompiled data for (C:)?\/.*\/foo.dat\z/)) - end - - it 'does not set :pre in repo' do - expect(snapshot_repo.get(rep, :pre)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :pre) } - end - - it 'does not set :post in repo' do - expect(snapshot_repo.get(rep, :post)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :post) } - end - - it 'updates :last in repo' do - expect { subject } - .to change { snapshot_repo.get(rep, :last) } - .from(some_binary_content('Foo Data')) - .to(some_textual_content(/\ACompiled data for (C:)?\/.*\/foo.dat\z/)) - end - end - - context 'normal flow with textual rep and text-to-binary filter' do - subject { executor.filter(:whatever) } - - before do - expect(Nanoc::Int::NotificationCenter) - .to receive(:post).with(:filtering_started, rep, :whatever) - expect(Nanoc::Int::NotificationCenter) - .to receive(:post).with(:filtering_ended, rep, :whatever) - - filter_class = Class.new(::Nanoc::Filter) do - type text: :binary - - def run(content, _params = {}) - File.write(output_filename, "Binary #{content}") - end - end - - expect(Nanoc::Filter).to receive(:named).with(:whatever) { filter_class } - - snapshot_repo.set(rep, :last, content) - end - - it 'does not set :pre on rep' do - expect(snapshot_repo.get(rep, :pre)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :pre) } - end - - it 'does not set :post on rep' do - expect(snapshot_repo.get(rep, :post)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :post) } - end - - it 'updates :last on rep' do - expect { subject } - .to change { snapshot_repo.get(rep, :last) } - .from(some_textual_content('<%= "Donkey" %> Power')) - .to(some_binary_content('Binary <%= "Donkey" %> Power')) - end - - it 'does not set :pre in repo' do - expect(snapshot_repo.get(rep, :pre)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :pre) } - end - - it 'does not set :post in repo' do - expect(snapshot_repo.get(rep, :post)).to be_nil - expect { subject }.not_to change { snapshot_repo.get(rep, :post) } - end - - it 'updates :last in repo' do - expect { subject } - .to change { snapshot_repo.get(rep, :last) } - .from(some_textual_content('<%= "Donkey" %> Power')) - .to(some_binary_content('Binary <%= "Donkey" %> Power')) - end - end - - context 'non-existant filter' do - it 'raises' do - expect { executor.filter(:ajlsdfjklaskldfj) } - .to raise_error(Nanoc::Int::Errors::UnknownFilter) - end - end - - context 'non-binary rep, binary-to-something filter' do - before do - filter_class = Class.new(::Nanoc::Filter) do - type :binary - - def run(_content, _params = {}); end - end - - expect(Nanoc::Filter).to receive(:named).with(:whatever) { filter_class } - - snapshot_repo.set(rep, :last, content) - end - - it 'raises' do - expect { executor.filter(:whatever) } - .to raise_error(Nanoc::Int::Errors::CannotUseBinaryFilter) - end - end - - context 'binary rep, text-to-something filter' do - let(:content) { Nanoc::Int::BinaryContent.new(File.expand_path('foo.md')) } - - before do - snapshot_repo.set(rep, :last, content) - end - - it 'raises' do - expect { executor.filter(:erb) } - .to raise_error(Nanoc::Int::Errors::CannotUseTextualFilter) - end - end - - context 'binary filter that does not write anything' do - let(:content) { Nanoc::Int::BinaryContent.new(File.expand_path('foo.dat')) } - - before do - expect(Nanoc::Int::NotificationCenter) - .to receive(:post).with(:filtering_started, rep, :whatever) - expect(Nanoc::Int::NotificationCenter) - .to receive(:post).with(:filtering_ended, rep, :whatever) - - File.write(content.filename, 'Foo Data') - - filter_class = Class.new(::Nanoc::Filter) do - type :binary - - def run(_filename, _params = {}); end - end - - snapshot_repo.set(rep, :last, content) - - expect(Nanoc::Filter).to receive(:named).with(:whatever) { filter_class } - end - - example do - expect { executor.filter(:whatever) } - .to raise_error(Nanoc::Int::Errors::OutputNotWritten) - end - end - - context 'content is frozen' do - before do - snapshot_repo.set(rep, :last, item.content) - end - - let(:item) do - Nanoc::Int::Item.new('foo bar', {}, '/foo.md').tap(&:freeze) - end - - let(:filter_that_modifies_content) do - Class.new(::Nanoc::Filter) do - def run(content, _params = {}) - content.gsub!('foo', 'moo') - content - end - end - end - - let(:filter_that_modifies_params) do - Class.new(::Nanoc::Filter) do - def run(_content, params = {}) - params[:foo] = 'bar' - 'asdf' - end - end - end - - it 'errors when attempting to modify content' do - expect(Nanoc::Filter).to receive(:named).with(:whatever).and_return(filter_that_modifies_content) - expect { executor.filter(:whatever) }.to raise_frozen_error - end - - it 'receives frozen filter args' do - expect(Nanoc::Filter).to receive(:named).with(:whatever).and_return(filter_that_modifies_params) - expect { executor.filter(:whatever) }.to raise_frozen_error - end - end - end - - describe '#layout' do - let(:site) { double(:site, config: config, layouts: layouts) } - - let(:config) do - { - string_pattern_type: 'glob', - } - end - - let(:layout) do - Nanoc::Int::Layout.new(layout_content, { bug: 'Gum Emperor' }, '/default.erb') - end - - let(:layouts) { [layout] } - - let(:layout_content) { 'head <%= @foo %> foot' } - - let(:assigns) do - { foo: 'hallo' } - end - - let(:view_context) do - Nanoc::ViewContextForCompilation.new( - reps: Nanoc::Int::ItemRepRepo.new, - items: Nanoc::Int::ItemCollection.new(config), - dependency_tracker: dependency_tracker, - compilation_context: double(:compilation_context), - snapshot_repo: snapshot_repo, - ) - end - - let(:action_sequence) do - Nanoc::Int::ActionSequence.build(rep) do |b| - b.add_filter(:erb, {}) - end - end - - before do - rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(:pre, binary: false)] - - snapshot_repo.set(rep, :last, content) - - allow(compilation_context).to receive(:site) { site } - allow(compilation_context).to receive(:assigns_for).with(rep, dependency_tracker) { assigns } - allow(compilation_context).to receive(:create_view_context).with(dependency_tracker).and_return(view_context) - - allow(action_provider).to receive(:action_sequence_for).with(layout).and_return(action_sequence) - end - - subject { executor.layout('/default.*') } - - context 'accessing layout attributes' do - let(:layout_content) { 'head <%= @layout[:bug] %> foot' } - - it 'exposes @layout as view' do - allow(dependency_tracker).to receive(:enter) - .with(layout, raw_content: true, attributes: false, compiled_content: false, path: false) - allow(dependency_tracker).to receive(:enter) - .with(layout, raw_content: false, attributes: [:bug], compiled_content: false, path: false) - allow(dependency_tracker).to receive(:exit) - subject - expect(snapshot_repo.get(rep, :last).string).to eq('head Gum Emperor foot') - end - end - - context 'normal flow' do - it 'updates :last on rep' do - expect { subject } - .to change { snapshot_repo.get(rep, :last) } - .from(some_textual_content('Donkey Power')) - .to(some_textual_content('head hallo foot')) - end - - it 'updates :last in repo' do - expect { subject } - .to change { snapshot_repo.get(rep, :last) } - .from(some_textual_content('Donkey Power')) - .to(some_textual_content('head hallo foot')) - end - - it 'sets frozen content' do - subject - expect(snapshot_repo.get(rep, :last)).to be_frozen - expect(snapshot_repo.get(rep, :pre)).to be_frozen - end - - it 'does not create pre snapshot' do - # a #layout is followed by a #snapshot(:pre, …) - expect(snapshot_repo.get(rep, :pre)).to be_nil - subject - expect(snapshot_repo.get(rep, :pre)).to be_nil - end - - it 'sends notifications' do - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:filtering_started, rep, :erb).ordered - expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:filtering_ended, rep, :erb).ordered - - subject - end - - context 'compiled_content reference in layout' do - let(:layout_content) { 'head <%= @item_rep.compiled_content(snapshot: :pre) %> foot' } - - let(:assigns) do - { item_rep: Nanoc::CompilationItemRepView.new(rep, view_context) } - end - - before do - executor.snapshot(:pre) - end - - it 'updates :last on rep' do - expect { subject } - .to change { snapshot_repo.get(rep, :last) } - .from(some_textual_content('Donkey Power')) - .to(some_textual_content('head Donkey Power foot')) - end - - it 'updates :last in repo' do - expect { subject } - .to change { snapshot_repo.get(rep, :last) } - .from(some_textual_content('Donkey Power')) - .to(some_textual_content('head Donkey Power foot')) - end - end - - context 'content with layout reference' do - let(:layout_content) { 'head <%= @layout.identifier %> foot' } - - it 'updates :last on rep' do - expect { subject } - .to change { snapshot_repo.get(rep, :last) } - .from(some_textual_content('Donkey Power')) - .to(some_textual_content('head /default.erb foot')) - end - - it 'updates :last in repo' do - expect { subject } - .to change { snapshot_repo.get(rep, :last) } - .from(some_textual_content('Donkey Power')) - .to(some_textual_content('head /default.erb foot')) - end - end - end - - context 'no layout found' do - let(:layouts) do - [Nanoc::Int::Layout.new('head <%= @foo %> foot', {}, '/other.erb')] - end - - it 'raises' do - expect { subject }.to raise_error(Nanoc::Int::Errors::UnknownLayout) - end - end - - context 'no filter specified' do - let(:action_sequence) do - Nanoc::Int::ActionSequence.new(rep) - end - - it 'raises' do - expect { subject }.to raise_error(Nanoc::Int::Errors::UndefinedFilterForLayout) - end - end - - context 'binary item' do - let(:content) { Nanoc::Int::BinaryContent.new(File.expand_path('donkey.md')) } - - it 'raises' do - expect { subject }.to raise_error( - Nanoc::Int::Errors::CannotLayoutBinaryItem, - 'The “/index.md” item (rep “donkey”) cannot be laid out because it is a binary item. If you are getting this error for an item that should be textual instead of binary, make sure that its extension is included in the text_extensions array in the site configuration.', - ) - end - end - - it 'receives frozen filter args' do - filter_class = Class.new(::Nanoc::Filter) do - def run(_content, params = {}) - params[:foo] = 'bar' - 'asdf' - end - end - - expect(Nanoc::Filter).to receive(:named).with(:erb) { filter_class } - - expect { subject }.to raise_frozen_error - end - end - - describe '#snapshot' do - subject { executor.snapshot(:something) } - - before do - snapshot_repo.set(rep, :last, content) - - File.write('donkey.dat', 'binary donkey') - end - - context 'binary content' do - let(:content) { Nanoc::Int::BinaryContent.new(File.expand_path('donkey.dat')) } - - it 'creates snapshots on rep' do - expect { subject } - .to change { snapshot_repo.get(rep, :something) } - .from(nil) - .to(some_binary_content('binary donkey')) - end - - it 'creates snapshots in repo' do - expect { subject } - .to change { snapshot_repo.get(rep, :something) } - .from(nil) - .to(some_binary_content('binary donkey')) - end - end - - context 'textual content' do - let(:content) { Nanoc::Int::TextualContent.new('Donkey Power') } - - it 'creates snapshots on rep' do - expect { subject } - .to change { snapshot_repo.get(rep, :something) } - .from(nil) - .to(some_textual_content('Donkey Power')) - end - - it 'creates snapshots in repo' do - expect { subject } - .to change { snapshot_repo.get(rep, :something) } - .from(nil) - .to(some_textual_content('Donkey Power')) - end - end - - context 'final snapshot' do - let(:content) { Nanoc::Int::TextualContent.new('Donkey Power') } - - context 'raw path' do - before do - rep.raw_paths = { something: [Dir.getwd + '/output/donkey.md'] } - end - - it 'does not write' do - executor.snapshot(:something) - - expect(File.file?('output/donkey.md')).not_to be - end - end - - context 'no raw path' do - it 'does not write' do - executor.snapshot(:something) - - expect(File.file?('output/donkey.md')).to eq(false) - end - end - end - end - - describe '#find_layout' do - let(:site) { double(:site, config: config, layouts: layouts) } - - let(:config) { {} } - - before do - allow(compilation_context).to receive(:site) { site } - end - - subject { executor.find_layout(arg) } - - context 'layout with cleaned identifier exists' do - let(:arg) { '/default' } - - let(:layouts) do - [Nanoc::Int::Layout.new('head <%= @foo %> foot', {}, Nanoc::Identifier.new('/default/', type: :legacy))] - end - - it { is_expected.to eq(layouts[0]) } - end - - context 'no layout with cleaned identifier exists' do - let(:layouts) do - [Nanoc::Int::Layout.new('head <%= @foo %> foot', {}, '/default.erb')] - end - - context 'globs' do - let(:config) { { string_pattern_type: 'glob' } } - - let(:arg) { '/default.*' } - - it { is_expected.to eq(layouts[0]) } - end - - context 'no globs' do - let(:config) { { string_pattern_type: 'legacy' } } - - let(:arg) { '/default.*' } - - it 'raises' do - expect { subject }.to raise_error(Nanoc::Int::Errors::UnknownLayout) - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/instrumentor_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/instrumentor_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/instrumentor_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/instrumentor_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -describe(Nanoc::Int::Instrumentor) do - subject { described_class } - - before { Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) } - after { Timecop.return } - - it 'sends notification' do - expect do - subject.call(:sample_notification, 'garbage', 123) do - # Go to a few seconds in the future - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 5)) - end - end.to send_notification(:sample_notification, 5.0, 'garbage', 123) - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/item_rep_router_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/item_rep_router_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/item_rep_router_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/item_rep_router_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,198 +0,0 @@ -# frozen_string_literal: true - -describe(Nanoc::Int::ItemRepRouter) do - subject(:item_rep_router) { described_class.new(reps, action_provider, site) } - - let(:reps) { double(:reps) } - let(:action_provider) { double(:action_provider) } - let(:site) { double(:site, config: config) } - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - describe '#run' do - subject { item_rep_router.run } - - let(:item) { Nanoc::Int::Item.new('content', {}, '/foo.md') } - - let(:reps) do - [ - Nanoc::Int::ItemRep.new(item, :default), - Nanoc::Int::ItemRep.new(item, :csv), - ] - end - - let(:memory_without_paths) do - actions = - [ - Nanoc::Int::ProcessingActions::Filter.new(:erb, {}), - Nanoc::Int::ProcessingActions::Snapshot.new([], []), - ] - - Nanoc::Int::ActionSequence.new(nil, actions: actions) - end - - let(:action_sequence_for_default) do - actions = - [ - Nanoc::Int::ProcessingActions::Filter.new(:erb, {}), - Nanoc::Int::ProcessingActions::Snapshot.new([:last], ['/foo/index.html']), - ] - - Nanoc::Int::ActionSequence.new(nil, actions: actions) - end - - let(:action_sequence_for_csv) do - actions = - [ - Nanoc::Int::ProcessingActions::Filter.new(:erb, {}), - Nanoc::Int::ProcessingActions::Snapshot.new([:last], ['/foo.csv']), - ] - - Nanoc::Int::ActionSequence.new(nil, actions: actions) - end - - example do - allow(action_provider).to receive(:action_sequence_for).with(reps[0]).and_return(action_sequence_for_default) - allow(action_provider).to receive(:action_sequence_for).with(reps[1]).and_return(action_sequence_for_csv) - - subject - - expect(reps[0].raw_paths).to eql(last: [Dir.getwd + '/output/foo/index.html']) - expect(reps[0].paths).to eql(last: ['/foo/']) - - expect(reps[1].raw_paths).to eql(last: [Dir.getwd + '/output/foo.csv']) - expect(reps[1].paths).to eql(last: ['/foo.csv']) - end - - it 'picks the paths last returned' do - allow(action_provider).to receive(:action_sequence_for) - .with(reps[0]).and_return(memory_without_paths, action_sequence_for_default) - allow(action_provider).to receive(:action_sequence_for) - .with(reps[1]).and_return(memory_without_paths, action_sequence_for_csv) - - subject - - expect(reps[0].raw_paths).to eql(last: [Dir.getwd + '/output/foo/index.html']) - expect(reps[0].paths).to eql(last: ['/foo/']) - - expect(reps[1].raw_paths).to eql(last: [Dir.getwd + '/output/foo.csv']) - expect(reps[1].paths).to eql(last: ['/foo.csv']) - end - end - - describe '#route_rep' do - subject { item_rep_router.route_rep(rep, paths, snapshot_names, paths_to_reps) } - - let(:snapshot_names) { [:foo] } - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } - let(:item) { Nanoc::Int::Item.new('content', {}, '/foo.md') } - let(:paths_to_reps) { {} } - - context 'basic path is nil' do - let(:paths) { [] } - - it 'assigns no paths' do - subject - expect(rep.raw_paths[:foo]).to be_empty - end - end - - context 'basic path is not nil' do - let(:paths) { ['/foo/index.html'] } - - context 'other snapshot with this path already exists' do - let(:paths_to_reps) { { '/foo/index.html' => Nanoc::Int::ItemRep.new(item, :other) } } - - it 'errors' do - expect { subject }.to raise_error(Nanoc::Int::ItemRepRouter::IdenticalRoutesError, 'The item representations /foo.md (rep name :default) and /foo.md (rep name :other) are both routed to /foo/index.html.') - end - end - - context 'path is unique' do - context 'single path' do - it 'sets the raw path' do - subject - expect(rep.raw_paths).to eql(foo: [Dir.getwd + '/output/foo/index.html']) - end - - it 'sets the path' do - subject - expect(rep.paths).to eql(foo: ['/foo/']) - end - - it 'adds to paths_to_reps' do - subject - expect(paths_to_reps).to have_key('/foo/index.html') - end - - context 'path does not start with a slash' do - let(:paths) { ['foo/index.html'] } - - it 'errors' do - expect { subject }.to raise_error(Nanoc::Int::ItemRepRouter::RouteWithoutSlashError, 'The item representation /foo.md (rep name :default) is routed to foo/index.html, which does not start with a slash, as required.') - end - end - - context 'path is not UTF-8' do - let(:paths) { ['/foo/index.html'.encode('ISO-8859-1')] } - - it 'sets the path as UTF-8' do - subject - expect(rep.paths).to eql(foo: ['/foo/']) - expect(rep.paths[:foo].first.encoding.to_s).to eql('UTF-8') - end - - it 'sets the raw path as UTF-8' do - subject - expect(rep.raw_paths).to eql(foo: [Dir.getwd + '/output/foo/index.html']) - expect(rep.raw_paths[:foo].first.encoding.to_s).to eql('UTF-8') - end - end - end - - context 'multiple paths' do - let(:paths) { ['/foo/index.html', '/bar/index.html'] } - - it 'sets the raw paths' do - subject - expect(rep.raw_paths).to eql(foo: [Dir.getwd + '/output/foo/index.html', Dir.getwd + '/output/bar/index.html']) - end - - it 'sets the paths' do - subject - expect(rep.paths).to eql(foo: ['/foo/', '/bar/']) - end - - it 'adds to paths_to_reps' do - subject - expect(paths_to_reps).to have_key('/foo/index.html') - expect(paths_to_reps).to have_key('/bar/index.html') - end - end - end - end - end - - describe '#strip_index_filename' do - subject { item_rep_router.strip_index_filename(basic_path) } - - context 'basic path ends with /index.html' do - let(:basic_path) { '/bar/index.html' } - it { is_expected.to eql('/bar/') } - end - - context 'basic path contains /index.html' do - let(:basic_path) { '/bar/index.html/foo' } - it { is_expected.to eql('/bar/index.html/foo') } - end - - context 'basic path ends with xindex.html' do - let(:basic_path) { '/bar/xindex.html' } - it { is_expected.to eql('/bar/xindex.html') } - end - - context 'basic path does not contain /index.html' do - let(:basic_path) { '/bar/foo.html' } - it { is_expected.to eql('/bar/foo.html') } - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/item_rep_selector_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/item_rep_selector_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/item_rep_selector_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/item_rep_selector_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,227 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::ItemRepSelector do - let(:selector) { described_class.new(reps_for_selector) } - - let(:item) do - Nanoc::Int::Item.new('stuff', {}, '/foo.md') - end - - let(:reps_array) do - [ - Nanoc::Int::ItemRep.new(item, :a), - Nanoc::Int::ItemRep.new(item, :b), - Nanoc::Int::ItemRep.new(item, :c), - Nanoc::Int::ItemRep.new(item, :d), - Nanoc::Int::ItemRep.new(item, :e), - ] - end - - let(:reps_for_selector) { reps_array } - - let(:names_to_reps) do - reps_array.each_with_object({}) do |rep, acc| - acc[rep.name] = rep - end - end - - let(:dependencies) { {} } - - let(:result) do - tentatively_yielded = [] - successfully_yielded = [] - selector.each do |rep| - tentatively_yielded << rep.name - - dependencies.fetch(rep.name, []).each do |name| - unless successfully_yielded.include?(name) - raise Nanoc::Int::Errors::UnmetDependency.new(names_to_reps[name]) - end - end - - successfully_yielded << rep.name - end - - [tentatively_yielded, successfully_yielded] - end - - let(:tentatively_yielded) { result[0] } - let(:successfully_yielded) { result[1] } - - describe 'error' do - context 'plain error' do - subject { selector.each { |_rep| raise 'heh' } } - - it 'raises' do - expect { subject }.to raise_error(RuntimeError, 'heh') - end - end - - context 'plain dependency error' do - subject do - idx = 0 - selector.each do |_rep| - idx += 1 - - raise Nanoc::Int::Errors::UnmetDependency.new(reps_array[2]) if idx == 1 - end - end - - it 'does not raise' do - expect { subject }.not_to raise_error - end - end - - context 'wrapped error' do - subject do - selector.each do |rep| - begin - raise 'heh' - rescue => e - raise Nanoc::Int::Errors::CompilationError.new(e, rep) - end - end - end - - it 'raises original error' do - expect { subject }.to raise_error(Nanoc::Int::Errors::CompilationError) do |err| - expect(err.unwrap).to be_a(RuntimeError) - expect(err.unwrap.message).to eq('heh') - end - end - end - - context 'wrapped dependency error' do - subject do - idx = 0 - selector.each do |rep| - idx += 1 - - begin - raise Nanoc::Int::Errors::UnmetDependency.new(reps_array[2]) if idx == 1 - rescue => e - raise Nanoc::Int::Errors::CompilationError.new(e, rep) - end - end - end - - it 'does not raise' do - expect { subject }.not_to raise_error - end - end - end - - describe 'cycle' do - context 'dependency on self' do - subject do - selector.each { |r| raise Nanoc::Int::Errors::UnmetDependency.new(r) } - end - - example do - expect { subject }.to raise_error(Nanoc::Int::Errors::DependencyCycle, <<~EOS) - The site cannot be compiled because there is a dependency cycle: - - (1) item /foo.md, rep :a, uses compiled content of (1) - EOS - end - end - - context 'cycle with three dependencies' do - subject do - selector.each do |r| - case r - when reps_array[0] - raise Nanoc::Int::Errors::UnmetDependency.new(reps_array[1]) - when reps_array[1] - raise Nanoc::Int::Errors::UnmetDependency.new(reps_array[2]) - when reps_array[2] - raise Nanoc::Int::Errors::UnmetDependency.new(reps_array[0]) - end - end - end - - example do - expect { subject }.to raise_error(Nanoc::Int::Errors::DependencyCycle, <<~EOS) - The site cannot be compiled because there is a dependency cycle: - - (1) item /foo.md, rep :a, uses compiled content of - (2) item /foo.md, rep :b, uses compiled content of - (3) item /foo.md, rep :c, uses compiled content of (1) - EOS - end - end - end - - describe 'yield order' do - context 'linear dependencies' do - let(:dependencies) do - { - a: [:b], - b: [:c], - c: [:d], - d: [:e], - e: [], - } - end - - example do - expect(successfully_yielded).to eq %i[e d c b a] - expect(tentatively_yielded).to eq %i[a b c d e d c b a] - end - end - - context 'no dependencies' do - let(:dependencies) do - {} - end - - example do - expect(successfully_yielded).to eq %i[a b c d e] - expect(tentatively_yielded).to eq %i[a b c d e] - end - end - - context 'star dependencies' do - let(:dependencies) do - { - a: %i[b c d e], - } - end - - example do - expect(successfully_yielded).to eq %i[b c d e a] - expect(tentatively_yielded).to eq %i[a b a c a d a e a] - end - end - - context 'star dependencies; selectively recompiling' do - let(:reps_for_selector) { reps_array.first(1) } - - let(:dependencies) do - { - a: %i[b c d e], - } - end - - example do - expect(successfully_yielded).to eq %i[b c d e a] - expect(tentatively_yielded).to eq %i[a b a c a d a e a] - end - end - - context 'unrelated roots' do - let(:dependencies) do - { - a: [:d], - b: [:e], - c: [], - } - end - - it 'picks prioritised roots' do - expect(successfully_yielded).to eq %i[d a e b c] - expect(tentatively_yielded).to eq %i[a d a b e b c] - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/notification_center_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/notification_center_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/notification_center_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/notification_center_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::NotificationCenter do - it 'receives notification after subscribing' do - ping_received = false - Nanoc::Int::NotificationCenter.on :ping_received, :test do - ping_received = true - end - - Nanoc::Int::NotificationCenter.post :ping_received - expect(ping_received).to be - end - - it 'does not receive notification after unsubscribing' do - ping_received = false - Nanoc::Int::NotificationCenter.on :ping_received, :test do - ping_received = true - end - - Nanoc::Int::NotificationCenter.remove :ping_received, :test - - Nanoc::Int::NotificationCenter.post :ping_received - expect(ping_received).not_to be - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/outdatedness_checker_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/outdatedness_checker_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/outdatedness_checker_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/outdatedness_checker_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,778 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::OutdatednessChecker do - let(:outdatedness_checker) do - described_class.new( - site: site, - checksum_store: checksum_store, - checksums: checksums, - dependency_store: dependency_store, - action_sequence_store: action_sequence_store, - action_sequences: action_sequences, - reps: reps, - ) - end - - let(:checksum_store) { double(:checksum_store) } - - let(:checksums) do - Nanoc::Int::Compiler::Stages::CalculateChecksums.new( - items: items, - layouts: layouts, - code_snippets: code_snippets, - config: config, - ).run - end - - let(:dependency_store) do - Nanoc::Int::DependencyStore.new(items, layouts, config) - end - - let(:items) { Nanoc::Int::ItemCollection.new(config, [item]) } - let(:layouts) { Nanoc::Int::LayoutCollection.new(config) } - - let(:code_snippets) { [] } - - let(:site) do - Nanoc::Int::Site.new( - config: config, - code_snippets: code_snippets, - data_source: Nanoc::Int::InMemDataSource.new([], []), - ) - end - - let(:action_sequence_store) do - Nanoc::Int::ActionSequenceStore.new(config: config) - end - - let(:old_action_sequence_for_item_rep) do - Nanoc::Int::ActionSequence.build(item_rep) do |b| - b.add_filter(:erb, {}) - end - end - - let(:new_action_sequence_for_item_rep) { old_action_sequence_for_item_rep } - - let(:action_sequences) do - { item_rep => new_action_sequence_for_item_rep } - end - - let(:reps) do - Nanoc::Int::ItemRepRepo.new - end - - let(:item_rep) { Nanoc::Int::ItemRep.new(item, :default) } - let(:item) { Nanoc::Int::Item.new('stuff', {}, '/foo.md') } - - before do - reps << item_rep - action_sequence_store[item_rep] = old_action_sequence_for_item_rep.serialize - end - - describe 'basic outdatedness reasons' do - subject { outdatedness_checker.send(:basic).outdatedness_status_for(obj).reasons.first } - - let(:checksum_store) { Nanoc::Int::ChecksumStore.new(config: config, objects: items.to_a + layouts.to_a) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - before do - checksum_store.add(item) - - allow(site).to receive(:code_snippets).and_return([]) - allow(site).to receive(:config).and_return(config) - end - - context 'with item' do - let(:obj) { item } - - context 'action sequence differs' do - let(:new_action_sequence_for_item_rep) do - Nanoc::Int::ActionSequence.build(item_rep) do |b| - b.add_filter(:super_erb, {}) - end - end - - it 'is outdated due to rule differences' do - expect(subject).to eql(Nanoc::Int::OutdatednessReasons::RulesModified) - end - end - - # … - end - - context 'with item rep' do - let(:obj) { item_rep } - - context 'action sequence differs' do - let(:new_action_sequence_for_item_rep) do - Nanoc::Int::ActionSequence.build(item_rep) do |b| - b.add_filter(:super_erb, {}) - end - end - - it 'is outdated due to rule differences' do - expect(subject).to eql(Nanoc::Int::OutdatednessReasons::RulesModified) - end - end - - # … - end - - context 'with layout' do - # … - end - - context 'with item collection' do - let(:obj) { items } - - context 'no new items' do - it { is_expected.to be_nil } - end - - context 'new items' do - before do - dependency_store.store - - new_item = Nanoc::Int::Item.new('stuff', {}, '/newblahz.md') - dependency_store.items = Nanoc::Int::ItemCollection.new(config, [item, new_item]) - - dependency_store.load - end - - it { is_expected.to be_a(Nanoc::Int::OutdatednessReasons::ItemCollectionExtended) } - - it 'includes proper raw_content props' do - expect(subject.objects.map(&:identifier).map(&:to_s)).to eq(['/newblahz.md']) - end - end - end - - context 'with layout collection' do - let(:obj) { layouts } - - context 'no new layouts' do - it { is_expected.to be_nil } - end - - context 'new layouts' do - before do - dependency_store.store - - new_layout = Nanoc::Int::Layout.new('stuff', {}, '/newblahz.md') - dependency_store.layouts = Nanoc::Int::LayoutCollection.new(config, layouts.to_a + [new_layout]) - - dependency_store.load - end - - it { is_expected.to be_a(Nanoc::Int::OutdatednessReasons::LayoutCollectionExtended) } - - it 'includes proper raw_content props' do - expect(subject.objects.map(&:identifier).map(&:to_s)).to eq(['/newblahz.md']) - end - end - end - end - - describe '#outdated_due_to_dependencies?' do - subject { outdatedness_checker.send(:outdated_due_to_dependencies?, item) } - - let(:checksum_store) { Nanoc::Int::ChecksumStore.new(config: config, objects: items.to_a + layouts.to_a) } - - let(:other_item) { Nanoc::Int::Item.new('other stuff', {}, '/other.md') } - let(:other_item_rep) { Nanoc::Int::ItemRep.new(other_item, :default) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - let(:items) { Nanoc::Int::ItemCollection.new(config, [item, other_item]) } - - let(:old_action_sequence_for_other_item_rep) do - Nanoc::Int::ActionSequence.build(other_item_rep) do |b| - b.add_filter(:erb, {}) - end - end - - let(:new_action_sequence_for_other_item_rep) { old_action_sequence_for_other_item_rep } - - let(:action_sequences) do - { - item_rep => new_action_sequence_for_item_rep, - other_item_rep => new_action_sequence_for_other_item_rep, - } - end - - before do - reps << other_item_rep - action_sequence_store[other_item_rep] = old_action_sequence_for_other_item_rep.serialize - checksum_store.add(item) - checksum_store.add(other_item) - checksum_store.add(config) - - allow(site).to receive(:code_snippets).and_return([]) - allow(site).to receive(:config).and_return(config) - end - - context 'transitive dependency' do - let(:distant_item) { Nanoc::Int::Item.new('distant stuff', {}, '/distant.md') } - let(:distant_item_rep) { Nanoc::Int::ItemRep.new(distant_item, :default) } - - let(:items) do - Nanoc::Int::ItemCollection.new(config, [item, other_item, distant_item]) - end - - let(:action_sequences) do - { - item_rep => new_action_sequence_for_item_rep, - other_item_rep => new_action_sequence_for_other_item_rep, - distant_item_rep => new_action_sequence_for_other_item_rep, - } - end - - before do - reps << distant_item_rep - checksum_store.add(distant_item) - action_sequence_store[distant_item_rep] = old_action_sequence_for_other_item_rep.serialize - end - - context 'on attribute + attribute' do - before do - dependency_store.record_dependency(item, other_item, attributes: true) - dependency_store.record_dependency(other_item, distant_item, attributes: true) - end - - context 'distant attribute changed' do - before { distant_item.attributes[:title] = 'omg new title' } - - it 'has correct outdatedness of item' do - expect(outdatedness_checker.send(:outdated_due_to_dependencies?, item)).not_to be - end - - it 'has correct outdatedness of other item' do - expect(outdatedness_checker.send(:outdated_due_to_dependencies?, other_item)).to be - end - end - - context 'distant raw content changed' do - before { distant_item.content = Nanoc::Int::TextualContent.new('omg new content') } - - it 'has correct outdatedness of item' do - expect(outdatedness_checker.send(:outdated_due_to_dependencies?, item)).not_to be - end - - it 'has correct outdatedness of other item' do - expect(outdatedness_checker.send(:outdated_due_to_dependencies?, other_item)).not_to be - end - end - end - - context 'on compiled content + attribute' do - before do - dependency_store.record_dependency(item, other_item, compiled_content: true) - dependency_store.record_dependency(other_item, distant_item, attributes: true) - end - - context 'distant attribute changed' do - before { distant_item.attributes[:title] = 'omg new title' } - - it 'has correct outdatedness of item' do - expect(outdatedness_checker.send(:outdated_due_to_dependencies?, item)).to be - end - - it 'has correct outdatedness of other item' do - expect(outdatedness_checker.send(:outdated_due_to_dependencies?, other_item)).to be - end - end - - context 'distant raw content changed' do - before { distant_item.content = Nanoc::Int::TextualContent.new('omg new content') } - - it 'has correct outdatedness of item' do - expect(outdatedness_checker.send(:outdated_due_to_dependencies?, item)).not_to be - end - - it 'has correct outdatedness of other item' do - expect(outdatedness_checker.send(:outdated_due_to_dependencies?, other_item)).not_to be - end - end - end - end - - context 'only generic attribute dependency' do - before do - dependency_store.record_dependency(item, other_item, attributes: true) - end - - context 'attribute changed' do - before { other_item.attributes[:title] = 'omg new title' } - it { is_expected.to be } - end - - context 'raw content changed' do - before { other_item.content = Nanoc::Int::TextualContent.new('omg new content') } - it { is_expected.not_to be } - end - - context 'attribute + raw content changed' do - before { other_item.attributes[:title] = 'omg new title' } - before { other_item.content = Nanoc::Int::TextualContent.new('omg new content') } - it { is_expected.to be } - end - - context 'path changed' do - let(:new_action_sequence_for_other_item_rep) do - Nanoc::Int::ActionSequence.build(other_item_rep) do |b| - b.add_filter(:erb, {}) - b.add_snapshot(:donkey, '/giraffe.txt') - end - end - - it { is_expected.not_to be } - end - end - - context 'only specific attribute dependency' do - before do - dependency_store.record_dependency(item, other_item, attributes: [:title]) - end - - context 'attribute changed' do - before { other_item.attributes[:title] = 'omg new title' } - it { is_expected.to be } - end - - context 'other attribute changed' do - before { other_item.attributes[:subtitle] = 'tagline here' } - it { is_expected.not_to be } - end - - context 'raw content changed' do - before { other_item.content = Nanoc::Int::TextualContent.new('omg new content') } - it { is_expected.not_to be } - end - - context 'attribute + raw content changed' do - before { other_item.attributes[:title] = 'omg new title' } - before { other_item.content = Nanoc::Int::TextualContent.new('omg new content') } - it { is_expected.to be } - end - - context 'other attribute + raw content changed' do - before { other_item.attributes[:subtitle] = 'tagline here' } - before { other_item.content = Nanoc::Int::TextualContent.new('omg new content') } - it { is_expected.not_to be } - end - - context 'path changed' do - let(:new_action_sequence_for_other_item_rep) do - Nanoc::Int::ActionSequence.build(other_item_rep) do |b| - b.add_filter(:erb, {}) - b.add_snapshot(:donkey, '/giraffe.txt') - end - end - - it { is_expected.not_to be } - end - end - - context 'generic dependency on config' do - before do - dependency_store.record_dependency(item, config, attributes: true) - end - - context 'nothing changed' do - it { is_expected.not_to be } - end - - context 'attribute changed' do - before { config[:title] = 'omg new title' } - it { is_expected.to be } - end - - context 'other attribute changed' do - before { config[:subtitle] = 'tagline here' } - it { is_expected.to be } - end - end - - context 'specific dependency on config' do - before do - dependency_store.record_dependency(item, config, attributes: [:title]) - end - - context 'nothing changed' do - it { is_expected.not_to be } - end - - context 'attribute changed' do - before { config[:title] = 'omg new title' } - it { is_expected.to be } - end - - context 'other attribute changed' do - before { config[:subtitle] = 'tagline here' } - it { is_expected.not_to be } - end - end - - context 'only raw content dependency' do - before do - dependency_store.record_dependency(item, other_item, raw_content: true) - end - - context 'attribute changed' do - before { other_item.attributes[:title] = 'omg new title' } - it { is_expected.not_to be } - end - - context 'raw content changed' do - before { other_item.content = Nanoc::Int::TextualContent.new('omg new content') } - it { is_expected.to be } - end - - context 'attribute + raw content changed' do - before { other_item.attributes[:title] = 'omg new title' } - before { other_item.content = Nanoc::Int::TextualContent.new('omg new content') } - it { is_expected.to be } - end - - context 'path changed' do - let(:new_action_sequence_for_other_item_rep) do - Nanoc::Int::ActionSequence.build(other_item_rep) do |b| - b.add_filter(:erb, {}) - b.add_snapshot(:donkey, '/giraffe.txt') - end - end - - it { is_expected.not_to be } - end - end - - context 'only path dependency' do - before do - dependency_store.record_dependency(item, other_item, raw_content: true) - end - - context 'attribute changed' do - before { other_item.attributes[:title] = 'omg new title' } - it { is_expected.not_to be } - end - - context 'raw content changed' do - before { other_item.content = Nanoc::Int::TextualContent.new('omg new content') } - it { is_expected.to be } - end - - context 'path changed' do - let(:new_action_sequence_for_other_item_rep) do - Nanoc::Int::ActionSequence.build(other_item_rep) do |b| - b.add_filter(:erb, {}) - b.add_snapshot(:donkey, '/giraffe.txt') - end - end - - it { is_expected.not_to be } - end - end - - context 'attribute + raw content dependency' do - before do - dependency_store.record_dependency(item, other_item, attributes: true, raw_content: true) - end - - context 'attribute changed' do - before { other_item.attributes[:title] = 'omg new title' } - it { is_expected.to be } - end - - context 'raw content changed' do - before { other_item.content = Nanoc::Int::TextualContent.new('omg new content') } - it { is_expected.to be } - end - - context 'attribute + raw content changed' do - before { other_item.attributes[:title] = 'omg new title' } - before { other_item.content = Nanoc::Int::TextualContent.new('omg new content') } - it { is_expected.to be } - end - - context 'rules changed' do - let(:new_action_sequence_for_other_item_rep) do - Nanoc::Int::ActionSequence.build(other_item_rep) do |b| - b.add_filter(:erb, {}) - b.add_filter(:donkey, {}) - end - end - - it { is_expected.not_to be } - end - end - - context 'attribute + other dependency' do - before do - dependency_store.record_dependency(item, other_item, attributes: true, path: true) - end - - context 'attribute changed' do - before { other_item.attributes[:title] = 'omg new title' } - it { is_expected.to be } - end - - context 'raw content changed' do - before { other_item.content = Nanoc::Int::TextualContent.new('omg new content') } - it { is_expected.not_to be } - end - end - - context 'other dependency' do - before do - dependency_store.record_dependency(item, other_item, path: true) - end - - context 'attribute changed' do - before { other_item.attributes[:title] = 'omg new title' } - it { is_expected.not_to be } - end - - context 'raw content changed' do - before { other_item.content = Nanoc::Int::TextualContent.new('omg new content') } - it { is_expected.not_to be } - end - end - - context 'only item collection dependency' do - context 'dependency on any new item' do - before do - dependency_tracker = Nanoc::Int::DependencyTracker.new(dependency_store) - dependency_tracker.enter(item) - dependency_tracker.bounce(items, raw_content: true) - dependency_store.store - end - - context 'nothing changed' do - it { is_expected.not_to be } - end - - context 'item added' do - before do - new_item = Nanoc::Int::Item.new('stuff', {}, '/newblahz.md') - dependency_store.items = Nanoc::Int::ItemCollection.new(config, items.to_a + [new_item]) - dependency_store.load - end - - it { is_expected.to be } - end - - context 'item removed' do - before do - dependency_store.items = Nanoc::Int::ItemCollection.new(config, []) - dependency_store.load - end - - it { is_expected.not_to be } - end - end - - context 'dependency on specific new items (string)' do - before do - dependency_tracker = Nanoc::Int::DependencyTracker.new(dependency_store) - dependency_tracker.enter(item) - dependency_tracker.bounce(items, raw_content: ['/new*']) - dependency_store.store - end - - context 'nothing changed' do - it { is_expected.not_to be } - end - - context 'matching item added' do - before do - new_item = Nanoc::Int::Item.new('stuff', {}, '/newblahz.md') - dependency_store.items = Nanoc::Int::ItemCollection.new(config, items.to_a + [new_item]) - dependency_store.load - end - - it { is_expected.to be } - end - - context 'non-matching item added' do - before do - new_item = Nanoc::Int::Item.new('stuff', {}, '/nublahz.md') - dependency_store.items = Nanoc::Int::ItemCollection.new(config, items.to_a + [new_item]) - dependency_store.load - end - - it { is_expected.not_to be } - end - - context 'item removed' do - before do - dependency_store.items = Nanoc::Int::ItemCollection.new(config, []) - dependency_store.load - end - - it { is_expected.not_to be } - end - end - - context 'dependency on specific new items (regex)' do - before do - dependency_tracker = Nanoc::Int::DependencyTracker.new(dependency_store) - dependency_tracker.enter(item) - dependency_tracker.bounce(items, raw_content: [%r{^/new.*}]) - dependency_store.store - end - - context 'nothing changed' do - it { is_expected.not_to be } - end - - context 'matching item added' do - before do - new_item = Nanoc::Int::Item.new('stuff', {}, '/newblahz.md') - dependency_store.items = Nanoc::Int::ItemCollection.new(config, items.to_a + [new_item]) - dependency_store.load - end - - it { is_expected.to be } - end - - context 'non-matching item added' do - before do - new_item = Nanoc::Int::Item.new('stuff', {}, '/nublahz.md') - dependency_store.items = Nanoc::Int::ItemCollection.new(config, items.to_a + [new_item]) - dependency_store.load - end - - it { is_expected.not_to be } - end - - context 'item removed' do - before do - dependency_store.items = Nanoc::Int::ItemCollection.new(config, []) - dependency_store.load - end - - it { is_expected.not_to be } - end - end - end - - context 'only layout collection dependency' do - context 'dependency on any new layout' do - before do - dependency_tracker = Nanoc::Int::DependencyTracker.new(dependency_store) - dependency_tracker.enter(item) - dependency_tracker.bounce(layouts, raw_content: true) - dependency_store.store - end - - context 'nothing changed' do - it { is_expected.not_to be } - end - - context 'layout added' do - before do - new_layout = Nanoc::Int::Layout.new('stuff', {}, '/newblahz.md') - dependency_store.layouts = Nanoc::Int::LayoutCollection.new(config, layouts.to_a + [new_layout]) - dependency_store.load - end - - it { is_expected.to be } - end - - context 'layout removed' do - before do - dependency_store.layouts = Nanoc::Int::LayoutCollection.new(config, []) - dependency_store.load - end - - it { is_expected.not_to be } - end - end - - context 'dependency on specific new layouts (string)' do - before do - dependency_tracker = Nanoc::Int::DependencyTracker.new(dependency_store) - dependency_tracker.enter(item) - dependency_tracker.bounce(layouts, raw_content: ['/new*']) - dependency_store.store - end - - context 'nothing changed' do - it { is_expected.not_to be } - end - - context 'matching layout added' do - before do - new_layout = Nanoc::Int::Layout.new('stuff', {}, '/newblahz.md') - dependency_store.layouts = Nanoc::Int::LayoutCollection.new(config, layouts.to_a + [new_layout]) - dependency_store.load - end - - it { is_expected.to be } - end - - context 'non-matching layout added' do - before do - new_layout = Nanoc::Int::Layout.new('stuff', {}, '/nublahz.md') - dependency_store.layouts = Nanoc::Int::LayoutCollection.new(config, layouts.to_a + [new_layout]) - dependency_store.load - end - - it { is_expected.not_to be } - end - - context 'layout removed' do - before do - dependency_store.layouts = Nanoc::Int::LayoutCollection.new(config, []) - dependency_store.load - end - - it { is_expected.not_to be } - end - end - - context 'dependency on specific new layouts (regex)' do - before do - dependency_tracker = Nanoc::Int::DependencyTracker.new(dependency_store) - dependency_tracker.enter(item) - dependency_tracker.bounce(layouts, raw_content: [%r{^/new.*}]) - dependency_store.store - end - - context 'nothing changed' do - it { is_expected.not_to be } - end - - context 'matching layout added' do - before do - new_layout = Nanoc::Int::Layout.new('stuff', {}, '/newblahz.md') - dependency_store.layouts = Nanoc::Int::LayoutCollection.new(config, layouts.to_a + [new_layout]) - dependency_store.load - end - - it { is_expected.to be } - end - - context 'non-matching layout added' do - before do - new_layout = Nanoc::Int::Layout.new('stuff', {}, '/nublahz.md') - dependency_store.layouts = Nanoc::Int::LayoutCollection.new(config, layouts.to_a + [new_layout]) - dependency_store.load - end - - it { is_expected.not_to be } - end - - context 'layout removed' do - before do - dependency_store.layouts = Nanoc::Int::LayoutCollection.new(config, []) - dependency_store.load - end - - it { is_expected.not_to be } - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/outdatedness_rules_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/outdatedness_rules_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/outdatedness_rules_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/outdatedness_rules_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,629 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::OutdatednessRules do - describe '#apply' do - subject { rule_class.instance.apply(obj, outdatedness_checker) } - - let(:obj) { item_rep } - - let(:outdatedness_checker) do - Nanoc::Int::OutdatednessChecker.new( - site: site, - checksum_store: checksum_store, - checksums: checksums, - dependency_store: dependency_store, - action_sequence_store: action_sequence_store, - action_sequences: action_sequences, - reps: reps, - ) - end - - let(:item_rep) { Nanoc::Int::ItemRep.new(item, :default) } - let(:item) { Nanoc::Int::Item.new('stuff', {}, '/foo.md') } - let(:layout) { Nanoc::Int::Layout.new('layoutz', {}, '/page.erb') } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - let(:code_snippets) { [] } - let(:objects) { [config] + code_snippets + [item] } - - let(:site) do - Nanoc::Int::Site.new( - config: config, - code_snippets: code_snippets, - data_source: Nanoc::Int::InMemDataSource.new(items, layouts), - ) - end - - let(:action_sequences) { {} } - let(:reps) { Nanoc::Int::ItemRepRepo.new } - let(:dependency_store) { Nanoc::Int::DependencyStore.new(items, layouts, config) } - let(:action_sequence_store) { Nanoc::Int::ActionSequenceStore.new(config: config) } - let(:checksum_store) { Nanoc::Int::ChecksumStore.new(config: config, objects: objects) } - - let(:checksums) do - Nanoc::Int::Compiler::Stages::CalculateChecksums.new( - items: items, - layouts: layouts, - code_snippets: code_snippets, - config: config, - ).run - end - - let(:items) { Nanoc::Int::ItemCollection.new(config, [item]) } - let(:layouts) { Nanoc::Int::LayoutCollection.new(config, [layout]) } - - before do - allow(site).to receive(:code_snippets).and_return(code_snippets) - allow(site).to receive(:config).and_return(config) - end - - describe 'CodeSnippetsModified' do - let(:rule_class) { Nanoc::Int::OutdatednessRules::CodeSnippetsModified } - - context 'no snippets' do - let(:code_snippets) { [] } - it { is_expected.not_to be } - end - - context 'only non-outdated snippets' do - let(:code_snippet) { Nanoc::Int::CodeSnippet.new('asdf', 'lib/foo.md') } - let(:code_snippets) { [code_snippet] } - - before { checksum_store.add(code_snippet) } - - it { is_expected.not_to be } - end - - context 'only outdated snippets' do - let(:code_snippet) { Nanoc::Int::CodeSnippet.new('asdf', 'lib/foo.md') } - let(:code_snippet_old) { Nanoc::Int::CodeSnippet.new('aaaaaaaa', 'lib/foo.md') } - let(:code_snippets) { [code_snippet] } - - before { checksum_store.add(code_snippet_old) } - - it { is_expected.to be } - end - end - - describe 'NotWritten' do - let(:rule_class) { Nanoc::Int::OutdatednessRules::NotWritten } - - context 'no path' do - before { item_rep.paths = {} } - - it { is_expected.not_to be } - end - - context 'path for last snapshot' do - let(:path) { Dir.getwd + '/foo.txt' } - - before { item_rep.raw_paths = { last: [path] } } - - context 'not written' do - it { is_expected.to be } - end - - context 'written' do - before { File.write(path, 'hello') } - it { is_expected.not_to be } - end - end - - context 'path for other snapshot' do - let(:path) { Dir.getwd + '/foo.txt' } - - before { item_rep.raw_paths = { donkey: [path] } } - - context 'not written' do - it { is_expected.to be } - end - - context 'written' do - before { File.write(path, 'hello') } - it { is_expected.not_to be } - end - end - end - - describe 'ContentModified' do - let(:rule_class) { Nanoc::Int::OutdatednessRules::ContentModified } - - context 'item' do - let(:obj) { item } - - before { reps << item_rep } - - context 'no checksum available' do - it { is_expected.to be } - end - - context 'checksum available and same' do - before { checksum_store.add(item) } - it { is_expected.not_to be } - end - - context 'checksum available, but content different' do - let(:old_item) { Nanoc::Int::Item.new('other stuff!!!!', {}, '/foo.md') } - before { checksum_store.add(old_item) } - it { is_expected.to be } - end - - context 'checksum available, but attributes different' do - let(:old_item) { Nanoc::Int::Item.new('stuff', { greeting: 'hi' }, '/foo.md') } - before { checksum_store.add(old_item) } - it { is_expected.not_to be } - end - end - - context 'item rep' do - let(:obj) { item_rep } - - context 'no checksum available' do - it { is_expected.to be } - end - - context 'checksum available and same' do - before { checksum_store.add(item) } - it { is_expected.not_to be } - end - - context 'checksum available, but content different' do - let(:old_item) { Nanoc::Int::Item.new('other stuff!!!!', {}, '/foo.md') } - before { checksum_store.add(old_item) } - it { is_expected.to be } - end - - context 'checksum available, but attributes different' do - let(:old_item) { Nanoc::Int::Item.new('stuff', { greeting: 'hi' }, '/foo.md') } - before { checksum_store.add(old_item) } - it { is_expected.not_to be } - end - end - end - - describe 'AttributesModified' do - let(:rule_class) { Nanoc::Int::OutdatednessRules::AttributesModified } - - context 'item' do - let(:obj) { item } - - before { reps << item_rep } - - context 'no checksum available' do - it { is_expected.to be } - end - - context 'checksum available and same' do - before { checksum_store.add(item) } - it { is_expected.not_to be } - end - - context 'checksum available, but content different' do - let(:old_item) { Nanoc::Int::Item.new('other stuff!!!!', {}, '/foo.md') } - before { checksum_store.add(old_item) } - it { is_expected.not_to be } - end - - context 'checksum available, but attributes different' do - let(:old_item) { Nanoc::Int::Item.new('stuff', { greeting: 'hi' }, '/foo.md') } - - before { checksum_store.add(old_item) } - - it { is_expected.to be } - - it 'has the one changed attribute' do - expect(subject.attributes).to contain_exactly(:greeting) - end - end - - context 'attribute kept identical' do - let(:item) { Nanoc::Int::Item.new('stuff', { greeting: 'hi' }, '/foo.md') } - let(:old_item) { Nanoc::Int::Item.new('stuff', { greeting: 'hi' }, '/foo.md') } - - before { checksum_store.add(old_item) } - - it 'has the one changed attribute' do - expect(subject).to be_nil - end - end - - context 'attribute changed' do - let(:item) { Nanoc::Int::Item.new('stuff', { greeting: 'hi' }, '/foo.md') } - let(:old_item) { Nanoc::Int::Item.new('stuff', { greeting: 'ho' }, '/foo.md') } - - before { checksum_store.add(old_item) } - - it 'has the one changed attribute' do - expect(subject.attributes).to contain_exactly(:greeting) - end - end - - context 'attribute deleted' do - let(:item) { Nanoc::Int::Item.new('stuff', { greeting: 'hi' }, '/foo.md') } - let(:old_item) { Nanoc::Int::Item.new('stuff', {}, '/foo.md') } - - before { checksum_store.add(old_item) } - - it 'has the one changed attribute' do - expect(subject.attributes).to contain_exactly(:greeting) - end - end - - context 'attribute added' do - let(:item) { Nanoc::Int::Item.new('stuff', {}, '/foo.md') } - let(:old_item) { Nanoc::Int::Item.new('stuff', { greeting: 'hi' }, '/foo.md') } - - before { checksum_store.add(old_item) } - - it 'has the one changed attribute' do - expect(subject.attributes).to contain_exactly(:greeting) - end - end - end - - context 'item rep' do - let(:obj) { item_rep } - - context 'no checksum available' do - it { is_expected.to be } - end - - context 'checksum available and same' do - before { checksum_store.add(item) } - it { is_expected.not_to be } - end - - context 'checksum available, but content different' do - let(:old_item) { Nanoc::Int::Item.new('other stuff!!!!', {}, '/foo.md') } - before { checksum_store.add(old_item) } - it { is_expected.not_to be } - end - - context 'checksum available, but attributes different' do - let(:old_item) { Nanoc::Int::Item.new('stuff', { greeting: 'hi' }, '/foo.md') } - - before { checksum_store.add(old_item) } - - it { is_expected.to be } - - it 'has the one changed attribute' do - expect(subject.attributes).to contain_exactly(:greeting) - end - end - end - - context 'config' do - # TODO - end - end - - describe 'RulesModified' do - let(:rule_class) { Nanoc::Int::OutdatednessRules::RulesModified } - - let(:old_mem) do - Nanoc::Int::ActionSequence.build(item_rep) do |b| - b.add_filter(:erb, {}) - end - end - - let(:action_sequences) { { item_rep => new_mem } } - - before do - action_sequence_store[item_rep] = old_mem.serialize - end - - context 'memory is the same' do - let(:new_mem) { old_mem } - it { is_expected.not_to be } - end - - context 'memory is different' do - let(:new_mem) do - Nanoc::Int::ActionSequence.build(item_rep) do |b| - b.add_filter(:erb, {}) - b.add_filter(:donkey, {}) - end - end - - it { is_expected.to be } - end - - context 'memory is the same, but refers to a layout' do - let(:old_mem) do - Nanoc::Int::ActionSequence.build(item_rep) do |b| - b.add_layout('/page.*', {}) - end - end - - let(:new_mem) { old_mem } - - let(:action_sequences) do - { - item_rep => new_mem, - layout => new_layout_mem, - } - end - - before do - action_sequence_store[layout] = old_layout_mem.serialize - end - - context 'everything is the same' do - let(:new_layout_mem) do - Nanoc::Int::ActionSequence.build(layout) do |b| - b.add_filter(:erb, {}) - end - end - - let(:old_layout_mem) { new_layout_mem } - - it { is_expected.not_to be } - end - - context 'referenced layout does not exist' do - let(:new_layout_mem) do - Nanoc::Int::ActionSequence.build(layout) do |b| - b.add_filter(:erb, {}) - end - end - - let(:old_layout_mem) do - Nanoc::Int::ActionSequence.build(layout) do |b| - b.add_filter(:haml, {}) - end - end - - let(:old_mem) do - Nanoc::Int::ActionSequence.build(item_rep) do |b| - b.add_layout('/moo.*', {}) - end - end - - # Something changed about the layout; the item-on-layout dependency - # will ensure this item is marked as outdated. - it { is_expected.not_to be } - end - - context 'filter name is different' do - let(:new_layout_mem) do - Nanoc::Int::ActionSequence.build(layout) do |b| - b.add_filter(:erb, {}) - end - end - - let(:old_layout_mem) do - Nanoc::Int::ActionSequence.build(layout) do |b| - b.add_filter(:haml, {}) - end - end - - it { is_expected.to be } - end - - context 'params are different' do - let(:new_layout_mem) do - Nanoc::Int::ActionSequence.build(layout) do |b| - b.add_filter(:erb, {}) - end - end - - let(:old_layout_mem) do - Nanoc::Int::ActionSequence.build(layout) do |b| - b.add_filter(:erb, foo: 123) - end - end - - it { is_expected.to be } - end - end - end - - describe 'ContentModified, AttributesModified' do - subject do - [ - Nanoc::Int::OutdatednessRules::ContentModified, - Nanoc::Int::OutdatednessRules::AttributesModified, - ].map { |c| !!c.instance.apply(new_obj, outdatedness_checker) } # rubocop:disable Style/DoubleNegation - end - - let(:stored_obj) { raise 'override me' } - let(:new_obj) { raise 'override me' } - - let(:items) { Nanoc::Int::ItemCollection.new(config, [new_obj]) } - - shared_examples 'a document' do - let(:stored_obj) { klass.new('a', {}, '/foo.md') } - let(:new_obj) { stored_obj } - - context 'no checksum data' do - context 'not stored' do - it { is_expected.to eql([true, true]) } - end - - context 'stored' do - before { checksum_store.add(stored_obj) } - - context 'but content changed afterwards' do - let(:new_obj) { klass.new('aaaaaaaa', {}, '/foo.md') } - it { is_expected.to eql([true, false]) } - end - - context 'but attributes changed afterwards' do - let(:new_obj) { klass.new('a', { animal: 'donkey' }, '/foo.md') } - it { is_expected.to eql([false, true]) } - end - - context 'and unchanged' do - it { is_expected.to eql([false, false]) } - end - end - end - - context 'checksum_data' do - let(:stored_obj) { klass.new('a', {}, '/foo.md', checksum_data: 'cs-data') } - let(:new_obj) { stored_obj } - - context 'not stored' do - it { is_expected.to eql([true, true]) } - end - - context 'stored' do - before { checksum_store.add(stored_obj) } - - context 'but checksum data afterwards' do - # NOTE: ignored for attributes! - - let(:new_obj) { klass.new('a', {}, '/foo.md', checksum_data: 'cs-data-new') } - it { is_expected.to eql([true, false]) } - end - - context 'and unchanged' do - it { is_expected.to eql([false, false]) } - end - end - end - - context 'content_checksum_data' do - let(:stored_obj) { klass.new('a', {}, '/foo.md', content_checksum_data: 'cs-data') } - let(:new_obj) { stored_obj } - - context 'not stored' do - it { is_expected.to eql([true, true]) } - end - - context 'stored' do - before { checksum_store.add(stored_obj) } - - context 'but checksum data afterwards' do - let(:new_obj) { klass.new('a', {}, '/foo.md', content_checksum_data: 'cs-data-new') } - it { is_expected.to eql([true, false]) } - end - - context 'and unchanged' do - it { is_expected.to eql([false, false]) } - end - end - end - - context 'attributes_checksum_data' do - # NOTE: attributes_checksum_data is ignored! - - let(:stored_obj) { klass.new('a', {}, '/foo.md', attributes_checksum_data: 'cs-data') } - let(:new_obj) { stored_obj } - - context 'not stored' do - it { is_expected.to eql([true, true]) } - end - - context 'stored' do - before { checksum_store.add(stored_obj) } - - context 'but checksum data afterwards' do - let(:new_obj) { klass.new('a', {}, '/foo.md', attributes_checksum_data: 'cs-data-new') } - it { is_expected.to eql([false, false]) } - end - - context 'and unchanged' do - it { is_expected.to eql([false, false]) } - end - end - end - end - - context 'item' do - let(:klass) { Nanoc::Int::Item } - it_behaves_like 'a document' - end - - context 'layout' do - let(:klass) { Nanoc::Int::Layout } - it_behaves_like 'a document' - end - - # … - end - - describe 'UsesAlwaysOutdatedFilter' do - let(:rule_class) { Nanoc::Int::OutdatednessRules::UsesAlwaysOutdatedFilter } - - let(:action_sequences) { { item_rep => mem } } - - context 'unknown filter' do - let(:mem) do - Nanoc::Int::ActionSequence.build(item_rep) do |b| - b.add_snapshot(:donkey, '/foo.md') - b.add_filter(:asdf, {}) - end - end - - it { is_expected.not_to be } - end - - context 'known filter, not always outdated' do - let(:mem) do - Nanoc::Int::ActionSequence.build(item_rep) do |b| - b.add_snapshot(:donkey, '/foo.md') - b.add_filter(:erb, {}) - end - end - - it { is_expected.not_to be } - end - - context 'known filter, always outdated' do - let(:mem) do - Nanoc::Int::ActionSequence.build(item_rep) do |b| - b.add_snapshot(:donkey, '/foo.md') - b.add_filter(:xsl, {}) - end - end - - it { is_expected.to be } - end - end - - describe 'ItemCollectionExtended' do - let(:rule_class) { Nanoc::Int::OutdatednessRules::ItemCollectionExtended } - - let(:obj) { items } - - context 'no new item added' do - before do - expect(dependency_store).to receive(:new_items).and_return([]) - end - - it { is_expected.not_to be } - end - - context 'new item added' do - before do - expect(dependency_store).to receive(:new_items).and_return([item]) - end - - it { is_expected.to be } - end - end - - describe 'LayoutCollectionExtended' do - let(:rule_class) { Nanoc::Int::OutdatednessRules::LayoutCollectionExtended } - - let(:obj) { layouts } - - context 'no new layout added' do - before do - expect(dependency_store).to receive(:new_layouts).and_return([]) - end - - it { is_expected.not_to be } - end - - context 'new layout added' do - before do - expect(dependency_store).to receive(:new_layouts).and_return([layout]) - end - - it { is_expected.to be } - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/pruner_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/pruner_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/pruner_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/pruner_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,431 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Pruner, stdio: true do - subject(:pruner) { described_class.new(config, reps, dry_run: dry_run, exclude: exclude) } - - let(:config) { Nanoc::Int::Configuration.new(hash: {}, dir: Dir.getwd).with_defaults } - let(:dry_run) { false } - let(:exclude) { [] } - - let(:reps) do - Nanoc::Int::ItemRepRepo.new.tap do |reps| - reps << Nanoc::Int::ItemRep.new(item, :default).tap do |rep| - rep.raw_paths = { last: [Dir.getwd + '/output/asdf.html'] } - end - - reps << Nanoc::Int::ItemRep.new(item, :text).tap do |rep| - rep.raw_paths = { last: [Dir.getwd + '/output/asdf.txt'] } - end - end - end - - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/a.md') } - - it 'is accessible through Nanoc::Extra::Pruner' do - expect(Nanoc::Extra::Pruner).to equal(Nanoc::Pruner) - end - - describe '#filename_excluded?' do - subject { pruner.filename_excluded?(filename) } - - let(:filename) { Dir.getwd + '/output/foo/bar.html' } - - context 'nothing excluded' do - it { is_expected.to be(false) } - end - - context 'matching identifier component excluded' do - let(:exclude) { ['foo'] } - it { is_expected.to be(true) } - end - - context 'non-matching identifier component excluded' do - let(:exclude) { ['xyz'] } - it { is_expected.to be(false) } - end - - context 'output dir excluded' do - let(:exclude) { ['output'] } - it { is_expected.to be(false) } - end - end - - describe '#run' do - subject { pruner.run } - - describe 'it removes stray files' do - let(:present_files) do - [ - 'output/foo.html', - 'output/foo.txt', - 'output/bar.html', - 'output/foo/bar.html', - 'output/foo/bar.txt', - 'output/output/asdf.txt', - ] - end - - let(:reps) do - Nanoc::Int::ItemRepRepo.new.tap do |reps| - reps << Nanoc::Int::ItemRep.new(item, :a).tap do |rep| - rep.raw_paths = { last: [Dir.getwd + '/output/foo.html'] } - end - - reps << Nanoc::Int::ItemRep.new(item, :b).tap do |rep| - rep.raw_paths = { last: [Dir.getwd + '/output/bar.html'] } - end - - reps << Nanoc::Int::ItemRep.new(item, :c).tap do |rep| - rep.raw_paths = { last: [Dir.getwd + '/output/foo/bar.html'] } - end - end - end - - before do - present_files.each do |fn| - FileUtils.mkdir_p(File.dirname(fn)) - File.write(fn, 'asdf') - end - end - - context 'nothing excluded' do - it 'removes /foo.txt' do - expect { subject } - .to change { File.file?('output/foo.txt') } - .from(true) - .to(false) - end - - it 'removes /foo/bar.txt' do - expect { subject } - .to change { File.file?('output/foo/bar.txt') } - .from(true) - .to(false) - end - - it 'removes /output/asdf.txt' do - expect { subject } - .to change { File.file?('output/output/asdf.txt') } - .from(true) - .to(false) - end - end - - context 'foo excluded' do - let(:exclude) { ['foo'] } - - it 'removes /foo.txt' do - expect { subject } - .to change { File.file?('output/foo.txt') } - .from(true) - .to(false) - end - - it 'keeps /foo/bar.txt' do - expect { subject } - .not_to change { File.file?('output/foo/bar.txt') } - .from(true) - end - - it 'removes /output/asdf.txt' do - expect { subject } - .to change { File.file?('output/output/asdf.txt') } - .from(true) - .to(false) - end - end - - context 'output excluded' do - let(:exclude) { ['output'] } - - it 'removes /foo.txt' do - expect { subject } - .to change { File.file?('output/foo.txt') } - .from(true) - .to(false) - end - - it 'removes /foo/bar.txt' do - expect { subject } - .to change { File.file?('output/foo/bar.txt') } - .from(true) - .to(false) - end - - it 'keeps /output/asdf.txt' do - expect { subject } - .not_to change { File.file?('output/output/asdf.txt') } - .from(true) - end - end - end - - describe 'it removes empty directories' do - let(:present_dirs) do - [ - 'output/.foo', - 'output/foo', - 'output/foo/bar', - 'output/bar', - 'output/output', - 'output/output/asdf', - ] - end - - before do - present_dirs.each do |fn| - FileUtils.mkdir_p(fn) - end - end - - context 'nothing excluded' do - it 'removes /.foo' do - expect { subject } - .to change { File.directory?('output/.foo') } - .from(true) - .to(false) - end - - it 'removes /foo' do - expect { subject } - .to change { File.directory?('output/foo') } - .from(true) - .to(false) - end - - it 'removes /foo/bar' do - expect { subject } - .to change { File.directory?('output/foo/bar') } - .from(true) - .to(false) - end - - it 'removes /bar' do - expect { subject } - .to change { File.directory?('output/bar') } - .from(true) - .to(false) - end - - it 'removes /output' do - expect { subject } - .to change { File.directory?('output/output') } - .from(true) - .to(false) - end - - it 'removes /output/asdf' do - expect { subject } - .to change { File.directory?('output/output/asdf') } - .from(true) - .to(false) - end - end - - context 'foo excluded' do - let(:exclude) { ['foo'] } - - it 'removes /.foo' do - expect { subject } - .to change { File.directory?('output/.foo') } - .from(true) - .to(false) - end - - it 'removes /bar' do - expect { subject } - .to change { File.directory?('output/bar') } - .from(true) - .to(false) - end - - it 'keeps /foo' do - expect { subject } - .not_to change { File.directory?('output/foo') } - .from(true) - end - - it 'keeps /foo/bar' do - expect { subject } - .not_to change { File.directory?('output/foo/bar') } - .from(true) - end - - it 'removes /output' do - expect { subject } - .to change { File.directory?('output/output') } - .from(true) - .to(false) - end - - it 'removes /output/asdf' do - expect { subject } - .to change { File.directory?('output/output/asdf') } - .from(true) - .to(false) - end - end - - context 'output excluded' do - let(:exclude) { ['output'] } - - it 'removes /.foo' do - expect { subject } - .to change { File.directory?('output/.foo') } - .from(true) - .to(false) - end - - it 'removes /bar' do - expect { subject } - .to change { File.directory?('output/bar') } - .from(true) - .to(false) - end - - it 'removes /foo' do - expect { subject } - .to change { File.directory?('output/foo') } - .from(true) - .to(false) - end - - it 'removes /foo/bar' do - expect { subject } - .to change { File.directory?('output/foo/bar') } - .from(true) - .to(false) - end - - it 'keeps /output' do - expect { subject } - .not_to change { File.directory?('output/output') } - .from(true) - end - - it 'keeps /output/asdf' do - expect { subject } - .not_to change { File.directory?('output/output/asdf') } - .from(true) - end - end - end - end - - describe '#pathname_components' do - subject { pruner.pathname_components(pathname) } - - context 'regular path' do - let(:pathname) { Pathname.new('/a/bb/ccc/dd/e') } - it { is_expected.to eql(%w[/ a bb ccc dd e]) } - end - end - - describe '#files_and_dirs_in' do - subject { pruner.files_and_dirs_in('output/') } - - before do - FileUtils.mkdir_p('output/projects') - FileUtils.mkdir_p('output/.git') - - File.write('output/asdf.html', '

text

') - File.write('output/.htaccess', 'secret stuff here') - File.write('output/projects/nanoc.html', '

Nanoc is v cool!!

') - File.write('output/.git/HEAD', 'some content here') - end - - context 'nothing excluded' do - let(:exclude) { [] } - - it 'returns all files' do - files = [ - 'output/asdf.html', - 'output/.htaccess', - 'output/projects/nanoc.html', - 'output/.git/HEAD', - ] - expect(subject[0]).to match_array(files) - end - - it 'returns all directories' do - dirs = [ - 'output/projects', - 'output/.git', - ] - expect(subject[1]).to match_array(dirs) - end - end - - context 'directory (.git) excluded' do - let(:exclude) { ['.git'] } - - it 'returns all files' do - files = [ - 'output/asdf.html', - 'output/.htaccess', - 'output/projects/nanoc.html', - ] - expect(subject[0]).to match_array(files) - end - - it 'returns all directories' do - dirs = [ - 'output/projects', - ] - expect(subject[1]).to match_array(dirs) - end - end - - context 'file (.htaccess) excluded' do - let(:exclude) { ['.htaccess'] } - - it 'returns all files' do - files = [ - 'output/asdf.html', - 'output/projects/nanoc.html', - 'output/.git/HEAD', - ] - expect(subject[0]).to match_array(files) - end - - it 'returns all directories' do - dirs = [ - 'output/projects', - 'output/.git', - ] - expect(subject[1]).to match_array(dirs) - end - end - - context 'output dir is a symlink' do - before do - FileUtils.mv('output', 'output-real') - File.symlink('output-real', 'output') - end - - before do - if Nanoc.on_windows? - skip 'Symlinks to output dirs are currently not supported on Windows.' - end - end - - it 'returns all files' do - files = [ - 'output/asdf.html', - 'output/.htaccess', - 'output/projects/nanoc.html', - 'output/.git/HEAD', - ] - expect(subject[0]).to match_array(files) - end - - it 'returns all directories' do - dirs = [ - 'output/projects', - 'output/.git', - ] - expect(subject[1]).to match_array(dirs) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/services/temp_filename_factory_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/services/temp_filename_factory_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/services/temp_filename_factory_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/services/temp_filename_factory_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::Int::TempFilenameFactory do - subject(:factory) { described_class.new } - - let(:prefix) { 'foo' } - - describe '#create' do - it 'creates unique paths' do - path_a = subject.create(prefix) - path_b = subject.create(prefix) - - expect(path_a).not_to eq(path_b) - end - - it 'returns absolute paths' do - path = subject.create(prefix) - - expect(path).to match(/\A(C:)?\//) - end - - it 'creates the containing directory' do - expect(Dir[subject.root_dir + '/**/*']).to be_empty - - path = subject.create(prefix) - - expect(File.directory?(File.dirname(path))).to be(true) - end - - it 'reuses the same path after cleanup' do - path_a = subject.create(prefix) - - subject.cleanup(prefix) - - path_b = subject.create(prefix) - expect(path_a).to eq(path_b) - end - - it 'does not create the file' do - path = subject.create(prefix) - expect(File.file?(path)).not_to be(true) - end - end - - describe '#cleanup' do - subject { factory.cleanup(prefix) } - - let!(:path) { factory.create(prefix) } - - before { File.write(path, 'hello') } - - def files - Dir[factory.root_dir + '/**/*'].select { |fn| File.file?(fn) } - end - - it 'removes generated files' do - expect { subject }.to change { files }.from([path]).to([]) - end - - context 'files with other prefixes exist' do - before do - factory.create('donkey') - end - - it 'does not delete root dir' do - expect(File.directory?(factory.root_dir)).to be(true) - expect { subject }.not_to change { File.directory?(factory.root_dir) } - end - end - - context 'no files with other prefixes exist' do - it 'deletes root dir' do - expect { subject }.to change { File.directory?(factory.root_dir) }.from(true).to(false) - end - end - end - - describe 'other instance' do - let(:other_instance) do - Nanoc::Int::TempFilenameFactory.new - end - - it 'creates unique paths across instances' do - path_a = subject.create(prefix) - path_b = other_instance.create(prefix) - expect(path_a).not_to eq(path_b) - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/basic_item_rep_collection_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/basic_item_rep_collection_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/basic_item_rep_collection_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/basic_item_rep_collection_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/item_rep_collection_view_examples' - -describe Nanoc::BasicItemRepCollectionView do - it_behaves_like 'an item rep collection view' - let(:expected_view_class) { Nanoc::BasicItemRepView } -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/basic_item_rep_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/basic_item_rep_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/basic_item_rep_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/basic_item_rep_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/item_rep_view_examples' - -describe Nanoc::BasicItemRepView do - let(:expected_item_view_class) { Nanoc::BasicItemView } - - it_behaves_like 'an item rep view' -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/compilation_item_rep_collection_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/compilation_item_rep_collection_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/compilation_item_rep_collection_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/compilation_item_rep_collection_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/item_rep_collection_view_examples' - -describe Nanoc::CompilationItemRepCollectionView do - it_behaves_like 'an item rep collection view' - let(:expected_view_class) { Nanoc::CompilationItemRepView } -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/compilation_item_rep_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/compilation_item_rep_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/compilation_item_rep_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/compilation_item_rep_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,149 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/item_rep_view_examples' - -describe Nanoc::CompilationItemRepView do - let(:expected_item_view_class) { Nanoc::CompilationItemView } - - it_behaves_like 'an item rep view' - - let(:view_context) do - Nanoc::ViewContextForCompilation.new( - reps: Nanoc::Int::ItemRepRepo.new, - items: Nanoc::Int::ItemCollection.new(config), - dependency_tracker: dependency_tracker, - compilation_context: compilation_context, - snapshot_repo: snapshot_repo, - ) - end - - let(:compilation_context) { double(:compilation_context) } - let(:snapshot_repo) { Nanoc::Int::SnapshotRepo.new } - - let(:dependency_tracker) { Nanoc::Int::DependencyTracker.new(dependency_store) } - let(:dependency_store) { Nanoc::Int::DependencyStore.new(empty_items, empty_layouts, config) } - let(:base_item) { Nanoc::Int::Item.new('base', {}, '/base.md') } - - let(:empty_items) { Nanoc::Int::ItemCollection.new(config) } - let(:empty_layouts) { Nanoc::Int::LayoutCollection.new(config) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - before do - dependency_tracker.enter(base_item) - end - - describe '#raw_path' do - subject { Fiber.new { view.raw_path }.resume } - - let(:view) { described_class.new(rep, view_context) } - - let(:rep) do - Nanoc::Int::ItemRep.new(item, :default).tap do |ir| - ir.raw_paths = { - last: [Dir.getwd + '/output/about/index.html'], - } - end - end - - let(:item) do - Nanoc::Int::Item.new('content', {}, '/asdf.md') - end - - context 'rep is not compiled' do - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.compiled_content?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.attributes?).to eq(false) - expect(dep.props.path?).to eq(false) - end - - it { should be_a(Nanoc::Int::Errors::UnmetDependency) } - end - - context 'rep is compiled' do - before { rep.compiled = true } - - context 'file does not exist' do - it 'raises' do - expect { subject }.to raise_error(Nanoc::Int::Errors::InternalInconsistency) - end - end - - context 'file exists' do - before do - FileUtils.mkdir_p('output/about') - File.write('output/about/index.html', 'hi!') - end - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.compiled_content?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.attributes?).to eq(false) - expect(dep.props.path?).to eq(false) - end - - it { should eq(Dir.getwd + '/output/about/index.html') } - end - end - end - - describe '#compiled_content' do - subject { view.compiled_content } - - let(:view) { described_class.new(rep, view_context) } - - let(:rep) do - Nanoc::Int::ItemRep.new(item, :default).tap do |ir| - ir.compiled = true - ir.snapshot_defs = [ - Nanoc::Int::SnapshotDef.new(:last, binary: false), - ] - end - end - - let(:item) do - Nanoc::Int::Item.new('content', {}, '/asdf.md') - end - - before do - snapshot_repo.set(rep, :last, Nanoc::Int::TextualContent.new('Hallo')) - end - - it 'creates a dependency' do - expect { subject } - .to change { dependency_store.objects_causing_outdatedness_of(base_item) } - .from([]) - .to([item]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.compiled_content?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.attributes?).to eq(false) - expect(dep.props.path?).to eq(false) - end - - it { should eq('Hallo') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/config_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/config_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/config_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/config_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,144 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::ConfigView do - let(:config) do - Nanoc::Int::Configuration.new(dir: Dir.getwd, hash: hash) - end - - let(:hash) { { amount: 9000, animal: 'donkey', foo: { bar: :baz } } } - - let(:view) { described_class.new(config, view_context) } - - let(:view_context) do - Nanoc::ViewContextForCompilation.new( - reps: Nanoc::Int::ItemRepRepo.new, - items: Nanoc::Int::ItemCollection.new(config), - dependency_tracker: dependency_tracker, - compilation_context: double(:compilation_context), - snapshot_repo: double(:snapshot_repo), - ) - end - - let(:dependency_tracker) { double(:dependency_tracker) } - - describe '#frozen?' do - subject { view.frozen? } - - context 'non-frozen config' do - it { is_expected.to be(false) } - end - - context 'frozen config' do - before { config.freeze } - it { is_expected.to be(true) } - end - end - - describe '#[]' do - subject { view[key] } - - before do - expect(dependency_tracker).to receive(:bounce).with(config, attributes: [key]) - end - - context 'with existing key' do - let(:key) { :animal } - it { is_expected.to eql('donkey') } - end - - context 'with non-existing key' do - let(:key) { :weapon } - it { is_expected.to eql(nil) } - end - end - - describe '#fetch' do - before do - expect(dependency_tracker).to receive(:bounce).with(config, attributes: [key]) - end - - context 'with existing key' do - let(:key) { :animal } - - subject { view.fetch(key) } - - it { is_expected.to eql('donkey') } - end - - context 'with non-existing key' do - let(:key) { :weapon } - - context 'with fallback' do - subject { view.fetch(key, 'nothing sorry') } - it { is_expected.to eql('nothing sorry') } - end - - context 'with block' do - subject { view.fetch(key) { 'nothing sorry' } } - it { is_expected.to eql('nothing sorry') } - end - - context 'with no fallback and no block' do - subject { view.fetch(key) } - - it 'raises' do - expect { subject }.to raise_error(KeyError) - end - end - end - end - - describe '#key?' do - subject { view.key?(key) } - - before do - expect(dependency_tracker).to receive(:bounce).with(config, attributes: [key]) - end - - context 'with existing key' do - let(:key) { :animal } - it { is_expected.to eql(true) } - end - - context 'with non-existing key' do - let(:key) { :weapon } - it { is_expected.to eql(false) } - end - end - - describe '#each' do - before do - expect(dependency_tracker).to receive(:bounce).with(config, attributes: true) - end - - example do - res = [] - view.each { |k, v| res << [k, v] } - - expect(res).to eql([[:amount, 9000], [:animal, 'donkey'], [:foo, { bar: :baz }]]) - end - end - - describe '#dig' do - subject { view.dig(*keys) } - - before do - expect(dependency_tracker).to receive(:bounce).with(config, attributes: [:foo]) - end - - context 'with existing keys' do - let(:keys) { %i[foo bar] } - it { is_expected.to eql(:baz) } - end - - context 'with non-existing keys' do - let(:keys) { %i[foo baz bar] } - it { is_expected.to be_nil } - end - end - - describe '#inspect' do - subject { view.inspect } - it { is_expected.to eql('') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/item_collection_without_reps_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/item_collection_without_reps_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/item_collection_without_reps_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/item_collection_without_reps_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/identifiable_collection_view_examples' - -describe Nanoc::ItemCollectionWithoutRepsView do - let(:view_class) { Nanoc::BasicItemView } - let(:collection_class) { Nanoc::Int::ItemCollection } - it_behaves_like 'an identifiable collection view' - - describe '#inspect' do - let(:wrapped) do - Nanoc::Int::ItemCollection.new(config) - end - - let(:view) { described_class.new(wrapped, view_context) } - let(:view_context) { double(:view_context) } - let(:config) { { string_pattern_type: 'glob' } } - - subject { view.inspect } - - it { is_expected.to eql('') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/item_collection_with_reps_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/item_collection_with_reps_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/item_collection_with_reps_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/item_collection_with_reps_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/identifiable_collection_view_examples' - -describe Nanoc::ItemCollectionWithRepsView do - let(:view_class) { Nanoc::CompilationItemView } - let(:collection_class) { Nanoc::Int::ItemCollection } - it_behaves_like 'an identifiable collection view' - - describe '#inspect' do - let(:wrapped) do - Nanoc::Int::ItemCollection.new(config) - end - - let(:view) { described_class.new(wrapped, view_context) } - let(:view_context) { double(:view_context) } - let(:config) { { string_pattern_type: 'glob' } } - - subject { view.inspect } - - it { is_expected.to eql('') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/item_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/item_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/item_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/item_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,447 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/document_view_examples' - -describe Nanoc::CompilationItemView do - let(:entity_class) { Nanoc::Int::Item } - let(:other_view_class) { Nanoc::LayoutView } - it_behaves_like 'a document view' - - let(:view_context) do - Nanoc::ViewContextForCompilation.new( - reps: reps, - items: items, - dependency_tracker: dependency_tracker, - compilation_context: compilation_context, - snapshot_repo: snapshot_repo, - ) - end - - let(:reps) { Nanoc::Int::ItemRepRepo.new } - let(:items) { Nanoc::Int::ItemCollection.new(config) } - let(:dependency_tracker) { Nanoc::Int::DependencyTracker.new(dependency_store) } - let(:dependency_store) { Nanoc::Int::DependencyStore.new(empty_items, empty_layouts, config) } - let(:compilation_context) { double(:compilation_context) } - let(:snapshot_repo) { Nanoc::Int::SnapshotRepo.new } - - let(:base_item) { Nanoc::Int::Item.new('base', {}, '/base.md') } - - let(:empty_items) { Nanoc::Int::ItemCollection.new(config) } - let(:empty_layouts) { Nanoc::Int::LayoutCollection.new(config) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - before do - dependency_tracker.enter(base_item) - end - - describe '#parent' do - let(:item) do - Nanoc::Int::Item.new('me', {}, identifier) - end - - let(:view) { described_class.new(item, view_context) } - - let(:items) do - Nanoc::Int::ItemCollection.new( - {}, - [ - item, - parent_item, - ].compact, - ) - end - - subject { view.parent } - - context 'with parent' do - context 'full identifier' do - let(:identifier) do - Nanoc::Identifier.new('/parent/me.md') - end - - let(:parent_item) do - Nanoc::Int::Item.new('parent', {}, '/parent.md') - end - - it 'raises' do - expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetParentOrChildrenOfNonLegacyItem) - end - end - - context 'legacy identifier' do - let(:identifier) do - Nanoc::Identifier.new('/parent/me/', type: :legacy) - end - - let(:parent_item) do - Nanoc::Int::Item.new('parent', {}, Nanoc::Identifier.new('/parent/', type: :legacy)) - end - - it 'returns a view for the parent' do - expect(subject.class).to eql(Nanoc::CompilationItemView) - expect(subject._unwrap).to eql(parent_item) - end - - it 'returns a view with the right context' do - expect(subject._context).to equal(view_context) - end - - context 'frozen parent' do - before { parent_item.freeze } - it { is_expected.to be_frozen } - end - - context 'non-frozen parent' do - it { is_expected.not_to be_frozen } - end - - context 'with root parent' do - let(:parent_item) { Nanoc::Int::Item.new('parent', {}, parent_identifier) } - let(:identifier) { Nanoc::Identifier.new('/me/', type: :legacy) } - let(:parent_identifier) { Nanoc::Identifier.new('/', type: :legacy) } - - it 'returns a view for the parent' do - expect(subject.class).to eql(Nanoc::CompilationItemView) - expect(subject._unwrap).to eql(parent_item) - end - end - end - end - - context 'without parent' do - let(:parent_item) do - nil - end - - context 'full identifier' do - let(:identifier) do - Nanoc::Identifier.new('/me.md') - end - - it 'raises' do - expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetParentOrChildrenOfNonLegacyItem) - end - end - - context 'legacy identifier' do - let(:identifier) do - Nanoc::Identifier.new('/me/', type: :legacy) - end - - it { is_expected.to be_nil } - it { is_expected.to be_frozen } - end - end - end - - describe '#children' do - let(:item) do - Nanoc::Int::Item.new('me', {}, identifier) - end - - let(:view) { described_class.new(item, view_context) } - - let(:items) do - Nanoc::Int::ItemCollection.new( - {}, - [ - item, - *children, - ], - ) - end - - subject { view.children } - - context 'full identifier' do - let(:identifier) do - Nanoc::Identifier.new('/me.md') - end - - let(:children) do - [Nanoc::Int::Item.new('child', {}, '/me/child.md')] - end - - it 'raises' do - expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetParentOrChildrenOfNonLegacyItem) - end - end - - context 'legacy identifier' do - let(:identifier) do - Nanoc::Identifier.new('/me/', type: :legacy) - end - - let(:children) do - [Nanoc::Int::Item.new('child', {}, Nanoc::Identifier.new('/me/child/', type: :legacy))] - end - - it 'returns views for the children' do - expect(subject.size).to eql(1) - expect(subject[0].class).to eql(Nanoc::CompilationItemView) - expect(subject[0]._unwrap).to eql(children[0]) - end - - it { is_expected.to be_frozen } - end - end - - describe '#reps' do - let(:item) { Nanoc::Int::Item.new('blah', {}, '/foo.md') } - let(:rep_a) { Nanoc::Int::ItemRep.new(item, :a) } - let(:rep_b) { Nanoc::Int::ItemRep.new(item, :b) } - - let(:reps) do - Nanoc::Int::ItemRepRepo.new.tap do |reps| - reps << rep_a - reps << rep_b - end - end - - let(:view) { described_class.new(item, view_context) } - - subject { view.reps } - - it 'returns a proper item rep collection' do - expect(subject.size).to eq(2) - expect(subject.class).to eql(Nanoc::CompilationItemRepCollectionView) - end - - it 'returns a view with the right context' do - expect(subject._context).to eq(view_context) - end - end - - describe '#compiled_content' do - subject { view.compiled_content(params) } - - let(:view) { described_class.new(item, view_context) } - - let(:item) do - Nanoc::Int::Item.new('content', {}, '/asdf') - end - - let(:reps) do - Nanoc::Int::ItemRepRepo.new.tap do |reps| - reps << rep - end - end - - let(:rep) do - Nanoc::Int::ItemRep.new(item, :default).tap do |ir| - ir.compiled = true - ir.snapshot_defs = [ - Nanoc::Int::SnapshotDef.new(:last, binary: false), - Nanoc::Int::SnapshotDef.new(:pre, binary: false), - Nanoc::Int::SnapshotDef.new(:post, binary: false), - Nanoc::Int::SnapshotDef.new(:specific, binary: false), - ] - end - end - - before do - snapshot_repo.set(rep, :last, Nanoc::Int::TextualContent.new('Last Hallo')) - snapshot_repo.set(rep, :pre, Nanoc::Int::TextualContent.new('Pre Hallo')) - snapshot_repo.set(rep, :post, Nanoc::Int::TextualContent.new('Post Hallo')) - snapshot_repo.set(rep, :specific, Nanoc::Int::TextualContent.new('Specific Hallo')) - end - - context 'requesting implicit default rep' do - let(:params) { {} } - - it { is_expected.to eq('Pre Hallo') } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item]) - end - - context 'requesting explicit snapshot' do - let(:params) { { snapshot: :specific } } - - it { is_expected.to eq('Specific Hallo') } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item]) - end - end - end - - context 'requesting explicit default rep' do - let(:params) { { rep: :default } } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item]) - end - - it { is_expected.to eq('Pre Hallo') } - - context 'requesting explicit snapshot' do - let(:params) { { snapshot: :specific } } - - it { is_expected.to eq('Specific Hallo') } - end - end - - context 'requesting other rep' do - let(:params) { { rep: :other } } - - it 'raises an error' do - expect { subject }.to raise_error(Nanoc::BasicItemRepCollectionView::NoSuchItemRepError) - end - end - end - - describe '#path' do - subject { view.path(params) } - - let(:view) { described_class.new(item, view_context) } - - let(:item) do - Nanoc::Int::Item.new('content', {}, '/asdf.md') - end - - let(:reps) do - Nanoc::Int::ItemRepRepo.new.tap do |reps| - reps << rep - end - end - - let(:rep) do - Nanoc::Int::ItemRep.new(item, :default).tap do |ir| - ir.paths = { - last: ['/about/'], - specific: ['/about.txt'], - } - end - end - - context 'requesting implicit default rep' do - let(:params) { {} } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item]) - end - - it { is_expected.to eq('/about/') } - - context 'requesting explicit snapshot' do - let(:params) { { snapshot: :specific } } - - it { is_expected.to eq('/about.txt') } - end - end - - context 'requesting explicit default rep' do - let(:params) { { rep: :default } } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item]) - end - - it { is_expected.to eq('/about/') } - - context 'requesting explicit snapshot' do - let(:params) { { snapshot: :specific } } - - it { is_expected.to eq('/about.txt') } - end - end - - context 'requesting other rep' do - let(:params) { { rep: :other } } - - it 'raises an error' do - expect { subject }.to raise_error(Nanoc::BasicItemRepCollectionView::NoSuchItemRepError) - end - end - end - - describe '#binary?' do - # TODO: implement - end - - describe '#raw_filename' do - subject { view.raw_filename } - - let(:item) do - Nanoc::Int::Item.new(content, { animal: 'donkey' }, '/foo') - end - - let(:view) { described_class.new(item, view_context) } - - context 'textual content with no raw filename' do - let(:content) { Nanoc::Int::TextualContent.new('asdf') } - - it { is_expected.to be_nil } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.raw_content?).to eq(true) - - expect(dep.props.attributes?).to eq(false) - expect(dep.props.compiled_content?).to eq(false) - expect(dep.props.path?).to eq(false) - end - end - - context 'textual content with raw filename' do - let(:content) { Nanoc::Int::TextualContent.new('asdf', filename: filename) } - let(:filename) { '/tmp/lol.txt' } - - it { is_expected.to eql('/tmp/lol.txt') } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.raw_content?).to eq(true) - - expect(dep.props.attributes?).to eq(false) - expect(dep.props.compiled_content?).to eq(false) - expect(dep.props.path?).to eq(false) - end - end - - context 'binary content' do - let(:content) { Nanoc::Int::BinaryContent.new(filename) } - let(:filename) { '/tmp/lol.txt' } - - it { is_expected.to eql('/tmp/lol.txt') } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.raw_content?).to eq(true) - - expect(dep.props.attributes?).to eq(false) - expect(dep.props.compiled_content?).to eq(false) - expect(dep.props.path?).to eq(false) - end - end - end - - describe '#inspect' do - let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf') } - let(:view) { described_class.new(item, nil) } - - subject { view.inspect } - - it { is_expected.to eql('') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/layout_collection_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/layout_collection_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/layout_collection_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/layout_collection_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/identifiable_collection_view_examples' - -describe Nanoc::LayoutCollectionView do - let(:view_class) { Nanoc::LayoutView } - let(:collection_class) { Nanoc::Int::LayoutCollection } - it_behaves_like 'an identifiable collection view' - - describe '#inspect' do - let(:wrapped) do - Nanoc::Int::LayoutCollection.new(config) - end - - let(:view) { described_class.new(wrapped, view_context) } - let(:view_context) { double(:view_context) } - let(:config) { { string_pattern_type: 'glob' } } - - subject { view.inspect } - - it { is_expected.to eql('') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/layout_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/layout_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/layout_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/layout_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/document_view_examples' - -describe Nanoc::LayoutView do - let(:entity_class) { Nanoc::Int::Layout } - let(:other_view_class) { Nanoc::CompilationItemView } - it_behaves_like 'a document view' - - describe '#inspect' do - let(:item) { Nanoc::Int::Layout.new('content', {}, '/asdf') } - let(:view) { described_class.new(item, nil) } - - subject { view.inspect } - - it { is_expected.to eql('') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/mutable_config_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/mutable_config_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/mutable_config_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/mutable_config_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::MutableConfigView do - let(:config) { {} } - let(:view) { described_class.new(config, nil) } - - describe '#[]=' do - it 'sets attributes' do - view[:awesomeness] = 'rather high' - expect(config[:awesomeness]).to eq('rather high') - end - end - - describe '#inspect' do - subject { view.inspect } - it { is_expected.to eql('') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/mutable_item_collection_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/mutable_item_collection_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/mutable_item_collection_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/mutable_item_collection_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/identifiable_collection_view_examples' -require_relative 'support/mutable_identifiable_collection_view_examples' - -describe Nanoc::MutableItemCollectionView do - let(:view_class) { Nanoc::MutableItemView } - let(:collection_class) { Nanoc::Int::ItemCollection } - it_behaves_like 'an identifiable collection view' - it_behaves_like 'a mutable identifiable collection view' - - let(:config) do - { string_pattern_type: 'glob' } - end - - describe '#create' do - let(:item) do - Nanoc::Int::Layout.new('content', {}, '/asdf') - end - - let(:wrapped) do - Nanoc::Int::ItemCollection.new(config, [item]) - end - - let(:view) { described_class.new(wrapped, nil) } - - it 'creates an object' do - view.create('new content', { title: 'New Page' }, '/new') - - expect(view._unwrap.size).to eq(2) - expect(view._unwrap['/new'].content.string).to eq('new content') - end - - it 'does not update wrapped' do - view.create('new content', { title: 'New Page' }, '/new') - - expect(wrapped.size).to eq(1) - expect(wrapped['/new']).to be_nil - end - - it 'returns self' do - ret = view.create('new content', { title: 'New Page' }, '/new') - expect(ret).to equal(view) - end - end - - describe '#inspect' do - let(:wrapped) do - Nanoc::Int::ItemCollection.new(config) - end - - let(:view) { described_class.new(wrapped, view_context) } - let(:view_context) { double(:view_context) } - let(:config) { { string_pattern_type: 'glob' } } - - subject { view.inspect } - - it { is_expected.to eql('') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/mutable_item_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/mutable_item_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/mutable_item_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/mutable_item_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/mutable_document_view_examples' - -describe Nanoc::MutableItemView do - let(:entity_class) { Nanoc::Int::Item } - it_behaves_like 'a mutable document view' - - let(:item) { entity_class.new('content', {}, '/asdf') } - let(:view) { described_class.new(item, nil) } - - it 'does have rep access' do - expect(view).not_to respond_to(:compiled_content) - expect(view).not_to respond_to(:path) - expect(view).not_to respond_to(:reps) - end - - describe '#inspect' do - let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf') } - let(:view) { described_class.new(item, nil) } - - subject { view.inspect } - - it { is_expected.to eql('') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/mutable_layout_collection_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/mutable_layout_collection_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/mutable_layout_collection_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/mutable_layout_collection_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/identifiable_collection_view_examples' -require_relative 'support/mutable_identifiable_collection_view_examples' - -describe Nanoc::MutableLayoutCollectionView do - let(:view_class) { Nanoc::MutableLayoutView } - let(:collection_class) { Nanoc::Int::LayoutCollection } - it_behaves_like 'an identifiable collection view' - it_behaves_like 'a mutable identifiable collection view' - - let(:config) do - { string_pattern_type: 'glob' } - end - - describe '#create' do - let(:layout) do - Nanoc::Int::Layout.new('content', {}, '/asdf') - end - - let(:wrapped) do - Nanoc::Int::LayoutCollection.new(config, [layout]) - end - - let(:view) { described_class.new(wrapped, nil) } - - it 'creates an object' do - view.create('new content', { title: 'New Page' }, '/new') - - expect(view._unwrap.size).to eq(2) - expect(view._unwrap['/new'].content.string).to eq('new content') - end - - it 'does not update wrapped' do - view.create('new content', { title: 'New Page' }, '/new') - - expect(wrapped.size).to eq(1) - expect(wrapped['/new']).to be_nil - end - - it 'returns self' do - ret = view.create('new content', { title: 'New Page' }, '/new') - expect(ret).to equal(view) - end - end - - describe '#inspect' do - let(:wrapped) do - Nanoc::Int::LayoutCollection.new(config) - end - - let(:view) { described_class.new(wrapped, view_context) } - let(:view_context) { double(:view_context) } - let(:config) { { string_pattern_type: 'glob' } } - - subject { view.inspect } - - it { is_expected.to eql('') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/mutable_layout_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/mutable_layout_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/mutable_layout_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/mutable_layout_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/mutable_document_view_examples' - -describe Nanoc::MutableLayoutView do - let(:entity_class) { Nanoc::Int::Layout } - it_behaves_like 'a mutable document view' - - describe '#inspect' do - let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf') } - let(:view) { described_class.new(item, nil) } - - subject { view.inspect } - - it { is_expected.to eql('') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/post_compile_item_rep_collection_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/post_compile_item_rep_collection_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/post_compile_item_rep_collection_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/post_compile_item_rep_collection_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/item_rep_collection_view_examples' - -describe Nanoc::PostCompileItemRepCollectionView do - it_behaves_like 'an item rep collection view' - let(:expected_view_class) { Nanoc::PostCompileItemRepView } -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/post_compile_item_rep_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/post_compile_item_rep_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/post_compile_item_rep_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/post_compile_item_rep_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,207 +0,0 @@ -# frozen_string_literal: true - -require_relative 'support/item_rep_view_examples' - -describe Nanoc::PostCompileItemRepView do - let(:expected_item_view_class) { Nanoc::PostCompileItemView } - - it_behaves_like 'an item rep view' - - let(:item_rep) { Nanoc::Int::ItemRep.new(item, :jacques) } - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo') } - let(:view) { described_class.new(item_rep, view_context) } - - let(:view_context) do - Nanoc::ViewContextForCompilation.new( - reps: Nanoc::Int::ItemRepRepo.new, - items: Nanoc::Int::ItemCollection.new(config), - dependency_tracker: dependency_tracker, - compilation_context: compilation_context, - snapshot_repo: snapshot_repo, - ) - end - - let(:reps) { double(:reps) } - let(:items) { Nanoc::Int::ItemCollection.new(config) } - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - let(:dependency_tracker) { Nanoc::Int::DependencyTracker.new(double(:dependency_store)) } - let(:compilation_context) { double(:compilation_context, compiled_content_cache: compiled_content_cache) } - let(:snapshot_repo) { double(:snapshot_repo) } - - let(:snapshot_contents) do - { - last: Nanoc::Int::TextualContent.new('content-last'), - pre: Nanoc::Int::TextualContent.new('content-pre'), - donkey: Nanoc::Int::TextualContent.new('content-donkey'), - } - end - - let(:compiled_content_cache) do - Nanoc::Int::CompiledContentCache.new(config: config).tap do |ccc| - ccc[item_rep] = snapshot_contents - end - end - - describe '#raw_path' do - context 'no args' do - subject { view.raw_path } - - it 'does not raise' do - subject - end - - context 'no path specified' do - it { is_expected.to be_nil } - end - - context 'path for default snapshot specified' do - before do - item_rep.raw_paths = { last: [Dir.getwd + '/output/about/index.html'] } - end - - it { is_expected.to eql(Dir.getwd + '/output/about/index.html') } - end - - context 'path specified, but not for default snapshot' do - before do - item_rep.raw_paths = { pre: [Dir.getwd + '/output/about/index.html'] } - end - - it { is_expected.to be_nil } - end - end - - context 'snapshot arg' do - subject { view.raw_path(snapshot: :special) } - - it 'does not raise' do - subject - end - - context 'no path specified' do - it { is_expected.to be_nil } - end - - context 'path for default snapshot specified' do - before do - item_rep.raw_paths = { special: [Dir.getwd + '/output/about/index.html'] } - end - - it { is_expected.to eql(Dir.getwd + '/output/about/index.html') } - end - - context 'path specified, but not for default snapshot' do - before do - item_rep.raw_paths = { pre: [Dir.getwd + '/output/about/index.html'] } - end - - it { is_expected.to be_nil } - end - end - end - - describe '#compiled_content' do - subject { view.compiled_content } - - context 'binary' do - let(:snapshot_contents) do - { - last: Nanoc::Int::TextualContent.new('content-last'), - pre: Nanoc::Int::BinaryContent.new('/content/pre'), - donkey: Nanoc::Int::TextualContent.new('content-donkey'), - } - end - - it 'raises error' do - expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetCompiledContentOfBinaryItem, 'You cannot access the compiled content of a binary item representation (but you can access the path). The offending item rep is /foo (rep name :jacques).') - end - end - - shared_examples 'returns pre content' do - example { expect(subject).to eq('content-pre') } - end - - shared_examples 'returns last content' do - example { expect(subject).to eq('content-last') } - end - - shared_examples 'returns donkey content' do - example { expect(subject).to eq('content-donkey') } - end - - shared_examples 'raises no-such-snapshot error' do - it 'raises error' do - err = Nanoc::Int::Errors::NoSuchSnapshot - expect { subject }.to raise_error(err) - end - end - - context 'textual' do - context 'snapshot provided' do - subject { view.compiled_content(snapshot: :donkey) } - let(:expected_snapshot) { :donkey } - - context 'snapshot exists' do - include_examples 'returns donkey content' - end - - context 'snapshot does not exist' do - let(:snapshot_contents) do - { - last: Nanoc::Int::TextualContent.new('content-last'), - pre: Nanoc::Int::TextualContent.new('content-pre'), - } - end - - include_examples 'raises no-such-snapshot error' - end - end - - context 'no snapshot provided' do - context 'pre and last snapshots exist' do - let(:snapshot_contents) do - { - last: Nanoc::Int::TextualContent.new('content-last'), - pre: Nanoc::Int::TextualContent.new('content-pre'), - donkey: Nanoc::Int::TextualContent.new('content-donkey'), - } - end - - include_examples 'returns pre content' - end - - context 'pre snapshot exists' do - let(:snapshot_contents) do - { - pre: Nanoc::Int::TextualContent.new('content-pre'), - donkey: Nanoc::Int::TextualContent.new('content-donkey'), - } - end - - include_examples 'returns pre content' - end - - context 'last snapshot exists' do - let(:snapshot_contents) do - { - last: Nanoc::Int::TextualContent.new('content-last'), - donkey: Nanoc::Int::TextualContent.new('content-donkey'), - } - end - - include_examples 'returns last content' - end - - context 'neither pre nor last snapshot exists' do - let(:snapshot_contents) do - { - donkey: Nanoc::Int::TextualContent.new('content-donkey'), - } - end - - include_examples 'raises no-such-snapshot error' - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/post_compile_item_view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/post_compile_item_view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/post_compile_item_view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/post_compile_item_view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::PostCompileItemView do - let(:item) { Nanoc::Int::Item.new('blah', {}, '/foo.md') } - let(:rep_a) { Nanoc::Int::ItemRep.new(item, :no_mod) } - let(:rep_b) { Nanoc::Int::ItemRep.new(item, :modded).tap { |r| r.modified = true } } - - let(:reps) do - Nanoc::Int::ItemRepRepo.new.tap do |reps| - reps << rep_a - reps << rep_b - end - end - - let(:view_context) { double(:view_context, reps: reps) } - let(:view) { described_class.new(item, view_context) } - - shared_examples 'a method that returns modified reps only' do - it 'returns only modified items' do - expect(subject.size).to eq(1) - expect(subject.map(&:name)).to eq(%i[modded]) - end - - it 'returns an array' do - expect(subject.class).to eql(Array) - end - end - - shared_examples 'a method that returns PostCompileItemRepViews' do - it 'returns PostCompileItemRepViews' do - expect(subject).to all(be_a(Nanoc::PostCompileItemRepView)) - end - end - - describe '#modified_reps' do - subject { view.modified_reps } - - it_behaves_like 'a method that returns modified reps only' - it_behaves_like 'a method that returns PostCompileItemRepViews' - end - - describe '#modified' do - subject { view.modified } - - it_behaves_like 'a method that returns modified reps only' - it_behaves_like 'a method that returns PostCompileItemRepViews' - end - - describe '#reps' do - subject { view.reps } - - it_behaves_like 'a method that returns PostCompileItemRepViews' - - it 'returns a PostCompileItemRepCollectionView' do - expect(subject).to be_a(Nanoc::PostCompileItemRepCollectionView) - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/support/document_view_examples.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/support/document_view_examples.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/support/document_view_examples.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/support/document_view_examples.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,340 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'a document view' do - let(:view) { described_class.new(document, view_context) } - - let(:view_context) do - Nanoc::ViewContextForCompilation.new( - reps: Nanoc::Int::ItemRepRepo.new, - items: Nanoc::Int::ItemCollection.new(config), - dependency_tracker: dependency_tracker, - compilation_context: double(:compilation_context), - snapshot_repo: double(:snapshot_repo), - ) - end - - let(:dependency_tracker) { Nanoc::Int::DependencyTracker.new(dependency_store) } - let(:dependency_store) { Nanoc::Int::DependencyStore.new(empty_items, empty_layouts, config) } - let(:base_item) { Nanoc::Int::Item.new('base', {}, '/base.md') } - - let(:empty_items) { Nanoc::Int::ItemCollection.new(config) } - let(:empty_layouts) { Nanoc::Int::LayoutCollection.new(config) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - before do - dependency_tracker.enter(base_item) - end - - describe '#frozen?' do - let(:document) { entity_class.new('content', {}, '/asdf') } - - subject { view.frozen? } - - context 'non-frozen document' do - it { is_expected.to be(false) } - end - - context 'frozen document' do - before { document.freeze } - it { is_expected.to be(true) } - end - end - - describe '#== and #eql?' do - let(:document) { entity_class.new('content', {}, '/asdf') } - - context 'comparing with document with same identifier' do - let(:other) { entity_class.new('content', {}, '/asdf') } - - it 'is ==' do - expect(view).to eq(other) - end - - it 'is not eql?' do - expect(view).not_to eql(other) - end - end - - context 'comparing with document with different identifier' do - let(:other) { entity_class.new('content', {}, '/fdsa') } - - it 'is not ==' do - expect(view).not_to eq(other) - end - - it 'is not eql?' do - expect(view).not_to eql(other) - end - end - - context 'comparing with document view with same identifier' do - let(:other) { other_view_class.new(entity_class.new('content', {}, '/asdf'), nil) } - - it 'is ==' do - expect(view).to eq(other) - end - - it 'is not eql?' do - expect(view).not_to eql(other) - end - end - - context 'comparing with document view with different identifier' do - let(:other) { other_view_class.new(entity_class.new('content', {}, '/fdsa'), nil) } - - it 'is not ==' do - expect(view).not_to eq(other) - end - - it 'is not eql?' do - expect(view).not_to eql(other) - end - end - - context 'comparing with other object' do - let(:other) { nil } - - it 'is not ==' do - expect(view).not_to eq(other) - end - - it 'is not eql?' do - expect(view).not_to eql(other) - end - end - end - - describe '#[]' do - let(:document) { entity_class.new('stuff', { animal: 'donkey' }, '/foo') } - - subject { view[key] } - - context 'with existant key' do - let(:key) { :animal } - - it { is_expected.to eql('donkey') } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([document]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.attributes?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.compiled_content?).to eq(false) - expect(dep.props.path?).to eq(false) - end - end - - context 'with non-existant key' do - let(:key) { :weapon } - - it { is_expected.to eql(nil) } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([document]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.attributes?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.compiled_content?).to eq(false) - expect(dep.props.path?).to eq(false) - end - end - end - - describe '#attributes' do - let(:document) { entity_class.new('stuff', { animal: 'donkey' }, '/foo') } - - subject { view.attributes } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([document]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.attributes?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.compiled_content?).to eq(false) - expect(dep.props.path?).to eq(false) - end - - it 'returns attributes' do - expect(subject).to eql(animal: 'donkey') - end - end - - describe '#fetch' do - let(:document) { entity_class.new('stuff', { animal: 'donkey' }, '/foo') } - - context 'with existant key' do - let(:key) { :animal } - - subject { view.fetch(key) } - - it { is_expected.to eql('donkey') } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([document]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.attributes?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.compiled_content?).to eq(false) - expect(dep.props.path?).to eq(false) - end - end - - context 'with non-existant key' do - let(:key) { :weapon } - - context 'with fallback' do - subject { view.fetch(key, 'nothing sorry') } - - it { is_expected.to eql('nothing sorry') } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([document]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.attributes?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.compiled_content?).to eq(false) - expect(dep.props.path?).to eq(false) - end - end - - context 'with block' do - subject { view.fetch(key) { 'nothing sorry' } } - - it { is_expected.to eql('nothing sorry') } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([document]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.attributes?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.compiled_content?).to eq(false) - expect(dep.props.path?).to eq(false) - end - end - - context 'with no fallback and no block' do - subject { view.fetch(key) } - - it 'raises' do - expect { subject }.to raise_error(KeyError) - end - end - end - end - - describe '#key?' do - let(:document) { entity_class.new('stuff', { animal: 'donkey' }, '/foo') } - - subject { view.key?(key) } - - context 'with existant key' do - let(:key) { :animal } - - it { is_expected.to eql(true) } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([document]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.attributes?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.compiled_content?).to eq(false) - expect(dep.props.path?).to eq(false) - end - end - - context 'with non-existant key' do - let(:key) { :weapon } - - it { is_expected.to eql(false) } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([document]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.attributes?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.compiled_content?).to eq(false) - expect(dep.props.path?).to eq(false) - end - end - end - - describe '#hash' do - let(:document) { double(:document, identifier: '/foo') } - - subject { view.hash } - - it { should == described_class.hash ^ '/foo'.hash } - end - - describe '#raw_content' do - let(:document) { entity_class.new('stuff', { animal: 'donkey' }, '/foo') } - - subject { view.raw_content } - - it { is_expected.to eql('stuff') } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([document]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.raw_content?).to eq(true) - - expect(dep.props.attributes?).to eq(false) - expect(dep.props.compiled_content?).to eq(false) - expect(dep.props.path?).to eq(false) - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/support/identifiable_collection_view_examples.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/support/identifiable_collection_view_examples.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/support/identifiable_collection_view_examples.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/support/identifiable_collection_view_examples.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,292 +0,0 @@ -# frozen_string_literal: true - -# Needs :view_class -shared_examples 'an identifiable collection view' do - let(:view) { described_class.new(wrapped, view_context) } - - let(:view_context) do - Nanoc::ViewContextForCompilation.new( - reps: Nanoc::Int::ItemRepRepo.new, - items: Nanoc::Int::ItemCollection.new(config), - dependency_tracker: dependency_tracker, - compilation_context: double(:__compilation_context), - snapshot_repo: double(:__snapshot_repo), - ) - end - - let(:dependency_tracker) do - Nanoc::Int::DependencyTracker::Null.new - end - - let(:config) do - { string_pattern_type: 'glob' } - end - - describe '#frozen?' do - let(:wrapped) do - collection_class.new( - config, - [ - double(:identifiable, identifier: Nanoc::Identifier.new('/foo')), - double(:identifiable, identifier: Nanoc::Identifier.new('/bar')), - ], - ) - end - - subject { view.frozen? } - - context 'non-frozen collection' do - it { is_expected.to be(false) } - end - - context 'frozen collection' do - before do - wrapped.each { |o| expect(o).to receive(:freeze) } - wrapped.freeze - end - - it { is_expected.to be(true) } - end - end - - describe '#_unwrap' do - let(:wrapped) do - collection_class.new( - config, - [ - double(:identifiable, identifier: Nanoc::Identifier.new('/foo')), - double(:identifiable, identifier: Nanoc::Identifier.new('/bar')), - double(:identifiable, identifier: Nanoc::Identifier.new('/baz')), - ], - ) - end - - subject { view._unwrap } - - it { should equal(wrapped) } - - it 'does not create dependency' do - expect(dependency_tracker).not_to receive(:bounce) - subject - end - end - - describe '#each' do - let(:wrapped) do - collection_class.new( - config, - [ - double(:identifiable, identifier: Nanoc::Identifier.new('/foo')), - double(:identifiable, identifier: Nanoc::Identifier.new('/bar')), - double(:identifiable, identifier: Nanoc::Identifier.new('/baz')), - ], - ) - end - - it 'creates dependency' do - expect(dependency_tracker).to receive(:bounce).with(wrapped, raw_content: true) - view.each { |_i| } - end - - it 'returns self' do - expect(view.each { |_i| }).to equal(view) - end - - it 'yields elements with the right context' do - view.each { |v| expect(v._context).to equal(view_context) } - end - end - - describe '#size' do - let(:wrapped) do - collection_class.new( - config, - [ - double(:identifiable, identifier: Nanoc::Identifier.new('/foo')), - double(:identifiable, identifier: Nanoc::Identifier.new('/bar')), - double(:identifiable, identifier: Nanoc::Identifier.new('/baz')), - ], - ) - end - - subject { view.size } - - it 'creates dependency' do - expect(dependency_tracker).to receive(:bounce).with(wrapped, raw_content: true) - subject - end - - it { should == 3 } - end - - describe '#[]' do - let(:page_object) do - double(:identifiable, identifier: Nanoc::Identifier.new('/page.erb')) - end - - let(:home_object) do - double(:identifiable, identifier: Nanoc::Identifier.new('/home.erb')) - end - - let(:wrapped) do - collection_class.new( - config, - [ - page_object, - home_object, - ], - ) - end - - subject { view[arg] } - - context 'no objects found' do - let(:arg) { '/donkey.*' } - it { is_expected.to equal(nil) } - - it 'creates dependency' do - expect(dependency_tracker).to receive(:bounce).with(wrapped, raw_content: ['/donkey.*']) - subject - end - end - - context 'string' do - let(:arg) { '/home.erb' } - - it 'creates dependency' do - expect(dependency_tracker).to receive(:bounce).with(wrapped, raw_content: ['/home.erb']) - subject - end - - it 'returns wrapped object' do - expect(subject.class).to equal(view_class) - expect(subject._unwrap).to equal(home_object) - end - - it 'returns objects with right context' do - expect(subject._context).to equal(view_context) - end - end - - context 'identifier' do - let(:arg) { Nanoc::Identifier.new('/home.erb') } - - it 'creates dependency' do - expect(dependency_tracker).to receive(:bounce).with(wrapped, raw_content: ['/home.erb']) - subject - end - - it 'returns wrapped object' do - expect(subject.class).to equal(view_class) - expect(subject._unwrap).to equal(home_object) - end - end - - context 'glob' do - let(:arg) { '/home.*' } - - context 'globs not enabled' do - let(:config) { { string_pattern_type: 'legacy' } } - - it 'creates dependency' do - expect(dependency_tracker).to receive(:bounce).with(wrapped, raw_content: ['/home.*']) - subject - end - - it 'returns nil' do - expect(subject).to be_nil - end - end - - context 'globs enabled' do - it 'creates dependency' do - expect(dependency_tracker).to receive(:bounce).with(wrapped, raw_content: ['/home.*']) - subject - end - - it 'returns wrapped object' do - expect(subject.class).to equal(view_class) - expect(subject._unwrap).to equal(home_object) - end - end - end - - context 'regex' do - let(:arg) { %r{\A/home} } - - it 'creates dependency' do - expect(dependency_tracker).to receive(:bounce).with(wrapped, raw_content: [%r{\A/home}]) - subject - end - - it 'returns wrapped object' do - expect(subject.class).to equal(view_class) - expect(subject._unwrap).to equal(home_object) - end - end - end - - describe '#find_all' do - let(:wrapped) do - collection_class.new( - config, - [ - double(:identifiable, identifier: Nanoc::Identifier.new('/about.css')), - double(:identifiable, identifier: Nanoc::Identifier.new('/about.md')), - double(:identifiable, identifier: Nanoc::Identifier.new('/style.css')), - ], - ) - end - - context 'with string' do - subject { view.find_all('/*.css') } - - it 'creates dependency' do - expect(dependency_tracker).to receive(:bounce).with(wrapped, raw_content: ['/*.css']) - subject - end - - it 'contains views' do - expect(subject.size).to eql(2) - about_css = subject.find { |iv| iv.identifier == '/about.css' } - style_css = subject.find { |iv| iv.identifier == '/style.css' } - expect(about_css.class).to equal(view_class) - expect(style_css.class).to equal(view_class) - end - end - - context 'with regex' do - subject { view.find_all(%r{\.css\z}) } - - it 'creates dependency' do - expect(dependency_tracker).to receive(:bounce).with(wrapped, raw_content: [%r{\.css\z}]) - subject - end - - it 'contains views' do - expect(subject.size).to eql(2) - about_css = subject.find { |iv| iv.identifier == '/about.css' } - style_css = subject.find { |iv| iv.identifier == '/style.css' } - expect(about_css.class).to equal(view_class) - expect(style_css.class).to equal(view_class) - end - end - - context 'with block' do - subject { view.find_all { |iv| iv.identifier =~ /css/ } } - - it 'creates dependency' do - expect(dependency_tracker).to receive(:bounce).with(wrapped, raw_content: true) - subject - end - - it 'contains views' do - expect(subject.size).to eql(2) - about_css = subject.find { |iv| iv.identifier == '/about.css' } - style_css = subject.find { |iv| iv.identifier == '/style.css' } - expect(about_css.class).to equal(view_class) - expect(style_css.class).to equal(view_class) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/support/item_rep_collection_view_examples.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/support/item_rep_collection_view_examples.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/support/item_rep_collection_view_examples.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/support/item_rep_collection_view_examples.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,140 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'an item rep collection view' do - let(:view) { described_class.new(wrapped, view_context) } - - let(:view_context) { double(:view_context) } - - let(:wrapped) do - [ - double(:item_rep, name: :foo), - double(:item_rep, name: :bar), - double(:item_rep, name: :baz), - ] - end - - describe '#_unwrap' do - subject { view._unwrap } - - it { should equal(wrapped) } - end - - describe '#frozen?' do - subject { view.frozen? } - - context 'non-frozen collection' do - it { is_expected.to be(false) } - end - - context 'frozen collection' do - before { wrapped.freeze } - it { is_expected.to be(true) } - end - end - - describe '#each' do - it 'yields' do - actual = [].tap { |res| view.each { |v| res << v } } - expect(actual.size).to eq(3) - end - - it 'returns self' do - expect(view.each { |_i| }).to equal(view) - end - - it 'yields elements with the right context' do - view.each { |v| expect(v._context).to equal(view_context) } - end - end - - describe '#size' do - subject { view.size } - - it { should == 3 } - end - - describe '#to_ary' do - subject { view.to_ary } - - it 'returns an array of item rep views' do - expect(subject.class).to eq(Array) - expect(subject.size).to eq(3) - expect(subject[0].class).to eql(expected_view_class) - expect(subject[0].name).to eql(:foo) - end - - it 'returns an array with correct contexts' do - expect(subject[0]._context).to equal(view_context) - end - end - - describe '#[]' do - subject { view[name] } - - context 'when not found' do - let(:name) { :donkey } - - it { should be_nil } - end - - context 'when found' do - let(:name) { :foo } - - it 'returns a view' do - expect(subject.class).to eq(expected_view_class) - expect(subject.name).to eq(:foo) - end - - it 'returns a view with the correct context' do - expect(subject._context).to equal(view_context) - end - end - - context 'when given a string' do - let(:name) { 'foo' } - - it 'raises' do - expect { subject }.to raise_error(ArgumentError, 'expected BasicItemRepCollectionView#[] to be called with a symbol') - end - end - - context 'when given a number' do - let(:name) { 0 } - - it 'raises' do - expect { subject }.to raise_error(ArgumentError, 'expected BasicItemRepCollectionView#[] to be called with a symbol (you likely want `.reps[:default]` rather than `.reps[0]`)') - end - end - end - - describe '#fetch' do - subject { view.fetch(name) } - - context 'when not found' do - let(:name) { :donkey } - - it 'raises' do - expect { subject }.to raise_error(Nanoc::BasicItemRepCollectionView::NoSuchItemRepError) - end - end - - context 'when found' do - let(:name) { :foo } - - it 'returns a view' do - expect(subject.class).to eq(expected_view_class) - expect(subject.name).to eq(:foo) - end - - it 'returns a view with the correct context' do - expect(subject._context).to equal(view_context) - end - end - end - - describe '#inspect' do - subject { view.inspect } - - it { is_expected.to eql('<' + described_class.name + '>') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/support/item_rep_view_examples.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/support/item_rep_view_examples.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/support/item_rep_view_examples.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/support/item_rep_view_examples.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,308 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'an item rep view' do - # needs expected_item_view_class - - let(:view_context) do - Nanoc::ViewContextForCompilation.new( - reps: Nanoc::Int::ItemRepRepo.new, - items: Nanoc::Int::ItemCollection.new(config), - dependency_tracker: dependency_tracker, - compilation_context: compilation_context, - snapshot_repo: snapshot_repo, - ) - end - - let(:compilation_context) { double(:compilation_context) } - let(:snapshot_repo) { Nanoc::Int::SnapshotRepo.new } - - let(:dependency_tracker) { Nanoc::Int::DependencyTracker.new(dependency_store) } - let(:dependency_store) { Nanoc::Int::DependencyStore.new(empty_items, empty_layouts, config) } - let(:base_item) { Nanoc::Int::Item.new('base', {}, '/base.md') } - - let(:empty_items) { Nanoc::Int::ItemCollection.new(config) } - let(:empty_layouts) { Nanoc::Int::LayoutCollection.new(config) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - before do - dependency_tracker.enter(base_item) - end - - describe '#frozen?' do - let(:item_rep) { Nanoc::Int::ItemRep.new(item, :jacques) } - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo') } - let(:view) { described_class.new(item_rep, view_context) } - - subject { view.frozen? } - - context 'non-frozen item rep' do - it { is_expected.to be(false) } - end - - context 'frozen item rep' do - before { item_rep.freeze } - it { is_expected.to be(true) } - end - end - - describe '#== and #eql?' do - let(:item_rep) { Nanoc::Int::ItemRep.new(item, :jacques) } - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo') } - let(:view) { described_class.new(item_rep, view_context) } - - context 'comparing with item rep with same identifier' do - let(:other_item) { double(:other_item, identifier: '/foo') } - let(:other) { double(:other_item_rep, item: other_item, name: :jacques) } - - it 'is ==' do - expect(view).to eq(other) - end - - it 'is eql?' do - expect(view).not_to eql(other) - end - end - - context 'comparing with item rep with different identifier' do - let(:other_item) { double(:other_item, identifier: '/bar') } - let(:other) { double(:other_item_rep, item: other_item, name: :jacques) } - - it 'is not ==' do - expect(view).not_to eq(other) - end - - it 'is not eql?' do - expect(view).not_to eql(other) - end - end - - context 'comparing with item rep with different name' do - let(:other_item) { double(:other_item, identifier: '/foo') } - let(:other) { double(:other_item_rep, item: other_item, name: :marvin) } - - it 'is not ==' do - expect(view).not_to eq(other) - end - - it 'is not eql?' do - expect(view).not_to eql(other) - end - end - - context 'comparing with item rep with same identifier' do - let(:other_item) { double(:other_item, identifier: '/foo') } - let(:other) { described_class.new(double(:other_item_rep, item: other_item, name: :jacques), view_context) } - - it 'is ==' do - expect(view).to eq(other) - end - - it 'is eql?' do - expect(view).not_to eql(other) - end - end - - context 'comparing with item rep with different identifier' do - let(:other_item) { double(:other_item, identifier: '/bar') } - let(:other) { described_class.new(double(:other_item_rep, item: other_item, name: :jacques), view_context) } - - it 'is not equal' do - expect(view).not_to eq(other) - expect(view).not_to eql(other) - end - end - - context 'comparing with item rep with different name' do - let(:other_item) { double(:other_item, identifier: '/foo') } - let(:other) { described_class.new(double(:other_item_rep, item: other_item, name: :marvin), view_context) } - - it 'is not equal' do - expect(view).not_to eq(other) - expect(view).not_to eql(other) - end - end - - context 'comparing with something that is not an item rep' do - let(:other_item) { double(:other_item, identifier: '/foo') } - let(:other) { :donkey } - - it 'is not equal' do - expect(view).not_to eq(other) - expect(view).not_to eql(other) - end - end - end - - describe '#hash' do - let(:item_rep) { Nanoc::Int::ItemRep.new(item, :jacques) } - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo') } - let(:view) { described_class.new(item_rep, view_context) } - - subject { view.hash } - - it { should == described_class.hash ^ Nanoc::Identifier.new('/foo').hash ^ :jacques.hash } - end - - describe '#snapshot?' do - subject { view.snapshot?(snapshot_name) } - - let(:view) { described_class.new(rep, view_context) } - - let(:rep) do - Nanoc::Int::ItemRep.new(item, :default).tap do |ir| - ir.compiled = true - ir.snapshot_defs = [ - Nanoc::Int::SnapshotDef.new(:last, binary: false), - ] - end - end - - let(:item) do - Nanoc::Int::Item.new('content', {}, '/asdf.md') - end - - let(:snapshot_name) { raise 'override me' } - - before do - snapshot_repo.set(rep, :last, Nanoc::Int::TextualContent.new('Hallo')) - end - - context 'snapshot exists' do - let(:snapshot_name) { :last } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.compiled_content?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.attributes?).to eq(false) - expect(dep.props.path?).to eq(false) - end - - it { is_expected.to be } - end - - context 'snapshot does not exist' do - let(:snapshot_name) { :donkey } - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.compiled_content?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.attributes?).to eq(false) - expect(dep.props.path?).to eq(false) - end - - it { is_expected.not_to be } - end - end - - describe '#path' do - subject { view.path } - - let(:view) { described_class.new(rep, view_context) } - - let(:rep) do - Nanoc::Int::ItemRep.new(item, :default).tap do |ir| - ir.paths = { - last: ['/about/'], - } - end - end - - let(:item) do - Nanoc::Int::Item.new('content', {}, '/asdf.md') - end - - it 'creates a dependency' do - expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item]) - end - - it 'creates a dependency with the right props' do - subject - dep = dependency_store.dependencies_causing_outdatedness_of(base_item)[0] - - expect(dep.props.path?).to eq(true) - - expect(dep.props.raw_content?).to eq(false) - expect(dep.props.attributes?).to eq(false) - expect(dep.props.compiled_content?).to eq(false) - end - - it { should eq('/about/') } - end - - describe '#binary?' do - let(:item_rep) { Nanoc::Int::ItemRep.new(item, :jacques) } - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo') } - let(:view) { described_class.new(item_rep, view_context) } - - subject { view.binary? } - - context 'no :last snapshot' do - before do - item_rep.snapshot_defs = [] - end - - it 'raises' do - expect { subject }.to raise_error(Nanoc::Int::Errors::NoSuchSnapshot) - end - end - - context ':last snapshot is textual' do - before do - item_rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(:last, binary: false)] - end - - it { is_expected.not_to be } - end - - context ':last snapshot is binary' do - before do - item_rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(:last, binary: true)] - end - - it { is_expected.to be } - end - end - - describe '#item' do - let(:item_rep) { Nanoc::Int::ItemRep.new(item, :jacques) } - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo') } - let(:view) { described_class.new(item_rep, view_context) } - - subject { view.item } - - it 'returns an item view' do - expect(subject).to be_a(expected_item_view_class) - end - - it 'returns an item view with the right context' do - expect(subject._context).to equal(view_context) - end - end - - describe '#inspect' do - let(:item_rep) { Nanoc::Int::ItemRep.new(item, :jacques) } - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo') } - let(:view) { described_class.new(item_rep, view_context) } - - subject { view.inspect } - - it { is_expected.to eql('<' + described_class.to_s + ' item.identifier=/foo name=jacques>') } - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/support/mutable_document_view_examples.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/support/mutable_document_view_examples.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/support/mutable_document_view_examples.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/support/mutable_document_view_examples.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,188 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'a mutable document view' do - let(:view) { described_class.new(document, view_context) } - - let(:view_context) do - Nanoc::ViewContextForCompilation.new( - reps: Nanoc::Int::ItemRepRepo.new, - items: Nanoc::Int::ItemCollection.new(config), - dependency_tracker: dependency_tracker, - compilation_context: double(:compilation_context), - snapshot_repo: snapshot_repo, - ) - end - - let(:dependency_tracker) { Nanoc::Int::DependencyTracker.new(double(:dependency_store)) } - let(:snapshot_repo) { double(:snapshot_repo) } - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd) } - - describe '#raw_content=' do - let(:document) { entity_class.new('content', {}, '/asdf') } - - it 'sets raw content' do - expect { view.raw_content = 'donkey' } - .to change { document.content.string } - .from('content') - .to('donkey') - end - - context 'checksum_data set' do - before do - document.checksum_data = 'my checksum data' - document.content_checksum_data = 'my content checksum data' - document.attributes_checksum_data = 'my attributes checksum data' - end - - it 'unsets checksum_data' do - expect { view.raw_content = 'donkey' } - .to change { document.checksum_data } - .from('my checksum data') - .to(nil) - end - - it 'unsets content_checksum_data' do - expect { view.raw_content = 'donkey' } - .to change { document.content_checksum_data } - .from('my content checksum data') - .to(nil) - end - - it 'keeps attributes_checksum_data' do - expect { view.raw_content = 'donkey' } - .not_to change { document.attributes_checksum_data } - end - end - end - - describe '#[]=' do - let(:document) { entity_class.new('content', {}, '/asdf') } - - it 'sets attributes' do - view[:title] = 'Donkey' - expect(view[:title]).to eq('Donkey') - end - - it 'disallows items' do - item = Nanoc::Int::Item.new('content', {}, '/foo.md') - expect { view[:item] = item }.to raise_error(Nanoc::MutableDocumentViewMixin::DisallowedAttributeValueError) - end - - it 'disallows layouts' do - layout = Nanoc::Int::Layout.new('content', {}, '/foo.md') - expect { view[:layout] = layout }.to raise_error(Nanoc::MutableDocumentViewMixin::DisallowedAttributeValueError) - end - - it 'disallows item views' do - item = Nanoc::CompilationItemView.new(Nanoc::Int::Item.new('content', {}, '/foo.md'), nil) - expect { view[:item] = item }.to raise_error(Nanoc::MutableDocumentViewMixin::DisallowedAttributeValueError) - end - - it 'disallows layout views' do - layout = Nanoc::LayoutView.new(Nanoc::Int::Layout.new('content', {}, '/foo.md'), nil) - expect { view[:layout] = layout }.to raise_error(Nanoc::MutableDocumentViewMixin::DisallowedAttributeValueError) - end - - context 'checksum_data set' do - before do - document.checksum_data = 'my checksum data' - document.content_checksum_data = 'my content checksum data' - document.attributes_checksum_data = 'my attributes checksum data' - end - - it 'unsets checksum_data' do - expect { view[:title] = 'Donkey' } - .to change { document.checksum_data } - .from('my checksum data') - .to(nil) - end - - it 'unsets attributes_checksum_data' do - expect { view[:title] = 'Donkey' } - .to change { document.attributes_checksum_data } - .from('my attributes checksum data') - .to(nil) - end - - it 'keeps content_checksum_data' do - expect { view[:title] = 'Donkey' } - .not_to change { document.content_checksum_data } - end - end - end - - describe '#identifier=' do - let(:document) { entity_class.new('content', {}, '/about.md') } - - subject { view.identifier = arg } - - context 'given a string' do - let(:arg) { '/about.adoc' } - - it 'changes the identifier' do - subject - expect(view.identifier).to eq('/about.adoc') - end - end - - context 'given an identifier' do - let(:arg) { Nanoc::Identifier.new('/about.adoc') } - - it 'changes the identifier' do - subject - expect(view.identifier).to eq('/about.adoc') - end - end - - context 'given anything else' do - let(:arg) { :donkey } - - it 'raises' do - expect { subject }.to raise_error(Nanoc::Identifier::NonCoercibleObjectError) - end - end - end - - describe '#update_attributes' do - let(:document) { entity_class.new('content', {}, '/asdf') } - - let(:update) { { friend: 'Giraffe' } } - - subject { view.update_attributes(update) } - - it 'sets attributes' do - expect { subject }.to change { view[:friend] }.from(nil).to('Giraffe') - end - - it 'returns self' do - expect(subject).to equal(view) - end - - context 'checksum_data set' do - before do - document.checksum_data = 'my checksum data' - document.content_checksum_data = 'my content checksum data' - document.attributes_checksum_data = 'my attributes checksum data' - end - - it 'unsets checksum_data' do - expect { subject } - .to change { document.checksum_data } - .from('my checksum data') - .to(nil) - end - - it 'unsets attributes_checksum_data' do - expect { subject } - .to change { document.attributes_checksum_data } - .from('my attributes checksum data') - .to(nil) - end - - it 'keeps content_checksum_data' do - expect { subject } - .not_to change { document.content_checksum_data } - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/base/views/support/mutable_identifiable_collection_view_examples.rb nanoc-4.11.14/nanoc/spec/nanoc/base/views/support/mutable_identifiable_collection_view_examples.rb --- nanoc-4.11.0/nanoc/spec/nanoc/base/views/support/mutable_identifiable_collection_view_examples.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/base/views/support/mutable_identifiable_collection_view_examples.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'a mutable identifiable collection view' do - let(:view) { described_class.new(wrapped, view_context) } - - let(:view_context) { double(:view_context) } - - let(:config) do - {} - end - - describe '#delete_if' do - let(:wrapped) do - collection_class.new( - config, - [double(:identifiable, identifier: Nanoc::Identifier.new('/asdf'))], - ) - end - - it 'deletes matching' do - view.delete_if { |i| i.identifier == '/asdf' } - expect(view._unwrap).to be_empty - end - - it 'does not mutate' do - view.delete_if { |i| i.identifier == '/asdf' } - expect(wrapped).not_to be_empty - end - - it 'deletes no non-matching' do - view.delete_if { |i| i.identifier == '/blah' } - expect(wrapped).not_to be_empty - end - - it 'returns self' do - ret = view.delete_if { |_i| false } - expect(ret).to equal(view) - end - - it 'yields items with the proper context' do - view.delete_if { |i| expect(i._context).to equal(view_context) } - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/checking/checks/external_links_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/checking/checks/external_links_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/checking/checks/external_links_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/checking/checks/external_links_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -10,17 +10,17 @@ end let(:site) do - Nanoc::Int::Site.new( + Nanoc::Core::Site.new( config: config, code_snippets: code_snippets, - data_source: Nanoc::Int::InMemDataSource.new(items, layouts), + data_source: Nanoc::Core::InMemoryDataSource.new(items, layouts), ) end - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } + let(:config) { Nanoc::Core::Configuration.new(dir: Dir.getwd).with_defaults } let(:code_snippets) { [] } - let(:items) { Nanoc::Int::ItemCollection.new(config, []) } - let(:layouts) { Nanoc::Int::LayoutCollection.new(config, []) } + let(:items) { Nanoc::Core::ItemCollection.new(config, []) } + let(:layouts) { Nanoc::Core::LayoutCollection.new(config, []) } before do FileUtils.mkdir_p('output') @@ -60,7 +60,7 @@ context 'redirect' do before do - skip 'Known failure on Windows' if Nanoc.on_windows? + skip 'Known failure on Windows' if Nanoc::Core.on_windows? end let(:check) do @@ -85,7 +85,7 @@ context 'redirect without location' do before do - skip 'Known failure on Windows' if Nanoc.on_windows? + skip 'Known failure on Windows' if Nanoc::Core.on_windows? end let(:check) do @@ -109,7 +109,7 @@ context 'invalid URL component' do before do - skip 'Known failure on Windows' if Nanoc.on_windows? + skip 'Known failure on Windows' if Nanoc::Core.on_windows? end let(:check) do diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/checking/check_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/checking/check_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/checking/check_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/checking/check_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -7,27 +7,69 @@ end describe Nanoc::Checking::Check do + let(:config) do + Nanoc::Core::Configuration.new( + dir: Dir.getwd, + hash: config_hash, + ).with_defaults + end + + let(:config_hash) { {} } + + let(:reps) { Nanoc::Core::ItemRepRepo.new } + + let(:site) do + Nanoc::Core::Site.new( + config: config, + code_snippets: [], + data_source: Nanoc::Core::InMemoryDataSource.new(items, layouts), + ) + end + + let(:items) { Nanoc::Core::ItemCollection.new(config, []) } + let(:layouts) { Nanoc::Core::LayoutCollection.new(config, []) } + + let(:view_context) do + Nanoc::Core::ViewContextForCompilation.new( + reps: reps, + items: items, + dependency_tracker: dependency_tracker, + compilation_context: compilation_context, + compiled_content_store: compiled_content_store, + ) + end + + let(:compilation_context) do + Nanoc::Core::CompilationContext.new( + action_provider: action_provider, + reps: reps, + site: site, + compiled_content_cache: compiled_content_cache, + compiled_content_store: compiled_content_store, + ) + end + + let(:action_provider) do + Class.new(Nanoc::Core::ActionProvider) do + def self.for(_context) + raise NotImplementedError + end + + def initialize; end + end.new + end + + let(:compiled_content_cache) { Nanoc::Core::CompiledContentCache.new(config: config) } + let(:compiled_content_store) { Nanoc::Core::CompiledContentStore.new } + + let(:dependency_tracker) { Nanoc::Core::DependencyTracker::Null.new } + describe '.define' do before do described_class.define(:spec_check_example_1) do add_issue('it’s totes bad') end - end - - let(:site) do - Nanoc::Int::Site.new( - config: config, - code_snippets: code_snippets, - data_source: Nanoc::Int::InMemDataSource.new(items, layouts), - ) - end - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - let(:code_snippets) { [] } - let(:items) { Nanoc::Int::ItemCollection.new(config, []) } - let(:layouts) { Nanoc::Int::LayoutCollection.new(config, []) } - - before do FileUtils.mkdir_p('output') File.write('Rules', 'passthrough "/**/*"') end @@ -54,9 +96,14 @@ end end - describe '#output_html_filenames' do + describe '#output_filenames' do + subject { check.output_filenames } + let(:check) do - described_class.new(output_filenames: output_filenames) + described_class.new( + output_filenames: output_filenames, + config: Nanoc::Core::ConfigView.new(config, view_context), + ) end let(:output_filenames) do @@ -70,14 +117,73 @@ ] end + context 'when exclude_files is unset' do + it { is_expected.to include('output/foo.htm') } + it { is_expected.to include('output/foo.html') } + it { is_expected.to include('output/foo.htmlx') } + it { is_expected.to include('output/foo.txt') } + it { is_expected.to include('output/foo.xhtml') } + it { is_expected.to include('output/foo.yhtml') } + end + + context 'when exclude_files is set' do + let(:config_hash) do + { checks: { all: { exclude_files: ['foo.xhtml'] } } } + end + + it { is_expected.to include('output/foo.htm') } + it { is_expected.to include('output/foo.html') } + it { is_expected.to include('output/foo.htmlx') } + it { is_expected.to include('output/foo.txt') } + it { is_expected.to include('output/foo.yhtml') } + + it { is_expected.not_to include('output/foo.xhtml') } + end + end + + describe '#output_html_filenames' do subject { check.output_html_filenames } - it { is_expected.to include('output/foo.html') } - it { is_expected.to include('output/foo.htm') } - it { is_expected.to include('output/foo.xhtml') } - - it { is_expected.not_to include('output/foo.txt') } - it { is_expected.not_to include('output/foo.htmlx') } - it { is_expected.not_to include('output/foo.yhtml') } + let(:check) do + described_class.new( + output_filenames: output_filenames, + config: Nanoc::Core::ConfigView.new(config, view_context), + ) + end + + let(:output_filenames) do + [ + 'output/foo.html', + 'output/foo.htm', + 'output/foo.xhtml', + 'output/foo.txt', + 'output/foo.htmlx', + 'output/foo.yhtml', + ] + end + + context 'when exclude_files is unset' do + it { is_expected.to include('output/foo.html') } + it { is_expected.to include('output/foo.htm') } + it { is_expected.to include('output/foo.xhtml') } + + it { is_expected.not_to include('output/foo.txt') } + it { is_expected.not_to include('output/foo.htmlx') } + it { is_expected.not_to include('output/foo.yhtml') } + end + + context 'when exclude_files is set' do + let(:config_hash) do + { checks: { all: { exclude_files: ['foo.xhtml'] } } } + end + + it { is_expected.to include('output/foo.html') } + it { is_expected.to include('output/foo.htm') } + + it { is_expected.not_to include('output/foo.xhtml') } + it { is_expected.not_to include('output/foo.txt') } + it { is_expected.not_to include('output/foo.htmlx') } + it { is_expected.not_to include('output/foo.yhtml') } + end end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/checking/runner_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/checking/runner_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/checking/runner_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/checking/runner_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -3,7 +3,7 @@ describe Nanoc::Checking::Runner, site: true do subject(:runner) { described_class.new(site) } - let(:site) { Nanoc::Int::SiteLoader.new.new_from_cwd } + let(:site) { Nanoc::Core::SiteLoader.new.new_from_cwd } describe '#any_enabled_checks?' do subject { runner.any_enabled_checks? } @@ -118,16 +118,19 @@ context 'given one full name' do let(:names) { %w[internal_links] } + it { is_expected.to eq([Nanoc::Checking::Checks::InternalLinks]) } end context 'given one full name with dash instead of underscore' do let(:names) { %w[internal-links] } + it { is_expected.to eq([Nanoc::Checking::Checks::InternalLinks]) } end context 'given one abbreviated name' do let(:names) { %w[ilinks] } + it { is_expected.to eq([Nanoc::Checking::Checks::InternalLinks]) } end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/command_runner_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/command_runner_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/command_runner_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/command_runner_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::CommandRunner, stdio: true do - describe '.find_site_dir' do - subject { described_class.find_site_dir } - - context 'config file in current dir' do - before { File.write('nanoc.yaml', 'hi') } - - it 'returns the current dir' do - expect(subject).to eq(File.expand_path(Dir.getwd)) - end - end - - context 'config file in parent dir' do - around do |ex| - FileUtils.mkdir_p('root/sub') - File.write('root/nanoc.yaml', 'hi') - chdir('root/sub') { ex.run } - end - - it 'returns the parent dir' do - expect(subject).to match(/root$/) - end - end - - context 'config file in grandparent dir' do - around do |ex| - FileUtils.mkdir_p('root/sub1/sub2') - File.write('root/nanoc.yaml', 'hi') - chdir('root/sub1/sub2') { ex.run } - end - - it 'returns the parent dir' do - expect(subject).to match(/root$/) - end - end - - context 'no config file in ancestral paths' do - it 'returns nil' do - expect(subject).to be_nil - end - end - end - - describe '.enter_site_dir' do - subject do - described_class.enter_site_dir - Dir.getwd - end - - context 'config file in current dir' do - before { File.write('nanoc.yaml', 'hi') } - - it 'returns the current dir' do - expect(subject).to eq(File.expand_path(Dir.getwd)) - end - end - - context 'config file in parent dir' do - around do |ex| - FileUtils.mkdir_p('root/sub') - File.write('root/nanoc.yaml', 'hi') - chdir('root/sub') { ex.run } - end - - it 'returns the parent dir' do - expect(subject).to match(/root$/) - end - end - - context 'config file in grandparent dir' do - around do |ex| - FileUtils.mkdir_p('root/sub1/sub2') - File.write('root/nanoc.yaml', 'hi') - chdir('root/sub1/sub2') { ex.run } - end - - it 'enters the parent dir' do - expect(subject).to match(/root$/) - end - end - - context 'no config file in ancestral paths' do - it 'raises' do - expect { subject }.to raise_error(::Nanoc::Int::Errors::GenericTrivial, 'The current working directory, nor any of its parents, seems to be a Nanoc site.') - end - end - end - - describe '#load_site' do - let(:command_runner) { described_class.new(nil, nil, nil) } - - subject { command_runner.load_site } - - before { File.write('nanoc.yaml', '{}') } - - it 'does not set @site' do - expect(command_runner.instance_variable_get(:@site)).to be_nil - expect { subject }.not_to change { command_runner.instance_variable_get(:@site) } - end - - it 'returns site' do - expect(subject).to be_a(Nanoc::Int::Site) - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/check_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/check_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/check_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/check_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::Commands::Check, site: true, stdio: true do - describe '#run' do - before do - File.write('Checks', "deploy_check :stale\n") - end - - context 'without options and arguments' do - subject { Nanoc::CLI.run(['check']) } - - context 'no issues for any checks' do - it 'succeeds' do - subject - end - end - - context 'issues for deploy check' do - before do - FileUtils.mkdir_p('output') - File.write('output/asdf.txt', 'staaale') - end - - it 'fails' do - expect { subject }.to raise_error(Nanoc::Int::Errors::GenericTrivial, 'One or more checks failed') - end - end - - context 'issues for non-deploy check' do - before do - FileUtils.mkdir_p('output') - File.write('output/asdf.txt', 'staaale') - File.write('Checks', '') - end - - it 'succeeds' do - subject - end - end - end - end - - describe 'help' do - subject { Nanoc::CLI.run(%w[help check]) } - - it 'shows --deploy as deprecated' do - expect { subject }.to output(/--deploy.*\(deprecated\)/).to_stdout - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/compile/abstract_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/compile/abstract_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/compile/abstract_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/compile/abstract_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::Commands::CompileListeners::Abstract do - subject { klass.new } - - context 'abstract class' do - let(:klass) { described_class } - - it 'errors on starting' do - expect { subject.start }.to raise_error(NotImplementedError) - end - - it 'stops silently' do - subject.stop - end - end - - context 'concrete subclass' do - let(:klass) do - Class.new(described_class) do - attr_reader :started - attr_reader :stopped - - def initialize - @started = false - @stopped = false - end - - def start - @started = true - end - - def stop - @stopped = true - end - end - end - - it 'starts' do - subject.start - expect(subject.started).to be - end - - it 'stops' do - subject.start - subject.stop - expect(subject.stopped).to be - end - - it 'starts safely' do - subject.start_safely - expect(subject.started).to be - end - - it 'stops safely' do - subject.start_safely - subject.stop_safely - expect(subject.stopped).to be - end - end - - context 'listener that does not start or stop properly' do - let(:klass) do - Class.new(described_class) do - def start - raise 'boom' - end - - def stop - raise 'boom' - end - end - end - - it 'raises on start, but not stop' do - expect { subject.start_safely }.to raise_error(RuntimeError) - expect { subject.stop_safely }.not_to raise_error - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/compile/diff_generator_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/compile/diff_generator_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/compile/diff_generator_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/compile/diff_generator_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::Commands::CompileListeners::DiffGenerator do - describe '.enable_for?' do - subject { described_class.enable_for?(command_runner, site) } - - let(:options) { {} } - let(:config_hash) { {} } - - let(:arguments) { double(:arguments) } - let(:command) { double(:command) } - - let(:site) do - Nanoc::Int::Site.new( - config: config, - code_snippets: code_snippets, - data_source: Nanoc::Int::InMemDataSource.new(items, layouts), - ) - end - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd, hash: config_hash).with_defaults } - let(:items) { [] } - let(:layouts) { [] } - let(:code_snippets) { [] } - - let(:command_runner) do - Nanoc::CLI::Commands::Compile.new(options, arguments, command) - end - - context 'default' do - it { is_expected.not_to be } - end - - context 'enabled in config' do - let(:config_hash) { { enable_output_diff: true } } - it { is_expected.to be } - end - - context 'enabled on command line' do - let(:options) { { diff: true } } - it { is_expected.to be } - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/compile/file_action_printer_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/compile/file_action_printer_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/compile/file_action_printer_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/compile/file_action_printer_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,127 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::Commands::CompileListeners::FileActionPrinter, stdio: true do - let(:listener) { described_class.new(reps: reps) } - - before { Timecop.freeze(Time.local(2008, 1, 2, 14, 5, 0)) } - after { Timecop.return } - - let(:reps) do - Nanoc::Int::ItemRepRepo.new.tap do |reps| - reps << rep - end - end - - let(:item) { Nanoc::Int::Item.new('<%= 1 + 2 %>', {}, '/hi.md') } - - let(:rep) do - Nanoc::Int::ItemRep.new(item, :default).tap do |rep| - rep.raw_paths = { default: ['/hi.html'] } - end - end - - it 'records from compilation_started to rep_write_ended' do - listener.start - - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - - expect { Nanoc::Int::NotificationCenter.post(:rep_write_ended, rep, false, '/foo.html', true, true) } - .to output(/create.*\[1\.00s\]/).to_stdout - end - - it 'stops listening after #stop' do - listener.start - listener.stop - - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - - expect { Nanoc::Int::NotificationCenter.post(:rep_write_ended, rep, false, '/foo.html', true, true) } - .not_to output(/create/).to_stdout - end - - it 'records from compilation_started over compilation_suspended to rep_write_ended' do - listener.start - - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - Nanoc::Int::NotificationCenter.post(:compilation_suspended, rep, :__irrelevant__) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 3)) - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 6)) - - expect { Nanoc::Int::NotificationCenter.post(:rep_write_ended, rep, false, '/foo.html', true, true) } - .to output(/create.*\[4\.00s\]/).to_stdout - end - - it 'records from compilation_started over rep_write_{enqueued,started} to rep_write_ended' do - listener.start - - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - Nanoc::Int::NotificationCenter.post(:rep_write_enqueued, rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 3)) - Nanoc::Int::NotificationCenter.post(:rep_write_started, rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 6)) - - expect { Nanoc::Int::NotificationCenter.post(:rep_write_ended, rep, false, '/foo.html', true, true) } - .to output(/create.*\[4\.00s\]/).to_stdout - end - - context 'log level = high' do - before { listener.start } - before { Nanoc::CLI::Logger.instance.level = :high } - - it 'does not print skipped (uncompiled) reps' do - expect { listener.stop } - .not_to output(/skip/).to_stdout - end - - it 'prints nothing' do - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - - expect { Nanoc::Int::NotificationCenter.post(:rep_write_ended, rep, false, '/foo.html', false, false) } - .not_to output(/identical/).to_stdout - end - - it 'prints nothing' do - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - Nanoc::Int::NotificationCenter.post(:cached_content_used, rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - - expect { Nanoc::Int::NotificationCenter.post(:rep_write_ended, rep, false, '/foo.html', false, false) } - .not_to output(/cached/).to_stdout - end - end - - context 'log level = low' do - before { listener.start } - before { Nanoc::CLI::Logger.instance.level = :low } - - it 'prints skipped (uncompiled) reps' do - expect { listener.stop } - .to output(/skip.*\/hi\.html/).to_stdout - end - - it 'prints “identical” if not cached' do - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - - expect { Nanoc::Int::NotificationCenter.post(:rep_write_ended, rep, false, '/foo.html', false, false) } - .to output(/identical/).to_stdout - end - - it 'prints “cached” if cached' do - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - Nanoc::Int::NotificationCenter.post(:cached_content_used, rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - - expect { Nanoc::Int::NotificationCenter.post(:rep_write_ended, rep, false, '/foo.html', false, false) } - .to output(/cached/).to_stdout - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/compile/timing_recorder_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/compile/timing_recorder_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/compile/timing_recorder_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/compile/timing_recorder_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,259 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::Commands::CompileListeners::TimingRecorder, stdio: true do - let(:listener) { described_class.new(reps: reps) } - - before { Timecop.freeze(Time.local(2008, 1, 2, 14, 5, 0)) } - after { Timecop.return } - - before { Nanoc::CLI.verbosity = 2 } - - before { listener.start } - after { listener.stop_safely } - - let(:reps) do - Nanoc::Int::ItemRepRepo.new.tap do |reps| - reps << rep - end - end - - let(:item) { Nanoc::Int::Item.new('<%= 1 + 2 %>', {}, '/hi.md') } - - let(:rep) do - Nanoc::Int::ItemRep.new(item, :default).tap do |rep| - rep.raw_paths = { default: ['/hi.html'] } - end - end - - let(:other_rep) do - Nanoc::Int::ItemRep.new(item, :other).tap do |rep| - rep.raw_paths = { default: ['/bye.html'] } - end - end - - it 'prints filters table' do - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) - Nanoc::Int::NotificationCenter.post(:filtering_started, rep, :erb) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :erb) - Timecop.freeze(Time.local(2008, 9, 1, 10, 14, 1)) - Nanoc::Int::NotificationCenter.post(:filtering_started, rep, :erb) - Timecop.freeze(Time.local(2008, 9, 1, 10, 14, 3)) - Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :erb) - - expect { listener.stop } - .to output(/^\s*erb │ 2 1\.00s 1\.50s 1\.90s 1\.95s 2\.00s 3\.00s$/).to_stdout - end - - it 'records single from filtering_started to filtering_ended' do - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) - Nanoc::Int::NotificationCenter.post(:filtering_started, rep, :erb) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :erb) - - expect(listener.filters_summary.get(name: 'erb').min).to eq(1.00) - expect(listener.filters_summary.get(name: 'erb').avg).to eq(1.00) - expect(listener.filters_summary.get(name: 'erb').max).to eq(1.00) - expect(listener.filters_summary.get(name: 'erb').sum).to eq(1.00) - expect(listener.filters_summary.get(name: 'erb').count).to eq(1.00) - end - - it 'records multiple from filtering_started to filtering_ended' do - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) - Nanoc::Int::NotificationCenter.post(:filtering_started, rep, :erb) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :erb) - Timecop.freeze(Time.local(2008, 9, 1, 10, 14, 1)) - Nanoc::Int::NotificationCenter.post(:filtering_started, rep, :erb) - Timecop.freeze(Time.local(2008, 9, 1, 10, 14, 3)) - Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :erb) - - expect(listener.filters_summary.get(name: 'erb').min).to eq(1.00) - expect(listener.filters_summary.get(name: 'erb').avg).to eq(1.50) - expect(listener.filters_summary.get(name: 'erb').max).to eq(2.00) - expect(listener.filters_summary.get(name: 'erb').sum).to eq(3.00) - expect(listener.filters_summary.get(name: 'erb').count).to eq(2.00) - end - - it 'records filters in nested filtering_started/filtering_ended' do - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) - Nanoc::Int::NotificationCenter.post(:filtering_started, rep, :outer) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - Nanoc::Int::NotificationCenter.post(:filtering_started, rep, :inner) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 3)) - Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :inner) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 6)) - Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :outer) - - expect(listener.filters_summary.get(name: 'inner').min).to eq(2.00) - expect(listener.filters_summary.get(name: 'inner').avg).to eq(2.00) - expect(listener.filters_summary.get(name: 'inner').max).to eq(2.00) - expect(listener.filters_summary.get(name: 'inner').sum).to eq(2.00) - expect(listener.filters_summary.get(name: 'inner').count).to eq(1.00) - - expect(listener.filters_summary.get(name: 'outer').min).to eq(6.00) - expect(listener.filters_summary.get(name: 'outer').avg).to eq(6.00) - expect(listener.filters_summary.get(name: 'outer').max).to eq(6.00) - expect(listener.filters_summary.get(name: 'outer').sum).to eq(6.00) - expect(listener.filters_summary.get(name: 'outer').count).to eq(1.00) - end - - it 'pauses outer stopwatch when suspended' do - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - Nanoc::Int::NotificationCenter.post(:filtering_started, rep, :outer) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - Nanoc::Int::NotificationCenter.post(:filtering_started, rep, :inner) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 3)) - Nanoc::Int::NotificationCenter.post(:compilation_suspended, rep, :__anything__) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 6)) - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 10)) - Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :inner) - Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :outer) - - expect(listener.filters_summary.get(name: 'outer').min).to eq(7.00) - expect(listener.filters_summary.get(name: 'outer').avg).to eq(7.00) - expect(listener.filters_summary.get(name: 'outer').max).to eq(7.00) - expect(listener.filters_summary.get(name: 'outer').sum).to eq(7.00) - expect(listener.filters_summary.get(name: 'outer').count).to eq(1.00) - end - - it 'records single from filtering_started over compilation_{suspended,started} to filtering_ended' do - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) - Nanoc::Int::NotificationCenter.post(:filtering_started, rep, :erb) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - Nanoc::Int::NotificationCenter.post(:compilation_suspended, rep, :__anything__) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 3)) - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 7)) - Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :erb) - - expect(listener.filters_summary.get(name: 'erb').min).to eq(5.00) - expect(listener.filters_summary.get(name: 'erb').avg).to eq(5.00) - expect(listener.filters_summary.get(name: 'erb').max).to eq(5.00) - expect(listener.filters_summary.get(name: 'erb').sum).to eq(5.00) - expect(listener.filters_summary.get(name: 'erb').count).to eq(1.00) - end - - it 'records single phase start+stop' do - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) - Nanoc::Int::NotificationCenter.post(:phase_started, 'donkey', rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - Nanoc::Int::NotificationCenter.post(:phase_ended, 'donkey', rep) - - expect(listener.phases_summary.get(name: 'donkey').min).to eq(1.00) - expect(listener.phases_summary.get(name: 'donkey').avg).to eq(1.00) - expect(listener.phases_summary.get(name: 'donkey').max).to eq(1.00) - expect(listener.phases_summary.get(name: 'donkey').sum).to eq(1.00) - expect(listener.phases_summary.get(name: 'donkey').count).to eq(1.00) - end - - it 'records multiple phase start+stop' do - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) - Nanoc::Int::NotificationCenter.post(:phase_started, 'donkey', rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - Nanoc::Int::NotificationCenter.post(:phase_ended, 'donkey', rep) - Timecop.freeze(Time.local(2008, 9, 1, 11, 6, 0)) - Nanoc::Int::NotificationCenter.post(:phase_started, 'donkey', rep) - Timecop.freeze(Time.local(2008, 9, 1, 11, 6, 2)) - Nanoc::Int::NotificationCenter.post(:phase_ended, 'donkey', rep) - - expect(listener.phases_summary.get(name: 'donkey').min).to eq(1.00) - expect(listener.phases_summary.get(name: 'donkey').avg).to eq(1.50) - expect(listener.phases_summary.get(name: 'donkey').max).to eq(2.00) - expect(listener.phases_summary.get(name: 'donkey').sum).to eq(3.00) - expect(listener.phases_summary.get(name: 'donkey').count).to eq(2.00) - end - - it 'records single phase start+yield+resume+stop' do - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) - Nanoc::Int::NotificationCenter.post(:phase_started, 'donkey', rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - Nanoc::Int::NotificationCenter.post(:phase_yielded, 'donkey', rep) - Timecop.freeze(Time.local(2008, 9, 1, 11, 6, 0)) - Nanoc::Int::NotificationCenter.post(:phase_resumed, 'donkey', rep) - Timecop.freeze(Time.local(2008, 9, 1, 11, 6, 2)) - Nanoc::Int::NotificationCenter.post(:phase_ended, 'donkey', rep) - - expect(listener.phases_summary.get(name: 'donkey').min).to eq(3.00) - expect(listener.phases_summary.get(name: 'donkey').avg).to eq(3.00) - expect(listener.phases_summary.get(name: 'donkey').max).to eq(3.00) - expect(listener.phases_summary.get(name: 'donkey').sum).to eq(3.00) - expect(listener.phases_summary.get(name: 'donkey').count).to eq(1.00) - end - - it 'records single phase start+yield+abort+start+stop' do - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0)) - Nanoc::Int::NotificationCenter.post(:phase_started, 'donkey', rep) - Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1)) - Nanoc::Int::NotificationCenter.post(:phase_yielded, 'donkey', rep) - Timecop.freeze(Time.local(2008, 9, 1, 11, 6, 0)) - Nanoc::Int::NotificationCenter.post(:phase_aborted, 'donkey', rep) - Timecop.freeze(Time.local(2008, 9, 1, 12, 7, 2)) - Nanoc::Int::NotificationCenter.post(:phase_started, 'donkey', rep) - Timecop.freeze(Time.local(2008, 9, 1, 12, 7, 5)) - Nanoc::Int::NotificationCenter.post(:phase_ended, 'donkey', rep) - - expect(listener.phases_summary.get(name: 'donkey').min).to eq(1.00) - expect(listener.phases_summary.get(name: 'donkey').avg).to eq(2.00) - expect(listener.phases_summary.get(name: 'donkey').max).to eq(3.00) - expect(listener.phases_summary.get(name: 'donkey').sum).to eq(4.00) - expect(listener.phases_summary.get(name: 'donkey').count).to eq(2.00) - end - - it 'records stage duration' do - Nanoc::Int::NotificationCenter.post(:stage_ran, 1.23, 'donkey_stage') - - expect(listener.stages_summary.get(name: 'donkey_stage').sum).to eq(1.23) - expect(listener.stages_summary.get(name: 'donkey_stage').count).to eq(1) - end - - it 'prints stage durations' do - Nanoc::Int::NotificationCenter.post(:stage_ran, 1.23, 'donkey_stage') - - expect { listener.stop } - .to output(/^\s*donkey_stage │ 1\.23s$/).to_stdout - end - - it 'prints out outdatedness rule durations' do - Nanoc::Int::NotificationCenter.post(:outdatedness_rule_ran, 1.0, Nanoc::Int::OutdatednessRules::CodeSnippetsModified) - - expect { listener.stop } - .to output(/^\s*CodeSnippetsModified │ 1 1\.00s 1\.00s 1\.00s 1\.00s 1\.00s 1\.00s$/).to_stdout - end - - it 'records single outdatedness rule duration' do - Nanoc::Int::NotificationCenter.post(:outdatedness_rule_ran, 1.0, Nanoc::Int::OutdatednessRules::CodeSnippetsModified) - - expect(listener.outdatedness_rules_summary.get(name: 'CodeSnippetsModified').min).to eq(1.00) - expect(listener.outdatedness_rules_summary.get(name: 'CodeSnippetsModified').avg).to eq(1.00) - expect(listener.outdatedness_rules_summary.get(name: 'CodeSnippetsModified').max).to eq(1.00) - expect(listener.outdatedness_rules_summary.get(name: 'CodeSnippetsModified').sum).to eq(1.00) - expect(listener.outdatedness_rules_summary.get(name: 'CodeSnippetsModified').count).to eq(1.00) - end - - it 'records multiple outdatedness rule duration' do - Nanoc::Int::NotificationCenter.post(:outdatedness_rule_ran, 1.0, Nanoc::Int::OutdatednessRules::CodeSnippetsModified) - Nanoc::Int::NotificationCenter.post(:outdatedness_rule_ran, 3.0, Nanoc::Int::OutdatednessRules::CodeSnippetsModified) - - expect(listener.outdatedness_rules_summary.get(name: 'CodeSnippetsModified').min).to eq(1.00) - expect(listener.outdatedness_rules_summary.get(name: 'CodeSnippetsModified').avg).to eq(2.00) - expect(listener.outdatedness_rules_summary.get(name: 'CodeSnippetsModified').max).to eq(3.00) - expect(listener.outdatedness_rules_summary.get(name: 'CodeSnippetsModified').sum).to eq(4.00) - expect(listener.outdatedness_rules_summary.get(name: 'CodeSnippetsModified').count).to eq(2.00) - end - - it 'prints load store durations' do - Nanoc::Int::NotificationCenter.post(:store_loaded, 1.23, Nanoc::Int::ChecksumStore) - - expect { listener.stop } - .to output(/^\s*Nanoc::Int::ChecksumStore │ 1\.23s$/).to_stdout - end - - it 'skips printing empty metrics' do - expect { listener.stop } - .not_to output(/filters|phases|stages/).to_stdout - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/compile_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/compile_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/compile_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/compile_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::Commands::Compile, site: true, stdio: true do - describe '#run' do - it 'starts and stops listeners as needed' do - test_listener_class = Class.new(::Nanoc::CLI::Commands::CompileListeners::Abstract) do - def start - @started = true - end - - def stop - @stopped = true - end - - def started? - @started - end - - def stopped? - @stopped - end - end - - expect(Nanoc::CLI::Commands::CompileListeners::Aggregate) - .to receive(:default_listener_classes) - .and_return([test_listener_class]) - - listener = test_listener_class.new - - expect(test_listener_class) - .to receive(:new) - .and_return(listener) - - options = {} - arguments = [] - cmd = nil - cmd_runner = Nanoc::CLI::Commands::Compile.new(options, arguments, cmd) - - cmd_runner.run - - expect(listener).to be_started - expect(listener).to be_stopped - end - - describe '--watch', fork: true do - it 'watches with --watch' do - pipe_stdout_read, pipe_stdout_write = IO.pipe - pid = fork do - trap(:INT) { exit(0) } - - pipe_stdout_read.close - $stdout = pipe_stdout_write - - # TODO: Use Nanoc::CLI.run instead (when --watch is no longer experimental) - options = { watch: true } - arguments = [] - cmd = nil - cmd_runner = Nanoc::CLI::Commands::Compile.new(options, arguments, cmd) - cmd_runner.run - end - pipe_stdout_write.close - - # Wait until ready - Timeout.timeout(5) do - progress = 0 - pipe_stdout_read.each_line do |line| - progress += 1 if line.start_with?('Listening for lib/ changes') - progress += 1 if line.start_with?('Listening for site changes') - break if progress == 2 - end - end - sleep 0.5 # Still needs time to warm up… - - File.write('content/lol.html', 'hej') - sleep_until { File.file?('output/lol.html') } - expect(File.read('output/lol.html')).to eq('hej') - - sleep 1.0 # HFS+ mtime resolution is 1s - File.write('content/lol.html', 'bye') - sleep_until { File.read('output/lol.html') == 'bye' } - - # Stop - Process.kill('INT', pid) - Process.waitpid(pid) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/deploy_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/deploy_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/deploy_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/deploy_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,333 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::Commands::Deploy, site: true, stdio: true do - before do - skip_unless_have_command 'rsync' - end - - describe '#run' do - let(:config) { {} } - - before do - # Prevent double-loading - expect(Nanoc::CLI).to receive(:setup) - - File.write('nanoc.yaml', YAML.dump(config)) - end - - shared_examples 'no effective deploy' do - it 'does not write any files' do - expect { run rescue nil }.not_to change { Dir['remote/*'] } - expect(Dir['remote/*']).to be_empty - end - end - - shared_examples 'effective deploy' do - it 'writes files' do - expect { run }.to change { Dir['remote/*'] }.from([]).to(['remote/success.txt']) - expect(File.read('remote/success.txt')).to eql('hurrah') - end - end - - shared_examples 'attempted/effective deploy' do - context 'no checks' do - include_examples 'effective deploy' - end - - context 'checks fail' do - before do - File.write( - 'Checks', - "check :donkey do\n" \ - " add_issue('things are broken', subject: 'success.txt')\n" \ - "end\n" \ - "\n" \ - "deploy_check :donkey\n", - ) - end - - include_examples 'no effective deploy' - - context 'checks disabled' do - context '--no-check' do - let(:command) { super() + ['--no-check'] } - include_examples 'effective deploy' - end - - context '--Ck' do - let(:command) { super() + ['-C'] } - include_examples 'effective deploy' - end - end - end - - context 'checks pass' do - before do - File.write( - 'Checks', - "check :donkey do\n" \ - "end\n" \ - "\n" \ - "deploy_check :donkey\n", - ) - end - - include_examples 'effective deploy' - end - end - - describe 'listing deployers' do - shared_examples 'lists all deployers' do - let(:run) { Nanoc::CLI.run(command) } - - it 'lists all deployers' do - expect { run }.to output(/Available deployers:\n fog\n git\n rsync/).to_stdout - end - - include_examples 'no effective deploy' - end - - context '--list-deployers' do - let(:command) { %w[deploy --list-deployers] } - include_examples 'lists all deployers' - end - - context '-D' do - let(:command) { %w[deploy -D] } - include_examples 'lists all deployers' - end - end - - describe 'listing deployment configurations' do - shared_examples 'lists all deployment configurations' do - let(:run) { Nanoc::CLI.run(command) } - - context 'no deployment configurations' do - let(:config) { { donkeys: 'lots' } } - - it 'says nothing is found' do - expect { run }.to output(/No deployment configurations./).to_stdout - end - - include_examples 'no effective deploy' - end - - context 'some deployment configurations' do - let(:config) do - { - deploy: { - production: { - kind: 'rsync', - dst: 'remote', - }, - staging: { - kind: 'rsync', - dst: 'remote', - }, - }, - } - end - - it 'says some targets are found' do - expect { run }.to output(/Available deployment configurations:\n production\n staging/).to_stdout - end - - include_examples 'no effective deploy' - end - end - - context '--list' do - let(:command) { %w[deploy --list] } - include_examples 'lists all deployment configurations' - end - - context '-L' do - let(:command) { %w[deploy -L] } - include_examples 'lists all deployment configurations' - end - end - - describe 'deploying' do - let(:run) { Nanoc::CLI.run(command) } - let(:command) { %w[deploy] } - - before do - FileUtils.mkdir_p('output') - FileUtils.mkdir_p('remote') - File.write('output/success.txt', 'hurrah') - end - - shared_examples 'missing kind warning' do - it 'warns about missing kind' do - expect { run }.to output(/Warning: The specified deploy target does not have a kind attribute. Assuming rsync./).to_stderr - end - end - - context 'no deploy configs' do - it 'errors' do - expect { run }.to raise_error( - Nanoc::Int::Errors::GenericTrivial, - 'The site has no deployment configurations.', - ) - end - - include_examples 'no effective deploy' - - context 'configuration created in preprocessor' do - before do - File.write( - 'Rules', - "preprocess do\n" \ - " @config[:deploy] = {\n" \ - " default: { dst: 'remote' },\n" \ - " }\n" \ - "end\n\n" + File.read('Rules'), - ) - end - - include_examples 'attempted/effective deploy' - end - end - - context 'some deploy configs' do - let(:config) do - { - deploy: { - irrelevant: { - kind: 'rsync', - dst: 'remote', - }, - }, - } - end - - context 'default target' do - context 'requested deploy config does not exist' do - it 'errors' do - expect { run }.to raise_error( - Nanoc::Int::Errors::GenericTrivial, - 'The site has no deployment configuration named `default`.', - ) - end - - include_examples 'no effective deploy' - end - - context 'requested deploy config exists' do - let(:config) do - { - deploy: { - default: { - kind: 'rsync', - dst: 'remote', - }, - }, - } - end - - include_examples 'attempted/effective deploy' - - context 'dry run' do - let(:command) { super() + ['--dry-run'] } - include_examples 'no effective deploy' - end - end - - context 'requested deploy config exists, but has no kind' do - let(:config) do - { - deploy: { - default: { - dst: 'remote', - }, - }, - } - end - - include_examples 'attempted/effective deploy' - include_examples 'missing kind warning' - - context 'dry run' do - let(:command) { super() + ['--dry-run'] } - include_examples 'no effective deploy' - end - end - end - - shared_examples 'deploy with non-default target' do - context 'requested deploy config does not exist' do - it 'errors' do - expect { run }.to raise_error( - Nanoc::Int::Errors::GenericTrivial, - 'The site has no deployment configuration named `production`.', - ) - end - - include_examples 'no effective deploy' - end - - context 'requested deploy config exists' do - let(:config) do - { - deploy: { - production: { - kind: 'rsync', - dst: 'remote', - }, - }, - } - end - - include_examples 'attempted/effective deploy' - - context 'dry run' do - let(:command) { (super() + ['--dry-run']) } - include_examples 'no effective deploy' - end - end - - context 'requested deploy config exists, but has no kind' do - let(:config) do - { - deploy: { - production: { - dst: 'remote', - }, - }, - } - end - - include_examples 'attempted/effective deploy' - include_examples 'missing kind warning' - - context 'dry run' do - let(:command) { (super() + ['--dry-run']) } - include_examples 'no effective deploy' - end - end - end - - context 'non-default target, specified as argument' do - let(:command) { %w[deploy production] } - include_examples 'deploy with non-default target' - end - - context 'non-default target, specified as option (--target)' do - let(:command) { %w[deploy --target production] } - include_examples 'deploy with non-default target' - end - - context 'multiple targets specified' do - let(:command) { %w[deploy --target staging production] } - - it 'errors' do - expect { run }.to raise_error( - Nanoc::Int::Errors::GenericTrivial, - 'Only one deployment target can be specified on the command line.', - ) - end - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/shell_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/shell_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/shell_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/shell_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::Commands::Shell, site: true, stdio: true do - describe '#run' do - before do - # Prevent double-loading - expect(Nanoc::CLI).to receive(:setup) - - File.write('content/hello.md', 'Hello!') - - File.write('Rules', <<~EOS) - preprocess do - @items['/hello.*'].raw_content = 'Better hello!' - end - - compile '/**/*' do - end - EOS - end - - it 'can be invoked' do - expect_any_instance_of(Nanoc::Int::Context).to receive(:pry) do |ctx| - expect(ctx.items.size).to eq(1) - expect(ctx.items.to_a[0]._unwrap.content.string).to eq('Hello!') - end - - Nanoc::CLI.run(['shell']) - end - - it 'can be invoked as sh' do - expect_any_instance_of(Nanoc::Int::Context).to receive(:pry) do |ctx| - expect(ctx.items.size).to eq(1) - expect(ctx.items.to_a[0]._unwrap.content.string).to eq('Hello!') - end - - Nanoc::CLI.run(['sh']) - end - - it 'can be invoked as console' do - expect_any_instance_of(Nanoc::Int::Context).to receive(:pry) do |ctx| - expect(ctx.items.size).to eq(1) - expect(ctx.items.to_a[0]._unwrap.content.string).to eq('Hello!') - end - - Nanoc::CLI.run(['console']) - end - - it 'will preprocess if requested' do - expect_any_instance_of(Nanoc::Int::Context).to receive(:pry) do |ctx| - expect(ctx.items.size).to eq(1) - expect(ctx.items.to_a[0]._unwrap.content.string).to eq('Better hello!') - end - - Nanoc::CLI.run(['shell', '--preprocess']) - end - end - - describe '#env_for_site' do - subject { described_class.env_for_site(site) } - - before do - File.write('content/hello.md', 'Hello!') - File.write('layouts/default.erb', 'MY SITE!<%= yield %>') - end - - let(:site) do - Nanoc::Int::SiteLoader.new.new_from_cwd - end - - it 'returns views' do - expect(subject[:items]).to be_a(Nanoc::ItemCollectionWithRepsView) - expect(subject[:layouts]).to be_a(Nanoc::LayoutCollectionView) - expect(subject[:config]).to be_a(Nanoc::ConfigView) - end - - it 'returns correct items' do - expect(subject[:items].size).to eq(1) - expect(subject[:items].first.identifier.to_s).to eq('/hello.md') - end - - it 'returns correct layouts' do - expect(subject[:layouts].size).to eq(1) - expect(subject[:layouts].first.identifier.to_s).to eq('/default.erb') - end - - it 'returns items with reps' do - expect(subject[:items].first.reps).not_to be_nil - expect(subject[:items].first.reps.first.name).to eq(:default) - end - - it 'returns items with rep paths' do - expect(subject[:items].first.reps.first.path).to eq('/hello.md') - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/show_data_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/show_data_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/show_data_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/show_data_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,317 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::Commands::ShowData, stdio: true do - describe '#print_item_dependencies' do - subject { runner.send(:print_item_dependencies, items, dependency_store) } - - let(:runner) do - described_class.new(options, arguments, command) - end - - let(:options) { {} } - let(:arguments) { [] } - let(:command) { double(:command) } - - let(:items) do - Nanoc::Int::ItemCollection.new( - config, - [ - item_about, - item_dog, - item_other, - ], - ) - end - - let(:item_about) { Nanoc::Int::Item.new('About Me', {}, '/about.md') } - let(:item_dog) { Nanoc::Int::Item.new('About My Dog', {}, '/dog.md') } - let(:item_other) { Nanoc::Int::Item.new('Raw Data', {}, '/other.dat') } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - let(:dependency_store) do - Nanoc::Int::DependencyStore.new(items, layouts, config) - end - - let(:layouts) do - Nanoc::Int::LayoutCollection.new(config) - end - - it 'prints a legend' do - expect { subject }.to output(%r{Item dependencies =+\n\nLegend:}).to_stdout - end - - context 'no dependencies' do - it 'outputs no dependencies for /about.md' do - expect { subject }.to output(%r{^item /about.md depends on:\n \(nothing\)$}m).to_stdout - end - - it 'outputs no dependencies for /dog.md' do - expect { subject }.to output(%r{^item /dog.md depends on:\n \(nothing\)$}m).to_stdout - end - - it 'outputs no dependencies for /other.dat' do - expect { subject }.to output(%r{^item /other.dat depends on:\n \(nothing\)$}m).to_stdout - end - end - - context 'dependency (without props) from config to dog' do - before do - dependency_store.record_dependency(item_dog, config) - end - - it 'outputs no dependencies for /about.md' do - expect { subject }.to output(%r{^item /about.md depends on:\n \(nothing\)$}m).to_stdout - end - - it 'outputs dependencies for /dog.md' do - expect { subject }.to output(%r{^item /dog.md depends on:\n \[ config \] \(racp\) $}m).to_stdout - end - - it 'outputs no dependencies for /other.dat' do - expect { subject }.to output(%r{^item /other.dat depends on:\n \(nothing\)$}m).to_stdout - end - end - - context 'dependency (without props) from about to dog' do - before do - dependency_store.record_dependency(item_dog, item_about) - end - - it 'outputs no dependencies for /about.md' do - expect { subject }.to output(%r{^item /about.md depends on:\n \(nothing\)$}m).to_stdout - end - - it 'outputs dependencies for /dog.md' do - expect { subject }.to output(%r{^item /dog.md depends on:\n \[ item \] \(racp\) /about.md$}m).to_stdout - end - - it 'outputs no dependencies for /other.dat' do - expect { subject }.to output(%r{^item /other.dat depends on:\n \(nothing\)$}m).to_stdout - end - end - - context 'dependency (with raw_content prop) from about to dog' do - before do - dependency_store.record_dependency(item_dog, item_about, raw_content: true) - end - - it 'outputs dependencies for /dog.md' do - expect { subject }.to output(%r{^item /dog.md depends on:\n \[ item \] \(r___\) /about.md$}m).to_stdout - end - end - - context 'dependency (with attributes prop) from about to dog' do - before do - dependency_store.record_dependency(item_dog, item_about, attributes: true) - end - - it 'outputs dependencies for /dog.md' do - expect { subject }.to output(%r{^item /dog.md depends on:\n \[ item \] \(_a__\) /about.md$}m).to_stdout - end - end - - context 'dependency (with attributes prop) from config to dog' do - before do - dependency_store.record_dependency(item_dog, config, attributes: true) - end - - it 'outputs dependencies for /dog.md' do - expect { subject }.to output(%r{^item /dog.md depends on:\n \[ config \] \(_a__\) $}m).to_stdout - end - end - - context 'dependency (with compiled_content prop) from about to dog' do - before do - dependency_store.record_dependency(item_dog, item_about, compiled_content: true) - end - - it 'outputs dependencies for /dog.md' do - expect { subject }.to output(%r{^item /dog.md depends on:\n \[ item \] \(__c_\) /about.md$}m).to_stdout - end - end - - context 'dependency (with path prop) from about to dog' do - before do - dependency_store.record_dependency(item_dog, item_about, path: true) - end - - it 'outputs dependencies for /dog.md' do - expect { subject }.to output(%r{^item /dog.md depends on:\n \[ item \] \(___p\) /about.md$}m).to_stdout - end - end - - context 'dependency (with multiple props) from about to dog' do - before do - dependency_store.record_dependency(item_dog, item_about, attributes: true, raw_content: true) - end - - it 'outputs dependencies for /dog.md' do - expect { subject }.to output(%r{^item /dog.md depends on:\n \[ item \] \(ra__\) /about.md$}m).to_stdout - end - end - - context 'dependency onto all items' do - before do - dependency_store.record_dependency(item_dog, items, raw_content: true) - end - - it 'outputs dependencies for /dog.md' do - expect { subject }.to output(%r{^item /dog.md depends on:\n \[ items \] \(r___\) matching any$}m).to_stdout - end - end - - context 'dependency onto one specific item' do - before do - dependency_store.record_dependency(item_dog, items, raw_content: ['/about.*']) - end - - it 'outputs dependencies for /dog.md' do - expect { subject }.to output(%r{^item /dog.md depends on:\n \[ items \] \(r___\) matching any of /about\.\*$}m).to_stdout - end - end - - context 'dependency onto multiple specific items' do - before do - dependency_store.record_dependency(item_dog, items, raw_content: ['/about.*']) - dependency_store.record_dependency(item_dog, items, raw_content: ['/giraffe.*']) - end - - it 'outputs dependencies for /dog.md' do - expect { subject }.to output(%r{^item /dog.md depends on:\n \[ items \] \(r___\) matching any of /about\.\*, /giraffe\.\*$}m).to_stdout - end - end - end - - describe '#print_item_rep_outdatedness' do - subject { runner.send(:print_item_rep_outdatedness, items, outdatedness_checker, reps) } - - let(:runner) do - described_class.new(options, arguments, command) - end - - let(:options) { {} } - let(:arguments) { [] } - let(:command) { double(:command) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd) } - - let(:items) do - Nanoc::Int::ItemCollection.new( - config, - [ - item_about, - item_dog, - ], - ) - end - - let(:item_about) { Nanoc::Int::Item.new('About Me', {}, '/about.md') } - let(:item_dog) { Nanoc::Int::Item.new('About My Dog', {}, '/dog.md') } - - let(:item_rep_about) { Nanoc::Int::ItemRep.new(item_about, :default) } - let(:item_rep_dog) { Nanoc::Int::ItemRep.new(item_dog, :default) } - - let(:site) { double(:site) } - let(:outdatedness_checker) { double(:outdatedness_checker) } - - let(:reps) do - { - item_about => [item_rep_about], - item_dog => [item_rep_dog], - } - end - - context 'not outdated' do - before do - allow(outdatedness_checker).to receive(:outdatedness_reasons_for).with(item_rep_about).and_return([]) - allow(outdatedness_checker).to receive(:outdatedness_reasons_for).with(item_rep_dog).and_return([]) - end - - example do - expect { subject }.to output(%r{^item /about.md, rep default:\n is not outdated$}).to_stdout - end - - example do - expect { subject }.to output(%r{^item /dog.md, rep default:\n is not outdated$}).to_stdout - end - end - - context 'outdated' do - before do - reasons_about = - [ - Nanoc::Int::OutdatednessReasons::ContentModified, - Nanoc::Int::OutdatednessReasons::AttributesModified.new([:title]), - ] - - reasons_dog = - [Nanoc::Int::OutdatednessReasons::DependenciesOutdated] - - allow(outdatedness_checker).to receive(:outdatedness_reasons_for) - .with(item_rep_about).and_return(reasons_about) - - allow(outdatedness_checker).to receive(:outdatedness_reasons_for) - .with(item_rep_dog).and_return(reasons_dog) - end - - example do - expect { subject }.to output(%r{^item /about.md, rep default:\n is outdated:\n - The content of this item has been modified since the last time the site was compiled.\n - The attributes of this item have been modified since the last time the site was compiled.$}).to_stdout - end - - example do - expect { subject }.to output(%r{^item /dog.md, rep default:\n is outdated:\n - This item uses content or attributes that have changed since the last time the site was compiled.$}).to_stdout - end - end - end - - describe '#print_layouts' do - subject { runner.send(:print_layouts, layouts, outdatedness_checker) } - - let(:runner) do - described_class.new(options, arguments, command) - end - - let(:options) { {} } - let(:arguments) { [] } - let(:command) { double(:command) } - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd) } - - let(:layouts) do - Nanoc::Int::LayoutCollection.new(config, [layout]) - end - - let(:layout) { Nanoc::Int::Layout.new('stuff', {}, '/default.erb') } - - let(:site) { double(:site) } - let(:outdatedness_checker) { double(:outdatedness_checker) } - - context 'not outdated' do - before do - allow(outdatedness_checker).to receive(:outdatedness_reasons_for).with(layout).and_return([]) - end - - example do - expect { subject }.to output(%r{^layout /default.erb:\n is not outdated$}).to_stdout - end - end - - context 'outdated' do - before do - reasons = - [ - Nanoc::Int::OutdatednessReasons::ContentModified, - Nanoc::Int::OutdatednessReasons::AttributesModified.new([:title]), - ] - - allow(outdatedness_checker).to receive(:outdatedness_reasons_for) - .with(layout).and_return(reasons) - end - - example do - expect { subject }.to output(%r{^layout /default.erb:\n is outdated:\n - The content of this item has been modified since the last time the site was compiled.\n - The attributes of this item have been modified since the last time the site was compiled.$}).to_stdout - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/show_plugins_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/show_plugins_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/show_plugins_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/show_plugins_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::Commands::ShowPlugins, site: true, stdio: true do - describe '#run' do - it 'can be invoked' do - Nanoc::CLI.run(['show-plugins']) - end - - context 'site with plugins' do - before do - File.write('lib/default.rb', 'Nanoc::Filter.define(:show_plugins_x) {}') - end - - it 'outputs show_plugins_x under the right section' do - expect { Nanoc::CLI.run(['show-plugins']) } - .to output(/ custom:\n show_plugins_x/).to_stdout - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/show_rules_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/show_rules_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/show_rules_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/show_rules_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,119 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::Commands::ShowRules, stdio: true, site: true do - describe '#run' do - subject { runner.run } - - let(:runner) do - described_class.new(options, arguments, command) - end - - let(:options) { {} } - - let(:arguments) { [] } - - let(:command) { double(:command) } - - let(:site) do - double( - :site, - items: items, - layouts: layouts, - compiler: compiler, - config: config, - ) - end - - let(:items) do - Nanoc::Int::ItemCollection.new( - config, - [ - Nanoc::Int::Item.new('About Me', {}, '/about.md'), - Nanoc::Int::Item.new('About My Dog', {}, '/dog.md'), - Nanoc::Int::Item.new('Raw Data', {}, '/other.dat'), - ], - ) - end - - let(:reps) do - Nanoc::Int::ItemRepRepo.new.tap do |reps| - reps << Nanoc::Int::ItemRep.new(items['/about.md'], :default) - reps << Nanoc::Int::ItemRep.new(items['/about.md'], :text) - reps << Nanoc::Int::ItemRep.new(items['/dog.md'], :default) - reps << Nanoc::Int::ItemRep.new(items['/dog.md'], :text) - reps << Nanoc::Int::ItemRep.new(items['/other.dat'], :default) - end - end - - let(:layouts) do - Nanoc::Int::LayoutCollection.new( - config, - [ - Nanoc::Int::Layout.new('Default', {}, '/default.erb'), - Nanoc::Int::Layout.new('Article', {}, '/article.haml'), - Nanoc::Int::Layout.new('Other', {}, '/other.xyzzy'), - ], - ) - end - - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - - let(:action_provider) { double(:action_provider, rules_collection: rules_collection) } - let(:compiler) { double(:compiler) } - - let(:rules_collection) do - Nanoc::RuleDSL::RulesCollection.new.tap do |rc| - rc.add_item_compilation_rule( - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/dog.*'), :default, proc {}), - ) - rc.add_item_compilation_rule( - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/*.md'), :default, proc {}), - ) - rc.add_item_compilation_rule( - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/**/*'), :text, proc {}), - ) - - rc.layout_filter_mapping[Nanoc::Int::Pattern.from('/*.haml')] = [:haml, {}] - rc.layout_filter_mapping[Nanoc::Int::Pattern.from('/*.erb')] = [:erb, {}] - end - end - - let(:expected_out) do - <<-EOS - \e[1m\e[33mItem /about.md\e[0m: - Rep default: /*.md - Rep text: /**/* - - \e[1m\e[33mItem /dog.md\e[0m: - Rep default: /dog.* - Rep text: /**/* - - \e[1m\e[33mItem /other.dat\e[0m: - Rep default: (none) - - \e[1m\e[33mLayout /article.haml\e[0m: - /*.haml - - \e[1m\e[33mLayout /default.erb\e[0m: - /*.erb - - \e[1m\e[33mLayout /other.xyzzy\e[0m: - (none) - - EOS - .gsub(/^ {8}/, '') - end - - it 'writes item and layout rules to stdout' do - expect(runner).to receive(:load_site).and_return(site) - expect(Nanoc::Int::Compiler).to receive(:new_for).with(site).and_return(compiler) - expect(compiler).to receive(:run_until_reps_built).and_return(reps: reps) - expect(Nanoc::RuleDSL::ActionProvider).to receive(:for).with(site).and_return(action_provider) - expect { subject }.to output(expected_out).to_stdout - end - - it 'writes status information to stderr' do - expect { subject }.to output("Loading site… done\n").to_stderr - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/view_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/view_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/commands/view_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/commands/view_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ -# frozen_string_literal: true - -require 'net/http' - -describe Nanoc::CLI::Commands::View, site: true, stdio: true, fork: true do - describe '#run' do - def run_nanoc_cmd(cmd) - pid = fork { Nanoc::CLI.run(cmd) } - - # Wait for server to start up - 20.times do |i| - begin - Net::HTTP.get('127.0.0.1', '/', 50_385) - break - rescue Errno::ECONNREFUSED, Errno::ECONNRESET - sleep(0.1 * 1.1**i) - next - end - - raise 'Server did not start up in time' - end - - yield - ensure - Process.kill('TERM', pid) - end - - context 'default configuration' do - it 'serves /index.html as /' do - File.write('output/index.html', 'Hello there! Nanoc loves you! <3') - run_nanoc_cmd(['view', '--port', '50385']) do - expect(Net::HTTP.get('127.0.0.1', '/', 50_385)).to eql('Hello there! Nanoc loves you! <3') - end - end - - it 'does not serve /index.xhtml as /' do - File.write('output/index.xhtml', 'Hello there! Nanoc loves you! <3') - run_nanoc_cmd(['view', '--port', '50385']) do - expect(Net::HTTP.get('127.0.0.1', '/', 50_385)).to eql("File not found: /\n") - end - end - end - - context 'index_filenames including index.xhtml' do - before do - File.write('nanoc.yaml', 'index_filenames: [index.xhtml]') - end - - it 'serves /index.xhtml as /' do - File.write('output/index.xhtml', 'Hello there! Nanoc loves you! <3') - run_nanoc_cmd(['view', '--port', '50385']) do - expect(Net::HTTP.get('127.0.0.1', '/', 50_385)).to eql('Hello there! Nanoc loves you! <3') - end - end - end - - it 'does not serve other files as /' do - File.write('output/index.html666', 'Hello there! Nanoc loves you! <3') - run_nanoc_cmd(['view', '--port', '50385']) do - expect(Net::HTTP.get('127.0.0.1', '/', 50_385)).to eql("File not found: /\n") - end - end - - it 'does not crash when output dir does not exist and --live-reload is given' do - FileUtils.rm_rf('output') - run_nanoc_cmd(['view', '--port', '50385', '--live-reload']) do - expect(Net::HTTP.get('127.0.0.1', '/', 50_385)).to eql("File not found: /\n") - end - end - - it 'does not listen on non-local interfaces' do - addresses = Socket.getifaddrs.map(&:addr).select(&:ipv4?).map(&:ip_address) - non_local_addresses = addresses - ['127.0.0.1'] - - if non_local_addresses.empty? - skip 'Need non-local network interfaces for this spec' - end - - run_nanoc_cmd(['view', '--port', '50385']) do - expect { Net::HTTP.get(non_local_addresses[0], '/', 50_385) }.to raise_error(Errno::ECONNREFUSED) - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/error_handler_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/error_handler_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/error_handler_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/error_handler_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,191 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::ErrorHandler, stdio: true do - subject(:error_handler) { described_class.new } - - describe '#forwards_stack_trace?' do - subject { error_handler.forwards_stack_trace? } - - context 'Ruby 2.4' do - before do - expect(error_handler).to receive(:ruby_version).and_return('2.4.2') - end - - it { is_expected.to be(false) } - end - - context 'Ruby 2.5' do - before do - expect(error_handler).to receive(:ruby_version).and_return('2.5.0') - end - - it { is_expected.to be(true) } - end - end - - describe '#trivial?' do - subject { error_handler.trivial?(error) } - - context 'LoadError of known gem' do - let(:error) do - begin - raise LoadError, 'cannot load such file -- nokogiri' - rescue LoadError => e - return e - end - end - - it { is_expected.to be(true) } - end - - context 'LoadError of unknown gem' do - let(:error) do - begin - raise LoadError, 'cannot load such file -- whatever' - rescue LoadError => e - return e - end - end - - it { is_expected.to be(false) } - end - - context 'random error' do - let(:error) do - begin - raise 'stuff' - rescue => e - return e - end - end - - it { is_expected.to be(false) } - end - - context 'Errno::EADDRINUSE' do - let(:error) do - begin - raise Errno::EADDRINUSE - rescue => e - return e - end - end - - it { is_expected.to be(true) } - end - - context 'GenericTrivial' do - let(:error) do - begin - raise Nanoc::Int::Errors::GenericTrivial, 'oh just a tiny thing' - rescue => e - return e - end - end - - it { is_expected.to be(true) } - end - end - - describe '#handle_error' do - subject { error_handler.handle_error(error, exit_on_error: exit_on_error) } - - let(:error) do - begin - raise 'Bewm' - rescue => e - return e - end - end - - let(:exit_on_error) { false } - - describe 'exit behavior' do - context 'exit on error' do - let(:exit_on_error) { true } - - it 'exits on error' do - expect { subject }.to raise_error(SystemExit) - end - end - - context 'no exit on error' do - let(:exit_on_error) { false } - - it 'does not exit on error' do - expect { subject }.not_to raise_error - end - end - end - - describe 'printing behavior' do - context 'trivial error with no resolution' do - let(:error) do - begin - raise Nanoc::Int::Errors::GenericTrivial, 'asdf' - rescue => e - return e - end - end - - it 'prints summary' do - expect { subject }.to output("\nError: asdf\n").to_stderr - end - end - - context 'LoadError' do - let(:error) do - begin - raise LoadError, 'cannot load such file -- nokogiri' - rescue LoadError => e - return e - end - end - - it 'prints summary' do - expected_output = "\n" + <<~OUT - Error: cannot load such file -- nokogiri - - 1. Add `gem 'nokogiri'` to your Gemfile - 2. Run `bundle install` - 3. Re-run this command - OUT - expect { subject }.to output(expected_output).to_stderr - end - end - - context 'non-trivial error' do - # … - end - end - end - - describe '#write_error_message' do - subject { error_handler.send(:write_error_message, $stdout, error, verbose: true) } - - let(:error) do - begin - Nanoc::Int::Configuration.new(dir: '/oink', hash: { enable_output_diff: 'yeah' }) - rescue => e - return e - end - end - - example do - expect { subject }.to output("\n===== MESSAGE:\n\nJsonSchema::AggregateError: \n * #/enable_output_diff: For 'properties/enable_output_diff', \"yeah\" is not a boolean.\n").to_stdout - end - end - - describe 'GEM_NAMES' do - example do - requires = Nanoc::Filter.all.flat_map(&:requires) - described = - Nanoc::CLI::ErrorHandler::GEM_NAMES.keys + - ['erb', 'rdoc', 'nanoc/filters/sass/importer', 'nanoc/filters/sass/functions'] - - missing = requires - described - - expect(missing).to be_empty - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/stack_trace_writer_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/stack_trace_writer_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/stack_trace_writer_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/stack_trace_writer_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::StackTraceWriter do - subject(:writer) do - described_class.new(io, forwards: forwards) - end - - let(:io) { StringIO.new } - let(:forwards) { true } - - describe '#write' do - let(:exception) do - backtrace_generator = lambda do |af| - if af.zero? - raise 'finally!' - else - backtrace_generator.call(af - 1) - end - end - - begin - backtrace_generator.call(3) - rescue => e - return e - end - end - - subject { writer.write(exception, verbose: verbose) } - - let(:verbose) { false } - - context 'backwards' do - let(:forwards) { false } - - context 'verbose' do - let(:verbose) { true } - - it 'starts with zero' do - expect { subject } - .to change { io.string } - .from('') - .to(start_with(' 0. ')) - end - - it 'has more recent stack frames at the top' do - expect { subject } - .to change { io.string } - .from('') - .to(match(%r{^ 0\. (C:)?/.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d+.*$\n 1\. (C:)?/.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d}m)) - end - - it 'has more than 10 stack frames' do - expect { subject } - .to change { io.string } - .from('') - .to(match(%r{^ 11\. })) - end - - it 'does not contain a see-more explanation' do - subject - expect(io.string).not_to match(/crash\.log/) - end - end - - context 'not verbose' do - let(:verbose) { false } - - it 'starts with zero' do - expect { subject } - .to change { io.string } - .from('') - .to(start_with(' 0. ')) - end - - it 'has more recent stack frames at the top' do - expect { subject } - .to change { io.string } - .from('') - .to(match(%r{^ 0\. (C:)?/.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d+.*$\n 1\. (C:)?/.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d}m)) - end - - it 'has not more than 10 stack frames' do - subject - expect(io.string).not_to match(/^ 11\. /) - end - - it 'does not contain a see-more explanation' do - subject - expect(io.string).to include(" lines omitted (see crash.log for details)\n") - end - end - end - - context 'forwards' do - let(:forwards) { true } - - context 'verbose' do - let(:verbose) { true } - - it 'ends with most recent line' do - expect { subject } - .to change { io.string } - .from('') - .to(match(%r{^ 1\. from (C:)?/.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d+.*$\n (C:)?/.+/spec/nanoc/cli}m)) - end - - it 'has more recent stack frames at the bottom' do - expect { subject } - .to change { io.string } - .from('') - .to(match(%r{^ 2\. from (C:)?/.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d+.*$\n 1\. from (C:)?/.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d}m)) - end - - it 'has more than 10 stack frames' do - expect { subject } - .to change { io.string } - .from('') - .to(match(%r{^ 11\. from })) - end - - it 'does not contain a see-more explanation' do - subject - expect(io.string).not_to match(/crash\.log/) - end - end - - context 'not verbose' do - let(:verbose) { false } - - it 'ends with most recent line' do - expect { subject } - .to change { io.string } - .from('') - .to(match(%r{^ 1\. from (C:)?/.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d+.*$\n (C:)?/.+/spec/nanoc/cli}m)) - end - - it 'has more recent stack frames at the top' do - expect { subject } - .to change { io.string } - .from('') - .to(match(%r{^ 2\. from (C:)?/.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d+.*$\n 1\. from (C:)?/.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d}m)) - end - - it 'has not more than 10 stack frames' do - subject - expect(io.string).not_to match(/^ 11\. from /) - end - - it 'does not contain a see-more explanation' do - subject - expect(io.string).to include(" lines omitted (see crash.log for details)\n") - end - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli/stream_cleaners/utf8_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli/stream_cleaners/utf8_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli/stream_cleaners/utf8_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli/stream_cleaners/utf8_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI::StreamCleaners::UTF8 do - subject { described_class.new } - - it 'handles all cases' do - expect(subject.clean('┼─ “© Denis” ‘and others…’ ─┼')).to eq('+- "(c) Denis" \'and others...\' -+') - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/cli_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/cli_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/cli_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/cli_spec.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -# frozen_string_literal: true - -describe Nanoc::CLI do - let(:all_commands) do - ObjectSpace.each_object(Cri::Command) - end - - let(:exceptions) do - # FIXME: [Nanoc 5] Get rid of these exceptions - [ - ['deploy', ['C']], - ['help', ['v']], - ['check', ['d']], - ] - end - - def ancestors_of_command(command) - if command.is_a?(Cri::Command) - [command] + ancestors_of_command(command.supercommand) - else - [] - end - end - - def short_options_for_command(command) - ancestors = ancestors_of_command(command) - ancestors.flat_map { |a| a.option_definitions.to_a.map(&:short) }.compact - end - - it 'has no commands that have conflicting options' do - all_commands.each do |command| - short_options = short_options_for_command(command) - - duplicate_options = short_options.select { |o| short_options.count(o) > 1 }.uniq - - next if exceptions.include?([command.name, duplicate_options]) - - expect(duplicate_options).to( - be_empty, - "The #{command.name} command’s option shorthands #{duplicate_options.uniq} are used by multiple options", - ) - end - end - - describe '#enable_ansi_colors?' do - subject { described_class.enable_ansi_colors?(io) } - - context 'TTY' do - let(:io) { double(:io, tty?: true) } - - context 'NO_COLOR set' do - before do - allow(ENV).to receive(:key?).with('NO_COLOR').and_return(true) - end - - it { is_expected.to be(false) } - end - - context 'NO_COLOR not set' do - it { is_expected.to be(true) } - end - end - - context 'no TTY' do - let(:io) { double(:io, tty?: false) } - - context 'NO_COLOR set' do - before do - allow(ENV).to receive(:key?).with('NO_COLOR').and_return(true) - end - - it { is_expected.to be(false) } - end - - context 'NO_COLOR not set' do - it { is_expected.to be(false) } - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/data_sources/filesystem/parser_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/data_sources/filesystem/parser_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/data_sources/filesystem/parser_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/data_sources/filesystem/parser_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -4,7 +4,7 @@ subject(:parser) { described_class.new(config: config) } let(:config) do - Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults + Nanoc::Core::Configuration.new(dir: Dir.getwd).with_defaults end describe '#call' do @@ -14,7 +14,7 @@ let(:meta_filename) { nil } context 'only meta file' do - let(:meta_filename) { Tempfile.open('test') { |fn| fn << 'asdf' }.path } + let(:meta_filename) { 'test_meta.txt' } before do File.write(meta_filename, meta) @@ -79,7 +79,7 @@ end context 'only content file' do - let(:content_filename) { Tempfile.open('test') { |fn| fn << 'asdf' }.path } + let(:content_filename) { 'test_content.txt' } before do File.write(content_filename, content) @@ -301,8 +301,8 @@ end context 'meta and content file' do - let(:content_filename) { Tempfile.open('test') { |fn| fn << 'asdf' }.path } - let(:meta_filename) { Tempfile.open('test') { |fn| fn << 'asdf' }.path } + let(:content_filename) { 'test_content.txt' } + let(:meta_filename) { 'test_meta.txt' } before do File.write(content_filename, content) diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/data_sources/filesystem_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/data_sources/filesystem_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/data_sources/filesystem_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/data_sources/filesystem_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,11 +1,12 @@ # frozen_string_literal: true describe Nanoc::DataSources::Filesystem, site: true do - let(:data_source) { Nanoc::DataSources::Filesystem.new(site.config, nil, nil, params) } + let(:data_source) { described_class.new(site.config, nil, nil, params) } let(:params) { {} } - let(:site) { Nanoc::Int::SiteLoader.new.new_from_cwd } + let(:site) { Nanoc::Core::SiteLoader.new.new_from_cwd } before { Timecop.freeze(now) } + after { Timecop.return } let(:now) { Time.local(2008, 1, 2, 14, 5, 0) } @@ -16,7 +17,7 @@ let(:klass) { raise 'override me' } context 'items' do - let(:klass) { Nanoc::Int::Item } + let(:klass) { Nanoc::Core::Item } context 'no files' do it 'loads nothing' do @@ -47,7 +48,7 @@ expect(subject[0].content.string).to eq('test 1') expect(subject[0].attributes).to eq(expected_attributes) - expect(subject[0].identifier).to eq(Nanoc::Identifier.new('/bar/', type: :legacy)) + expect(subject[0].identifier).to eq(Nanoc::Core::Identifier.new('/bar/', type: :legacy)) expect(subject[0].checksum_data).to be_nil expect(subject[0].attributes_checksum_data).to be_a(String) expect(subject[0].attributes_checksum_data.size).to eq(20) @@ -98,9 +99,9 @@ it 'loads that file' do expect(subject.size).to eq(1) - expect(subject[0].content).to be_a(Nanoc::Int::BinaryContent) + expect(subject[0].content).to be_a(Nanoc::Core::BinaryContent) expect(subject[0].attributes).to eq(expected_attributes) - expect(subject[0].identifier).to eq(Nanoc::Identifier.new('/bar/', type: :legacy)) + expect(subject[0].identifier).to eq(Nanoc::Core::Identifier.new('/bar/', type: :legacy)) expect(subject[0].checksum_data).to be_nil expect(subject[0].attributes_checksum_data).to be_a(String) expect(subject[0].attributes_checksum_data.size).to eq(20) @@ -125,7 +126,7 @@ expect { subject } .to raise_error( Nanoc::Int::Errors::AmbiguousMetadataAssociation, - 'There are multiple content files (foo/a.txt, foo/a.md) that could match the file containing metadata (foo/a.yaml).', + 'There are multiple content files (foo/a.md, foo/a.txt) that could match the file containing metadata (foo/a.yaml).', ) end end @@ -145,12 +146,12 @@ items = subject.sort_by { |i| i.identifier.to_s } - expect(items[0].content).to be_a(Nanoc::Int::TextualContent) - expect(items[0].identifier).to eq(Nanoc::Identifier.new('/a.md', type: :full)) + expect(items[0].content).to be_a(Nanoc::Core::TextualContent) + expect(items[0].identifier).to eq(Nanoc::Core::Identifier.new('/a.md', type: :full)) expect(items[0].attributes[:title]).to eq('Aaah') - expect(items[1].content).to be_a(Nanoc::Int::TextualContent) - expect(items[1].identifier).to eq(Nanoc::Identifier.new('/a.txt', type: :full)) + expect(items[1].content).to be_a(Nanoc::Core::TextualContent) + expect(items[1].identifier).to eq(Nanoc::Core::Identifier.new('/a.txt', type: :full)) expect(items[1].attributes[:title]).to eq('Hi') end end @@ -169,7 +170,7 @@ expect { subject } .to raise_error( Nanoc::Int::Errors::AmbiguousMetadataAssociation, - 'There are multiple content files (foo/a.txt, foo/a.md) that could match the file containing metadata (foo/a.yaml).', + 'There are multiple content files (foo/a.md, foo/a.txt) that could match the file containing metadata (foo/a.yaml).', ) end end @@ -188,12 +189,12 @@ items = subject.sort_by { |i| i.identifier.to_s } - expect(items[0].content).to be_a(Nanoc::Int::TextualContent) - expect(items[0].identifier).to eq(Nanoc::Identifier.new('/a.md', type: :full)) + expect(items[0].content).to be_a(Nanoc::Core::TextualContent) + expect(items[0].identifier).to eq(Nanoc::Core::Identifier.new('/a.md', type: :full)) expect(items[0].attributes[:title]).to eq('Ho') - expect(items[1].content).to be_a(Nanoc::Int::TextualContent) - expect(items[1].identifier).to eq(Nanoc::Identifier.new('/a.txt', type: :full)) + expect(items[1].content).to be_a(Nanoc::Core::TextualContent) + expect(items[1].identifier).to eq(Nanoc::Core::Identifier.new('/a.txt', type: :full)) expect(items[1].attributes[:title]).to eq('Hi') end end @@ -212,12 +213,12 @@ items = subject.sort_by { |i| i.identifier.to_s } - expect(items[0].content).to be_a(Nanoc::Int::TextualContent) - expect(items[0].identifier).to eq(Nanoc::Identifier.new('/a.md', type: :full)) + expect(items[0].content).to be_a(Nanoc::Core::TextualContent) + expect(items[0].identifier).to eq(Nanoc::Core::Identifier.new('/a.md', type: :full)) expect(items[0].attributes[:title]).to be_nil - expect(items[1].content).to be_a(Nanoc::Int::TextualContent) - expect(items[1].identifier).to eq(Nanoc::Identifier.new('/a.txt', type: :full)) + expect(items[1].content).to be_a(Nanoc::Core::TextualContent) + expect(items[1].identifier).to eq(Nanoc::Core::Identifier.new('/a.txt', type: :full)) expect(items[1].attributes[:title]).to be_nil end end @@ -234,9 +235,9 @@ it 'uses only metadata from meta file' do expect(subject.size).to eq(1) - expect(subject[0].content).to be_a(Nanoc::Int::TextualContent) + expect(subject[0].content).to be_a(Nanoc::Core::TextualContent) expect(subject[0].content.string).to eq("---\ntitle: Hi\n---\n\nhi") - expect(subject[0].identifier).to eq(Nanoc::Identifier.new('/a.txt', type: :full)) + expect(subject[0].identifier).to eq(Nanoc::Core::Identifier.new('/a.txt', type: :full)) expect(subject[0].attributes[:title]).to be_nil expect(subject[0].attributes[:author]).to eq('Denis') end @@ -248,7 +249,7 @@ subject { data_source.item_changes } before do - if Nanoc.on_windows? + if Nanoc::Core.on_windows? skip 'nanoc-live is not currently supported on Windows' end end @@ -277,7 +278,7 @@ subject { data_source.layout_changes } before do - if Nanoc.on_windows? + if Nanoc::Core.on_windows? skip 'nanoc-live is not currently supported on Windows' end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/deploying/fog_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/deploying/fog_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/deploying/fog_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/deploying/fog_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,8 +1,10 @@ # frozen_string_literal: true describe Nanoc::Deploying::Deployers::Fog, stdio: true do + subject { deployer.run } + let(:deployer) do - Nanoc::Deploying::Deployers::Fog.new( + described_class.new( 'output/', config, dry_run: is_dry_run, @@ -30,8 +32,6 @@ FileUtils.mkdir_p('remote') end - subject { deployer.run } - shared_examples 'no effective deploy' do it 'does not modify remote' do expect { subject }.not_to change { Dir['remote/**/*'].sort } diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/deploying/git_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/deploying/git_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/deploying/git_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/deploying/git_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,10 +1,10 @@ # frozen_string_literal: true describe Nanoc::Deploying::Deployers::Git, stdio: true do - let(:deployer) { described_class.new(output_dir, options, dry_run: dry_run) } - subject { deployer.run } + let(:deployer) { described_class.new(output_dir, options, dry_run: dry_run) } + let(:output_dir) { 'output/' } let(:options) { remote_options.merge(branch_options).merge(forced_options) } let(:dry_run) { false } @@ -14,11 +14,7 @@ let(:forced_options) { {} } def run_and_get_stdout(*args) - stdout = +'' - stderr = +'' - piper = Nanoc::Extra::Piper.new(stdout: stdout, stderr: stderr) - piper.run(args, '') - stdout + TTY::Command.new.run(*args).out end def add_changes_to_remote @@ -103,6 +99,7 @@ context 'remote has other changes' do before { add_changes_to_remote } + include_examples 'successful push' end end @@ -118,7 +115,7 @@ before { add_changes_to_remote } it 'raises' do - expect { subject }.to raise_error(Nanoc::Extra::Piper::Error) + expect { subject }.to raise_error(TTY::Command::ExitError) end end end @@ -134,7 +131,7 @@ before { add_changes_to_remote } it 'raises' do - expect { subject }.to raise_error(Nanoc::Extra::Piper::Error) + expect { subject }.to raise_error(TTY::Command::ExitError) end end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/filters/asciidoc_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/filters/asciidoc_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/filters/asciidoc_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/filters/asciidoc_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,12 +1,12 @@ # frozen_string_literal: true describe Nanoc::Filters::AsciiDoc do + subject { described_class.new } + before do skip_unless_have_command 'asciidoc' end - subject { described_class.new } - example do expect(subject.setup_and_run('== Blah blah')) .to match(%r{

Blah blah

}) diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/filters/colorize_syntax/rouge_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/filters/colorize_syntax/rouge_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/filters/colorize_syntax/rouge_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/filters/colorize_syntax/rouge_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -4,6 +4,7 @@ describe Nanoc::Filters::ColorizeSyntax, filter: true do subject { filter.setup_and_run(input, default_colorizer: :rouge, rouge: params) } + let(:filter) { ::Nanoc::Filters::ColorizeSyntax.new } let(:params) { {} } let(:wrap) { false } @@ -63,7 +64,8 @@ 2
  def foo
-              end
+ end + after EOS @@ -142,7 +144,8 @@ 2
  def foo
-              end
+ end + after EOS diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/filters/erb_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/filters/erb_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/filters/erb_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/filters/erb_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -80,14 +80,14 @@ end context 'error' do - let(:filter) { described_class.new(layout: layout) } - - let(:layout) { Nanoc::Int::Layout.new('asdf', {}, '/default.erb') } - subject do filter.setup_and_run('<% raise "boom %>') end + let(:filter) { described_class.new(layout: layout) } + + let(:layout) { Nanoc::Core::Layout.new('asdf', {}, '/default.erb') } + example do error = begin @@ -101,14 +101,14 @@ end context 'with trim mode' do - let(:filter) { described_class.new } - - let(:res) { { success: false } } - subject do filter.setup_and_run('% res[:success] = true', params) end + let(:filter) { described_class.new } + + let(:res) { { success: false } } + context 'trim mode unchanged' do let(:params) do { @@ -136,14 +136,14 @@ end context 'safe level' do - let(:filter) { described_class.new } - - let(:res) { { success: false } } - subject do filter.setup_and_run('<%= eval File.read("moo") %>', params) end + let(:filter) { described_class.new } + + let(:res) { { success: false } } + before do File.write('moo', '1+2') end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/filters/relativize_paths_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/filters/relativize_paths_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/filters/relativize_paths_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/filters/relativize_paths_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -8,11 +8,11 @@ end let(:item) do - Nanoc::Int::Item.new('contentz', {}, '/sub/page.html') + Nanoc::Core::Item.new('contentz', {}, '/sub/page.html') end let(:item_rep) do - Nanoc::Int::ItemRep.new(item, :default).tap do |rep| + Nanoc::Core::ItemRep.new(item, :default).tap do |rep| rep.paths = { last: ['/sub/page.html'] } end end @@ -30,105 +30,126 @@ context 'HTML' do let(:params) { { type: :html } } + it { is_expected.to eq('
Foo') } context 'full component excluded' do let(:params) { { type: :html, exclude: '/foo' } } + it { is_expected.to eq('Foo') } end context 'full component excluded as list' do let(:params) { { type: :html, exclude: ['/foo'] } } + it { is_expected.to eq('Foo') } end context 'partial component excluded' do let(:params) { { type: :html, exclude: ['/fo'] } } + it { is_expected.to eq('Foo') } end context 'non-root component excluded' do let(:params) { { type: :html, exclude: ['/bar'] } } + it { is_expected.to eq('Foo') } end context 'excluded with regexp' do let(:params) { { type: :html, exclude: /ar/ } } + it { is_expected.to eq('Foo') } end context 'excluded with regexp list' do let(:params) { { type: :html, exclude: [/ar/] } } + it { is_expected.to eq('Foo') } end end context 'HTML5' do let(:params) { { type: :html5 } } + it { is_expected.to eq('Foo') } context 'full component excluded' do let(:params) { { type: :html5, exclude: '/foo' } } + it { is_expected.to eq('Foo') } end context 'full component excluded as list' do let(:params) { { type: :html5, exclude: ['/foo'] } } + it { is_expected.to eq('Foo') } end context 'partial component excluded' do let(:params) { { type: :html5, exclude: ['/fo'] } } + it { is_expected.to eq('Foo') } end context 'non-root component excluded' do let(:params) { { type: :html5, exclude: ['/bar'] } } + it { is_expected.to eq('Foo') } end context 'excluded with regexp' do let(:params) { { type: :html5, exclude: /ar/ } } + it { is_expected.to eq('Foo') } end context 'excluded with regexp list' do let(:params) { { type: :html5, exclude: [/ar/] } } + it { is_expected.to eq('Foo') } end end context 'XHTML' do let(:params) { { type: :xhtml } } + it { is_expected.to eq('Foo') } context 'full component excluded' do let(:params) { { type: :xhtml, exclude: '/foo' } } + it { is_expected.to eq('Foo') } end context 'full component excluded as list' do let(:params) { { type: :xhtml, exclude: ['/foo'] } } + it { is_expected.to eq('Foo') } end context 'partial component excluded' do let(:params) { { type: :xhtml, exclude: ['/fo'] } } + it { is_expected.to eq('Foo') } end context 'non-root component excluded' do let(:params) { { type: :xhtml, exclude: ['/bar'] } } + it { is_expected.to eq('Foo') } end context 'excluded with regexp' do let(:params) { { type: :xhtml, exclude: /ar/ } } + it { is_expected.to eq('Foo') } end context 'excluded with regexp list' do let(:params) { { type: :xhtml, exclude: [/ar/] } } + it { is_expected.to eq('Foo') } end end @@ -144,31 +165,37 @@ context 'full component excluded' do let(:params) { { type: :css, exclude: '/foo' } } + it { is_expected.to eq('.oink { background: url(/foo/bar.png) }') } end context 'full component excluded as list' do let(:params) { { type: :css, exclude: ['/foo'] } } + it { is_expected.to eq('.oink { background: url(/foo/bar.png) }') } end context 'partial component excluded' do let(:params) { { type: :css, exclude: ['/fo'] } } + it { is_expected.to eq('.oink { background: url(../foo/bar.png) }') } end context 'non-root component excluded' do let(:params) { { type: :css, exclude: ['/bar'] } } + it { is_expected.to eq('.oink { background: url(../foo/bar.png) }') } end context 'excluded with regexp' do let(:params) { { type: :css, exclude: /ar/ } } + it { is_expected.to eq('.oink { background: url(/foo/bar.png) }') } end context 'excluded with regexp list' do let(:params) { { type: :css, exclude: [/ar/] } } + it { is_expected.to eq('.oink { background: url(/foo/bar.png) }') } end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/filters/sass_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/filters/sass_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/filters/sass_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/filters/sass_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -2,8 +2,11 @@ describe Nanoc::Filters::SassCommon do context 'with item, items, config context' do - subject(:sass) { ::Nanoc::Filter.named(:sass).new(sass_params) } - subject(:sass_sourcemap) { ::Nanoc::Filter.named(:sass_sourcemap).new(sass_sourcemap_params) } + subject(:sass_sourcemap) do + ::Nanoc::Filter.named(:sass_sourcemap).new(sass_sourcemap_params) + end + + let(:sass) { ::Nanoc::Filter.named(:sass).new(sass_params) } let(:sass_params) do { @@ -24,7 +27,7 @@ end let(:item_main) do - Nanoc::Int::Item.new( + Nanoc::Core::Item.new( content_main, { content_filename: 'content/style/main.sass' }, '/style/main.sass', @@ -32,14 +35,14 @@ end let(:content_main) do - Nanoc::Int::TextualContent.new( + Nanoc::Core::TextualContent.new( '/* irrelevant */', filename: File.expand_path('content/style/main.sass'), ) end let(:item_blue) do - Nanoc::Int::Item.new( + Nanoc::Core::Item.new( content_blue, { content_filename: 'content/style/colors/blue.sass' }, '/style/colors/blue.sass', @@ -47,14 +50,14 @@ end let(:content_blue) do - Nanoc::Int::TextualContent.new( + Nanoc::Core::TextualContent.new( "\.blue\n color: blue", filename: File.expand_path('content/style/colors/blue.sass'), ) end let(:item_red) do - Nanoc::Int::Item.new( + Nanoc::Core::Item.new( content_red, { content_filename: 'content/style/colors/red.scss' }, '/style/colors/red.scss', @@ -62,62 +65,103 @@ end let(:content_red) do - Nanoc::Int::TextualContent.new( + Nanoc::Core::TextualContent.new( '.red { color: red; }', filename: File.expand_path('content/style/colors/red.scss'), ) end - let(:item_partial) do - Nanoc::Int::Item.new( - content_partial, + let(:item_partial_scss) do + Nanoc::Core::Item.new( + content_partial_scss, { content_filename: 'content/style/_partial.scss' }, '/style/_partial.scss', ) end - let(:content_partial) do - Nanoc::Int::TextualContent.new( + let(:content_partial_scss) do + Nanoc::Core::TextualContent.new( '* { margin: 0; }', filename: File.expand_path('content/style/_partial.scss'), ) end + let(:item_partial_sass) do + Nanoc::Core::Item.new( + content_partial_sass, + { content_filename: 'content/style/_sass-partial.sass' }, + '/style/_sass-partial.sass', + ) + end + + let(:content_partial_sass) do + sass = <<~SASS + * + margin: 0 + SASS + + Nanoc::Core::TextualContent.new( + sass, + filename: File.expand_path('content/style/_sass-partial.sass'), + ) + end + + let(:item_partial_sass_anonymous) do + Nanoc::Core::Item.new( + content_partial_sass_anonymous, + { content_filename: 'content/style/_anonymous-sass-partial' }, + '/style/_anonymous-sass-partial', + ) + end + + let(:content_partial_sass_anonymous) do + sass = <<~SASS + * + margin: 0 + SASS + + Nanoc::Core::TextualContent.new( + sass, + filename: File.expand_path('content/style/_anonymous-sass-partial'), + ) + end + let(:item_main_default_rep) do - Nanoc::Int::ItemRep.new(item_main, :default).tap do |rep| + Nanoc::Core::ItemRep.new(item_main, :default).tap do |rep| rep.raw_paths = rep.paths = { last: [Dir.getwd + '/output/style/main.sass'] } end end let(:item_main_sourcemap_rep) do - Nanoc::Int::ItemRep.new(item_main, :sourcemap).tap do |rep| + Nanoc::Core::ItemRep.new(item_main, :sourcemap).tap do |rep| rep.raw_paths = rep.paths = { last: [Dir.getwd + '/output/style/main.sass.map'] } end end - let(:item_main_view) { Nanoc::CompilationItemView.new(item_main, view_context) } - let(:item_main_default_rep_view) { Nanoc::CompilationItemRepView.new(item_main_default_rep, view_context) } - let(:item_main_sourcemap_rep_view) { Nanoc::CompilationItemRepView.new(item_main_sourcemap_rep, view_context) } - - let(:items) { Nanoc::Int::ItemCollection.new(config, [item_main, item_blue, item_red, item_partial]) } - let(:item_views) { Nanoc::ItemCollectionWithRepsView.new(items, view_context) } + let(:item_main_view) { Nanoc::Core::CompilationItemView.new(item_main, view_context) } + let(:item_main_default_rep_view) { Nanoc::Core::CompilationItemRepView.new(item_main_default_rep, view_context) } + let(:item_main_sourcemap_rep_view) { Nanoc::Core::CompilationItemRepView.new(item_main_sourcemap_rep, view_context) } + + let(:items) { Nanoc::Core::ItemCollection.new(config, [item_main, item_blue, item_red, item_partial_scss, item_partial_sass, item_partial_sass_anonymous]) } + let(:layouts) { Nanoc::Core::LayoutCollection.new(config) } + let(:item_views) { Nanoc::Core::ItemCollectionWithRepsView.new(items, view_context) } let(:view_context) do - Nanoc::ViewContextForCompilation.new( + Nanoc::Core::ViewContextForCompilation.new( reps: reps, items: items, dependency_tracker: dependency_tracker, compilation_context: compilation_context, - snapshot_repo: snapshot_repo, + compiled_content_store: compiled_content_store, ) end let(:reps) do - Nanoc::Int::ItemRepRepo.new.tap do |reps| - [item_blue, item_red, item_partial].each do |item| - reps << Nanoc::Int::ItemRep.new(item, :default).tap do |rep| + Nanoc::Core::ItemRepRepo.new.tap do |reps| + [item_blue, item_red, item_partial_scss, item_partial_sass, item_partial_sass_anonymous].each do |item| + reps << Nanoc::Core::ItemRep.new(item, :default).tap do |rep| rep.compiled = true - rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(:last, binary: false)] + rep.snapshot_defs = [Nanoc::Core::SnapshotDef.new(:last, binary: false)] end end reps << item_main_default_rep @@ -125,22 +169,53 @@ end end - let(:dependency_tracker) { Nanoc::Int::DependencyTracker.new(dependency_store) } - let(:dependency_store) { Nanoc::Int::DependencyStore.new(empty_items, empty_layouts, config) } - let(:compilation_context) { double(:compilation_context) } + let(:dependency_tracker) { Nanoc::Core::DependencyTracker.new(dependency_store) } + let(:dependency_store) { Nanoc::Core::DependencyStore.new(empty_items, empty_layouts, config) } - let(:snapshot_repo) do - Nanoc::Int::SnapshotRepo.new.tap do |repo| - repo.set(reps[item_blue].first, :last, Nanoc::Int::TextualContent.new('.blue { color: blue }')) - repo.set(reps[item_red].first, :last, Nanoc::Int::TextualContent.new('.red { color: red }')) - repo.set(reps[item_partial].first, :last, Nanoc::Int::TextualContent.new('* { margin: 0 }')) + let(:compilation_context) do + Nanoc::Core::CompilationContext.new( + action_provider: action_provider, + reps: reps, + site: site, + compiled_content_cache: compiled_content_cache, + compiled_content_store: compiled_content_store, + ) + end + + let(:action_provider) do + Class.new(Nanoc::Core::ActionProvider) do + def self.for(_context) + raise NotImplementedError + end + + def initialize; end + end.new + end + + let(:compiled_content_cache) { Nanoc::Core::CompiledContentCache.new(config: config) } + + let(:compiled_content_store) do + Nanoc::Core::CompiledContentStore.new.tap do |repo| + repo.set(reps[item_blue].first, :last, content_blue) + repo.set(reps[item_red].first, :last, content_red) + repo.set(reps[item_partial_scss].first, :last, content_partial_scss) + repo.set(reps[item_partial_sass].first, :last, content_partial_sass) + repo.set(reps[item_partial_sass_anonymous].first, :last, content_partial_sass_anonymous) end end - let(:empty_items) { Nanoc::Int::ItemCollection.new(config) } - let(:empty_layouts) { Nanoc::Int::LayoutCollection.new(config) } + let(:site) do + Nanoc::Core::Site.new( + config: config, + code_snippets: [], + data_source: Nanoc::Core::InMemoryDataSource.new(items, layouts), + ) + end + + let(:empty_items) { Nanoc::Core::ItemCollection.new(config) } + let(:empty_layouts) { Nanoc::Core::LayoutCollection.new(config) } - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults.merge(color: 'yellow') } + let(:config) { Nanoc::Core::Configuration.new(dir: Dir.getwd).with_defaults.merge(color: 'yellow') } before do items.each do |item| @@ -164,6 +239,26 @@ .to match(/^\.foo #bar[\s]*\{[\s]*color:\s*(red|#f00);?[\s]*\}/m) end + it 'supports SASS' do + content = <<~SASS + .foo + color: #f00 + SASS + + expect(sass.setup_and_run(content, syntax: :sass)) + .to match(/^\.foo[\s]*\{[\s]*color:\s*(red|#f00);?[\s]*\}/m) + end + + it 'supports SASS as default syntax' do + content = <<~SASS + .foo + color: #f00 + SASS + + expect(sass.setup_and_run(content)) + .to match(/^\.foo[\s]*\{[\s]*color:\s*(red|#f00);?[\s]*\}/m) + end + it 'supports SCSS' do expect(sass.setup_and_run('.foo { color: #f00 }', syntax: :scss)) .to match(/^\.foo[\s]*\{[\s]*color:\s*(red|#f00);?[\s]*\}/m) @@ -203,29 +298,59 @@ .to raise_error(::Sass::SyntaxError, /File to import not found/) end - it 'can import partials by relative path' do + it 'can import SCSS partials by relative path' do expect(sass.setup_and_run('@import partial')) .to match(/\A\*\s*\{\s*margin:\s+0;\s*\}\s*\z/) end + it 'can import SASS partials by relative path' do + expect(sass.setup_and_run('@import sass-partial')) + .to match(/\A\*\s*\{\s*margin:\s+0;\s*\}\s*\z/) + end + + it 'cannot import anonymous SASS partials by relative path' do + expect { sass.setup_and_run('@import anonymous-sass-partial') } + .to raise_error(::Sass::SyntaxError, /File to import not found/) + end + it 'cannot import partials by nested relative path' do expect { sass.setup_and_run('@import content/style/_partial') } .to raise_error(::Sass::SyntaxError, /File to import not found/) end - it 'can import partials by relative path with extension' do + it 'can import partials by relative path with SCSS extension' do expect(sass.setup_and_run('@import partial.scss')) .to match(/\A\*\s*\{\s*margin:\s+0;\s*\}\s*\z/) end - it 'cannot import partials by nested relative path with extension' do + it 'can import partials by relative path with SASS extension' do + expect(sass.setup_and_run('@import sass-partial.sass')) + .to match(/\A\*\s*\{\s*margin:\s+0;\s*\}\s*\z/) + end + + it 'cannot import partials by relative path without extension' do + expect { sass.setup_and_run('@import anonymous-sass-partial') } + .to raise_error(::Sass::SyntaxError, /File to import not found/) + end + + it 'cannot import partials by nested relative path with SCSS extension' do expect { sass.setup_and_run('@import content/style/partial.scss') } .to raise_error(::Sass::SyntaxError, /File to import not found/) end + it 'cannot import partials by nested relative path with SASS extension' do + expect { sass.setup_and_run('@import content/style/sass-partial.sass') } + .to raise_error(::Sass::SyntaxError, /File to import not found/) + end + + it 'cannot import partials by nested relative path without extension' do + expect { sass.setup_and_run('@import content/style/anonymous-sass-partial') } + .to raise_error(::Sass::SyntaxError, /File to import not found/) + end + it 'creates a dependency' do expect { sass.setup_and_run('@import partial') } - .to create_dependency_on(item_views[item_partial.identifier]) + .to create_dependency_on(item_views[item_partial_scss.identifier]) end end @@ -240,7 +365,7 @@ it 'creates no dependency' do expect { sass.setup_and_run('@import external', load_paths: ['.']) } - .to create_dependency_from(item_main_view).onto([instance_of(Nanoc::Int::ItemCollection)]) + .to create_dependency_from(item_main_view).onto([instance_of(Nanoc::Core::ItemCollection)]) end end @@ -258,13 +383,21 @@ end context 'importing by identifier or pattern' do - it 'can import by identifier' do - expect(sass.setup_and_run('@import /style/colors/blue.*')) + it 'can import SASS by identifier' do + expect(sass.setup_and_run('@import /style/colors/blue.sass')) .to match(/\A\.blue\s+\{\s*color:\s+blue;?\s*\}\s*\z/) - expect(sass.setup_and_run('@import /style/colors/red.*')) + end + + it 'can import SCSS by identifier' do + expect(sass.setup_and_run('@import /style/colors/red.scss')) .to match(/\A\.red\s+\{\s*color:\s+red;?\s*\}\s*\z/) end + it 'can import SASS by identifier without extension' do + expect(sass.setup_and_run('@import /style/_anonymous-sass-partial')) + .to match(/\A\*\s+\{\s*margin:\s+0;?\s*\}\s*\z/) + end + it 'can import by pattern' do expect(sass.setup_and_run('@import /style/colors/*')) .to match(/\A\.blue\s+\{\s*color:\s+blue;?\s*\}\s*\.red\s+\{\s*color:\s+red;?\s*\}\s*\z/) diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/helpers/blogging_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/helpers/blogging_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/helpers/blogging_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/helpers/blogging_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -146,21 +146,25 @@ context 'with Time instance' do let(:arg) { around_noon_utc } + it { is_expected.to eql(around_noon_utc) } end context 'with Date instance' do let(:arg) { Date.new(2015, 11, 7) } + it { is_expected.to eql(beginning_of_day_utc) } end context 'with DateTime instance' do - let(:arg) { DateTime.new(2015, 11, 7, 13, 31, 16) } # rubocop:disable Style/DateTime + let(:arg) { DateTime.new(2015, 11, 7, 13, 31, 16) } + it { is_expected.to eql(around_noon_utc) } end context 'with string' do let(:arg) { '2015-11-7 13:31:16' } + it { is_expected.to eql(around_noon_local) } end end @@ -181,21 +185,25 @@ context 'item with path' do let(:item_rep_path) { '/stuff.xml' } + it { is_expected.to eql('tag:url.base,2015-05-19:/stuff.xml') } end context 'item without path' do let(:item_rep_path) { nil } + it { is_expected.to eql('tag:url.base,2015-05-19:/stuff') } end context 'bare URL without subdir' do let(:base_url) { 'http://url.base' } + it { is_expected.to eql('tag:url.base,2015-05-19:/stuff.xml') } end context 'bare URL with subdir' do let(:base_url) { 'http://url.base/sub' } + it { is_expected.to eql('tag:url.base,2015-05-19:/sub/stuff.xml') } end @@ -203,6 +211,7 @@ let(:item_attributes) do { created_at: Date.parse('2015-05-19 12:34:56') } end + it { is_expected.to eql('tag:url.base,2015-05-19:/stuff.xml') } end @@ -210,6 +219,7 @@ let(:item_attributes) do { created_at: Time.parse('2015-05-19 12:34:56') } end + it { is_expected.to eql('tag:url.base,2015-05-19:/stuff.xml') } end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/helpers/breadcrumbs_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/helpers/breadcrumbs_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/helpers/breadcrumbs_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/helpers/breadcrumbs_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -12,7 +12,7 @@ context 'legacy identifiers' do context 'root' do before do - ctx.create_item('root', {}, Nanoc::Identifier.new('/', type: :legacy)) + ctx.create_item('root', {}, Nanoc::Core::Identifier.new('/', type: :legacy)) ctx.item = ctx.items['/'] end @@ -24,8 +24,8 @@ context 'root and direct child' do before do - ctx.create_item('child', {}, Nanoc::Identifier.new('/foo/', type: :legacy)) - ctx.create_item('root', {}, Nanoc::Identifier.new('/', type: :legacy)) + ctx.create_item('child', {}, Nanoc::Core::Identifier.new('/foo/', type: :legacy)) + ctx.create_item('root', {}, Nanoc::Core::Identifier.new('/', type: :legacy)) ctx.item = ctx.items['/foo/'] end @@ -37,9 +37,9 @@ context 'root, child and grandchild' do before do - ctx.create_item('grandchild', {}, Nanoc::Identifier.new('/foo/bar/', type: :legacy)) - ctx.create_item('child', {}, Nanoc::Identifier.new('/foo/', type: :legacy)) - ctx.create_item('root', {}, Nanoc::Identifier.new('/', type: :legacy)) + ctx.create_item('grandchild', {}, Nanoc::Core::Identifier.new('/foo/bar/', type: :legacy)) + ctx.create_item('child', {}, Nanoc::Core::Identifier.new('/foo/', type: :legacy)) + ctx.create_item('root', {}, Nanoc::Core::Identifier.new('/', type: :legacy)) ctx.item = ctx.items['/foo/bar/'] end @@ -51,8 +51,8 @@ context 'root, missing child and grandchild' do before do - ctx.create_item('grandchild', {}, Nanoc::Identifier.new('/foo/bar/', type: :legacy)) - ctx.create_item('root', {}, Nanoc::Identifier.new('/', type: :legacy)) + ctx.create_item('grandchild', {}, Nanoc::Core::Identifier.new('/foo/bar/', type: :legacy)) + ctx.create_item('root', {}, Nanoc::Core::Identifier.new('/', type: :legacy)) ctx.item = ctx.items['/foo/bar/'] end @@ -66,7 +66,7 @@ context 'non-legacy identifiers' do context 'root' do before do - ctx.create_item('root', {}, Nanoc::Identifier.new('/index.md')) + ctx.create_item('root', {}, Nanoc::Core::Identifier.new('/index.md')) ctx.item = ctx.items['/index.md'] end @@ -78,8 +78,8 @@ context 'root and direct child' do before do - ctx.create_item('child', {}, Nanoc::Identifier.new('/foo.md')) - ctx.create_item('root', {}, Nanoc::Identifier.new('/index.md')) + ctx.create_item('child', {}, Nanoc::Core::Identifier.new('/foo.md')) + ctx.create_item('root', {}, Nanoc::Core::Identifier.new('/index.md')) ctx.item = ctx.items['/foo.md'] end @@ -91,9 +91,9 @@ context 'root, child and grandchild' do before do - ctx.create_item('grandchild', {}, Nanoc::Identifier.new('/foo/bar.md')) - ctx.create_item('child', {}, Nanoc::Identifier.new('/foo.md')) - ctx.create_item('root', {}, Nanoc::Identifier.new('/index.md')) + ctx.create_item('grandchild', {}, Nanoc::Core::Identifier.new('/foo/bar.md')) + ctx.create_item('child', {}, Nanoc::Core::Identifier.new('/foo.md')) + ctx.create_item('root', {}, Nanoc::Core::Identifier.new('/index.md')) ctx.item = ctx.items['/foo/bar.md'] end @@ -105,8 +105,8 @@ context 'root, missing child and grandchild' do before do - ctx.create_item('grandchild', {}, Nanoc::Identifier.new('/foo/bar.md')) - ctx.create_item('root', {}, Nanoc::Identifier.new('/index.md')) + ctx.create_item('grandchild', {}, Nanoc::Core::Identifier.new('/foo/bar.md')) + ctx.create_item('root', {}, Nanoc::Core::Identifier.new('/index.md')) ctx.item = ctx.items['/foo/bar.md'] end @@ -120,8 +120,8 @@ # No special handling of non-root index.* files. before do - ctx.create_item('grandchild', {}, Nanoc::Identifier.new('/foo/index.md')) - ctx.create_item('root', {}, Nanoc::Identifier.new('/index.md')) + ctx.create_item('grandchild', {}, Nanoc::Core::Identifier.new('/foo/index.md')) + ctx.create_item('root', {}, Nanoc::Core::Identifier.new('/index.md')) ctx.item = ctx.items['/foo/index.md'] end @@ -133,11 +133,11 @@ context 'item with version number component in path' do before do - ctx.create_item('grandchild', {}, Nanoc::Identifier.new('/1.5/stuff.md')) - ctx.create_item('child0', {}, Nanoc::Identifier.new('/1.4.md')) - ctx.create_item('child1', {}, Nanoc::Identifier.new('/1.5.md')) - ctx.create_item('child2', {}, Nanoc::Identifier.new('/1.6.md')) - ctx.create_item('root', {}, Nanoc::Identifier.new('/index.md')) + ctx.create_item('grandchild', {}, Nanoc::Core::Identifier.new('/1.5/stuff.md')) + ctx.create_item('child0', {}, Nanoc::Core::Identifier.new('/1.4.md')) + ctx.create_item('child1', {}, Nanoc::Core::Identifier.new('/1.5.md')) + ctx.create_item('child2', {}, Nanoc::Core::Identifier.new('/1.6.md')) + ctx.create_item('root', {}, Nanoc::Core::Identifier.new('/index.md')) ctx.item = ctx.items['/1.5/stuff.md'] end @@ -156,11 +156,11 @@ context 'item with multiple extensions in path' do before do - ctx.create_item('grandchild', {}, Nanoc::Identifier.new('/foo/stuff.md')) - ctx.create_item('child0', {}, Nanoc::Identifier.new('/foo.md.erb')) - ctx.create_item('child1', {}, Nanoc::Identifier.new('/foo.md')) - ctx.create_item('child2', {}, Nanoc::Identifier.new('/foo.erb')) - ctx.create_item('root', {}, Nanoc::Identifier.new('/index.md')) + ctx.create_item('grandchild', {}, Nanoc::Core::Identifier.new('/foo/stuff.md')) + ctx.create_item('child0', {}, Nanoc::Core::Identifier.new('/foo.md.erb')) + ctx.create_item('child1', {}, Nanoc::Core::Identifier.new('/foo.md')) + ctx.create_item('child2', {}, Nanoc::Core::Identifier.new('/foo.erb')) + ctx.create_item('root', {}, Nanoc::Core::Identifier.new('/index.md')) ctx.item = ctx.items['/foo/stuff.md'] end @@ -235,11 +235,11 @@ context 'child with multiple extensions' do before do - ctx.create_item('grandchild1', {}, Nanoc::Identifier.new('/foo/stuff.zip')) - ctx.create_item('grandchild2', {}, Nanoc::Identifier.new('/foo/stuff.md')) - ctx.create_item('grandchild3', {}, Nanoc::Identifier.new('/foo/stuff.png')) - ctx.create_item('child', {}, Nanoc::Identifier.new('/foo.md')) - ctx.create_item('root', {}, Nanoc::Identifier.new('/index.md')) + ctx.create_item('grandchild1', {}, Nanoc::Core::Identifier.new('/foo/stuff.zip')) + ctx.create_item('grandchild2', {}, Nanoc::Core::Identifier.new('/foo/stuff.md')) + ctx.create_item('grandchild3', {}, Nanoc::Core::Identifier.new('/foo/stuff.png')) + ctx.create_item('child', {}, Nanoc::Core::Identifier.new('/foo.md')) + ctx.create_item('root', {}, Nanoc::Core::Identifier.new('/index.md')) ctx.item = ctx.items['/foo/stuff.md'] end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/helpers/capturing_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/helpers/capturing_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/helpers/capturing_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/helpers/capturing_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -21,12 +21,13 @@ it 'stores snapshot content' do subject - expect(ctx.snapshot_repo.get(ctx.item.reps[:default]._unwrap, :__capture_foo).string).to eql('foo') + expect(ctx.compiled_content_store.get(ctx.item.reps[:default]._unwrap, :__capture_foo).string).to eql('foo') end end context 'name and params given' do subject { subject_proc_with_params.call } + let(:params) { raise 'overwrite me' } context 'no existing behavior specified' do @@ -44,7 +45,7 @@ it 'overwrites' do subject_proc_with_params.call subject_proc_with_params.call - expect(ctx.snapshot_repo.get(ctx.item.reps[:default]._unwrap, :__capture_foo).string).to eql('bar') + expect(ctx.compiled_content_store.get(ctx.item.reps[:default]._unwrap, :__capture_foo).string).to eql('bar') end end @@ -54,7 +55,7 @@ it 'appends' do subject_proc_with_params.call subject_proc_with_params.call - expect(ctx.snapshot_repo.get(ctx.item.reps[:default]._unwrap, :__capture_foo).string).to eql('foobar') + expect(ctx.compiled_content_store.get(ctx.item.reps[:default]._unwrap, :__capture_foo).string).to eql('foobar') end end @@ -165,13 +166,13 @@ expect(ctx.dependency_tracker).to receive(:bounce).with(item._unwrap, compiled_content: true).twice fiber = Fiber.new { subject } - expect(fiber.resume).to be_a(Nanoc::Int::Errors::UnmetDependency) + expect(fiber.resume).to be_a(Nanoc::Core::Errors::UnmetDependency) item.reps[:default]._unwrap.compiled = true - ctx.snapshot_repo.set( + ctx.compiled_content_store.set( item.reps[:default]._unwrap, :__capture_foo, - Nanoc::Int::TextualContent.new('content after compilation'), + Nanoc::Core::TextualContent.new('content after compilation'), ) expect(fiber.resume).to eql('content after compilation') end @@ -180,10 +181,10 @@ context 'other item is compiled' do before do item.reps[:default]._unwrap.compiled = true - ctx.snapshot_repo.set( + ctx.compiled_content_store.set( item.reps[:default]._unwrap, :__capture_foo, - Nanoc::Int::TextualContent.new('other captured foo'), + Nanoc::Core::TextualContent.new('other captured foo'), ) end @@ -198,10 +199,10 @@ describe '#capture' do context 'with string' do - let(:_erbout) { +'existing content' } - subject { helper.capture { _erbout << 'new content' } } + let(:_erbout) { +'existing content' } + it 'returns the appended content' do expect(subject).to eql('new content') end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/helpers/child_parent_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/helpers/child_parent_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/helpers/child_parent_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/helpers/child_parent_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -5,15 +5,16 @@ subject { helper.children_of(item) } before { ctx.create_item('some content', {}, identifier) } + let(:item) { ctx.items[identifier] } context 'legacy identifier' do - let(:identifier) { Nanoc::Identifier.new('/foo/', type: :legacy) } + let(:identifier) { Nanoc::Core::Identifier.new('/foo/', type: :legacy) } before do - ctx.create_item('abc', {}, Nanoc::Identifier.new('/foo/a/', type: :legacy)) - ctx.create_item('def', {}, Nanoc::Identifier.new('/foo/a/b/', type: :legacy)) - ctx.create_item('xyz', {}, Nanoc::Identifier.new('/bar/', type: :legacy)) + ctx.create_item('abc', {}, Nanoc::Core::Identifier.new('/foo/a/', type: :legacy)) + ctx.create_item('def', {}, Nanoc::Core::Identifier.new('/foo/a/b/', type: :legacy)) + ctx.create_item('xyz', {}, Nanoc::Core::Identifier.new('/bar/', type: :legacy)) end it 'returns only direct children' do @@ -22,13 +23,13 @@ end context 'full identifier' do - let(:identifier) { Nanoc::Identifier.new('/foo.md', type: :full) } + let(:identifier) { Nanoc::Core::Identifier.new('/foo.md', type: :full) } before do - ctx.create_item('abc', {}, Nanoc::Identifier.new('/foo/a.md', type: :full)) - ctx.create_item('def', {}, Nanoc::Identifier.new('/foo/a/b.md', type: :full)) - ctx.create_item('xyz', {}, Nanoc::Identifier.new('/bar.md', type: :full)) - ctx.create_item('xyz', {}, Nanoc::Identifier.new('/foo/a/index.md', type: :full)) + ctx.create_item('abc', {}, Nanoc::Core::Identifier.new('/foo/a.md', type: :full)) + ctx.create_item('def', {}, Nanoc::Core::Identifier.new('/foo/a/b.md', type: :full)) + ctx.create_item('xyz', {}, Nanoc::Core::Identifier.new('/bar.md', type: :full)) + ctx.create_item('xyz', {}, Nanoc::Core::Identifier.new('/foo/a/index.md', type: :full)) end it 'returns only direct children' do @@ -41,16 +42,17 @@ subject { helper.parent_of(item) } before { ctx.create_item('some content', {}, identifier) } + let(:item) { ctx.items[identifier] } context 'legacy identifier' do - let(:identifier) { Nanoc::Identifier.new('/foo/bar/', type: :legacy) } + let(:identifier) { Nanoc::Core::Identifier.new('/foo/bar/', type: :legacy) } before do - ctx.create_item('abc', {}, Nanoc::Identifier.new('/foo/', type: :legacy)) - ctx.create_item('def', {}, Nanoc::Identifier.new('/foo/qux/', type: :legacy)) - ctx.create_item('xyz', {}, Nanoc::Identifier.new('/foo/bar/asdf/', type: :legacy)) - ctx.create_item('opq', {}, Nanoc::Identifier.new('/', type: :legacy)) + ctx.create_item('abc', {}, Nanoc::Core::Identifier.new('/foo/', type: :legacy)) + ctx.create_item('def', {}, Nanoc::Core::Identifier.new('/foo/qux/', type: :legacy)) + ctx.create_item('xyz', {}, Nanoc::Core::Identifier.new('/foo/bar/asdf/', type: :legacy)) + ctx.create_item('opq', {}, Nanoc::Core::Identifier.new('/', type: :legacy)) end it 'returns parent' do @@ -59,13 +61,13 @@ end context 'full identifier' do - let(:identifier) { Nanoc::Identifier.new('/foo/bar.md', type: :full) } + let(:identifier) { Nanoc::Core::Identifier.new('/foo/bar.md', type: :full) } before do - ctx.create_item('abc', {}, Nanoc::Identifier.new('/foo.md', type: :full)) - ctx.create_item('def', {}, Nanoc::Identifier.new('/foo/qux.md', type: :full)) - ctx.create_item('xyz', {}, Nanoc::Identifier.new('/foo/bar/asdf.md', type: :full)) - ctx.create_item('opq', {}, Nanoc::Identifier.new('/index.md', type: :full)) + ctx.create_item('abc', {}, Nanoc::Core::Identifier.new('/foo.md', type: :full)) + ctx.create_item('def', {}, Nanoc::Core::Identifier.new('/foo/qux.md', type: :full)) + ctx.create_item('xyz', {}, Nanoc::Core::Identifier.new('/foo/bar/asdf.md', type: :full)) + ctx.create_item('opq', {}, Nanoc::Core::Identifier.new('/index.md', type: :full)) end it 'returns parent' do diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/helpers/filtering_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/helpers/filtering_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/helpers/filtering_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/helpers/filtering_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -2,6 +2,8 @@ describe Nanoc::Helpers::Filtering, helper: true do describe '#filter' do + subject { ::ERB.new(content).result(helper.get_binding) } + before do ctx.create_item('some content', { title: 'Hello!' }, '/about.md') ctx.create_rep(ctx.items['/about.md'], '/about.html') @@ -14,20 +16,15 @@ "A<% filter :erb do %><%%= 'X' %><% end %>B" end - subject { ::ERB.new(content).result(helper.get_binding) } - context 'basic case' do it { is_expected.to eql('AXB') } - it 'notifies' do - ns = Set.new - Nanoc::Int::NotificationCenter.on(:filtering_started) { ns << :filtering_started } - Nanoc::Int::NotificationCenter.on(:filtering_ended) { ns << :filtering_ended } - - subject + it 'notifies filtering_started' do + expect { subject }.to send_notification(:filtering_started, ctx.item_rep._unwrap, :erb) + end - expect(ns).to include(:filtering_started) - expect(ns).to include(:filtering_ended) + it 'notifies filtering_ended' do + expect { subject }.to send_notification(:filtering_ended, ctx.item_rep._unwrap, :erb) end end @@ -45,7 +42,7 @@ end it 'errors' do - expect { subject }.to raise_error(Nanoc::Int::Errors::UnknownFilter) + expect { subject }.to raise_error(Nanoc::Filter::UnknownFilterError) end end @@ -58,6 +55,8 @@ end context 'with Haml' do + subject { ::Haml::Engine.new(content).render(helper.get_binding) } + let(:content) do "%p Foo.\n" \ "- filter(:erb) do\n" \ @@ -69,8 +68,6 @@ require 'haml' end - subject { ::Haml::Engine.new(content).render(helper.get_binding) } - it { is_expected.to match(%r{^

Foo.

\s*abcxyz\s*

Bar.

$}) } end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/helpers/html_escape_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/helpers/html_escape_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/helpers/html_escape_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/helpers/html_escape_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -6,6 +6,7 @@ context 'given strings to escape' do let(:string) { '< > & "' } + it { is_expected.to eql('< > & "') } end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/helpers/link_to_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/helpers/link_to_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/helpers/link_to_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/helpers/link_to_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -10,26 +10,31 @@ context 'with string path' do let(:target) { '/foo/' } + it { is_expected.to eql('Text') } context 'with attributes' do let(:attributes) { { title: 'Donkey' } } + it { is_expected.to eql('Text') } end context 'special HTML characters in text' do let(:text) { 'Foo & Bar' } + it { is_expected.to eql('Foo & Bar') } # Not escaped! end context 'special HTML characters in URL' do let(:target) { '/r&d/' } + it { is_expected.to eql('Text') } end context 'special HTML characters in attribute' do let(:attributes) { { title: 'Research & Development' } } + it { is_expected.to eql('Text') } end end @@ -145,6 +150,7 @@ context 'current' do let(:target) { ctx.item_rep } + it { is_expected.to eql('Text') } end @@ -161,6 +167,7 @@ context 'item rep present, but not current' do let(:target) { some_item_rep } + it { is_expected.to eql('Text') } end end @@ -182,6 +189,7 @@ context 'current' do let(:target) { ctx.item } + it { is_expected.to eql('Text') } end @@ -198,6 +206,7 @@ context 'item rep present, but not current' do let(:target) { some_item } + it { is_expected.to eql('Text') } end end @@ -229,21 +238,25 @@ context 'to path without trailing slash' do let(:target) { '/bar/target.html' } + it { is_expected.to eql('../bar/target.html') } end context 'to path with trailing slash' do let(:target) { '/bar/target/' } + it { is_expected.to eql('../bar/target/') } end context 'to Windows/UNC path (forward slashes)' do let(:target) { '//foo' } + it { is_expected.to eql('//foo') } end context 'to Windows/UNC path (backslashes)' do let(:target) { '\\\\foo' } + it { is_expected.to eql('\\\\foo') } end end @@ -266,6 +279,7 @@ context 'self is a directory' do let(:self_path) { '/foo/self/' } + it { is_expected.to eql('./') } end end @@ -290,6 +304,7 @@ context 'self is a directory' do let(:self_path) { '/foo/self/' } + it { is_expected.to eql('./') } end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/helpers/rendering_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/helpers/rendering_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/helpers/rendering_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/helpers/rendering_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -5,7 +5,7 @@ subject { helper.instance_eval { render('/partial.erb') } } let(:action_sequence_for_layout) do - [Nanoc::Int::ProcessingActions::Filter.new(:erb, {})] + [Nanoc::Core::ProcessingActions::Filter.new(:erb, {})] end let(:layout_view) { ctx.layouts[layout_identifier] } @@ -17,7 +17,7 @@ end context 'legacy identifier' do - let(:layout_identifier) { Nanoc::Identifier.new('/partial/', type: :legacy) } + let(:layout_identifier) { Nanoc::Core::Identifier.new('/partial/', type: :legacy) } context 'cleaned identifier' do subject { helper.instance_eval { render('/partial/') } } @@ -29,7 +29,7 @@ it 'tracks proper dependencies' do expect(ctx.dependency_tracker).to receive(:enter) - .with(an_instance_of(Nanoc::Int::LayoutCollection), raw_content: ['/partial/'], attributes: false, compiled_content: false, path: false) + .with(an_instance_of(Nanoc::Core::LayoutCollection), raw_content: ['/partial/'], attributes: false, compiled_content: false, path: false) .ordered expect(ctx.dependency_tracker).to receive(:enter) .with(layout, raw_content: true, attributes: false, compiled_content: false, path: false) @@ -41,6 +41,7 @@ context 'layout with instructions' do let(:layout_content) { 'blah <%= @layout.identifier %>' } + it { is_expected.to eql('blah /partial/') } end end @@ -50,37 +51,43 @@ context 'layout without instructions' do let(:layout_content) { 'blah' } + it { is_expected.to eql('blah') } end context 'layout with instructions' do let(:layout_content) { 'blah <%= @layout.identifier %>' } + it { is_expected.to eql('blah /partial/') } end end end context 'full-style identifier' do - let(:layout_identifier) { Nanoc::Identifier.new('/partial.erb') } + let(:layout_identifier) { Nanoc::Core::Identifier.new('/partial.erb') } context 'layout without instructions' do let(:layout_content) { 'blah' } + it { is_expected.to eql('blah') } end context 'layout with instructions' do let(:layout_content) { 'blah <%= @layout.identifier %>' } + it { is_expected.to eql('blah /partial.erb') } end context 'printing wrapped layout class' do let(:layout_content) { 'blah <%= @layout.class %>' } - it { is_expected.to eql('blah Nanoc::LayoutView') } + + it { is_expected.to eql('blah Nanoc::Core::LayoutView') } end context 'printing unwrapped layout class' do let(:layout_content) { 'blah <%= @layout._unwrap.class %>' } - it { is_expected.to eql('blah Nanoc::Int::Layout') } + + it { is_expected.to eql('blah Nanoc::Core::Layout') } end context 'unknown layout' do @@ -95,19 +102,19 @@ context 'layout with unknown filter' do let(:action_sequence_for_layout) do - [Nanoc::Int::ProcessingActions::Filter.new(:donkey, {})] + [Nanoc::Core::ProcessingActions::Filter.new(:donkey, {})] end let(:layout_content) { 'blah' } it 'raises' do - expect { subject }.to raise_error(Nanoc::Int::Errors::UnknownFilter) + expect { subject }.to raise_error(Nanoc::Filter::UnknownFilterError) end end context 'layout without filter' do let(:action_sequence_for_layout) do - [Nanoc::Int::ProcessingActions::Filter.new(nil, {})] + [Nanoc::Core::ProcessingActions::Filter.new(nil, {})] end let(:layout_content) { 'blah' } diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/helpers/tagging_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/helpers/tagging_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/helpers/tagging_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/helpers/tagging_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -14,22 +14,26 @@ context 'no tags' do let(:item_attributes) { {} } + it { is_expected.to eql('(none)') } end context 'nil tag list' do let(:item_attributes) { { tags: nil } } + it { is_expected.to eql('(none)') } end context 'empty tag list' do let(:item_attributes) { { tags: [] } } + it { is_expected.to eql('(none)') } end context 'no tags, and custom none text' do let(:item_attributes) { {} } let(:params) { { none_text: 'no tags for you, fool' } } + it { is_expected.to eql('no tags for you, fool') } end @@ -42,27 +46,32 @@ context 'explicit nil base_url' do let(:params) { { base_url: nil } } + it { is_expected.to eql('donkey') } end context 'explicit other base_url' do - let(:params) { { base_url: 'http://nanoc.ws/tag/' } } - it { is_expected.to eql('') } + let(:params) { { base_url: 'https://nanoc.ws/tag/' } } + + it { is_expected.to eql('') } end end context 'two tags' do let(:item_attributes) { { tags: %w[donkey giraffe] } } + it { is_expected.to eql('donkey, giraffe') } end context 'three tags' do let(:item_attributes) { { tags: %w[donkey giraffe zebra] } } + it { is_expected.to eql('donkey, giraffe, zebra') } context 'custom separator' do let(:item_attributes) { { tags: %w[donkey giraffe zebra] } } let(:params) { { separator: ' / ' } } + it { is_expected.to eql('donkey / giraffe / zebra') } end end @@ -81,11 +90,13 @@ context 'tag that exists' do let(:tag) { :foo } + it { is_expected.to contain_exactly(ctx.items['/item1.md'], ctx.items['/item3.md']) } end context 'tag that does not exists' do let(:tag) { :other } + it { is_expected.to be_empty } end end @@ -94,13 +105,14 @@ subject { helper.link_for_tag(tag, base_url) } let(:tag) { 'foo' } - let(:base_url) { 'http://nanoc.ws/tag/' } + let(:base_url) { 'https://nanoc.ws/tag/' } - it { is_expected.to eql('') } + it { is_expected.to eql('') } context 'tag with special HTML characters' do let(:tag) { 'R&D' } - it { is_expected.to eql('') } + + it { is_expected.to eql('') } end end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/integration/compile_command_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/integration/compile_command_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/integration/compile_command_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/integration/compile_command_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -51,8 +51,8 @@ end # Compile - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile + site = Nanoc::Core::SiteLoader.new.new_from_cwd + Nanoc::Core::Compiler.compile(site) # Check expect(File.read('output/index.html')).to eq('

A

') @@ -68,8 +68,8 @@ end # Compile - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile + site = Nanoc::Core::SiteLoader.new.new_from_cwd + Nanoc::Core::Compiler.compile(site) # Check expect(File.read('output/index.html')).to eq('

B

') diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/integration/toml_config_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/integration/toml_config_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/integration/toml_config_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/integration/toml_config_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -16,7 +16,7 @@ animal = "donkey" EOS - Nanoc::Feature.enable(Nanoc::Feature::TOML) do + Nanoc::Core::Feature.enable(Nanoc::Core::Feature::TOML) do Nanoc::CLI.run(%w[compile]) end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/orig_cli/commands/check_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/orig_cli/commands/check_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/orig_cli/commands/check_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/orig_cli/commands/check_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +describe Nanoc::OrigCLI::Commands::Check, site: true, stdio: true do + describe '#run' do + before do + File.write('Checks', "deploy_check :stale\n") + end + + context 'without options and arguments' do + subject { Nanoc::CLI.run(['check']) } + + context 'no issues for any checks' do + it 'succeeds' do + subject + end + end + + context 'issues for deploy check' do + before do + FileUtils.mkdir_p('output') + File.write('output/asdf.txt', 'staaale') + end + + it 'fails' do + expect { subject }.to raise_error(Nanoc::Core::TrivialError, 'One or more checks failed') + end + end + + context 'issues for non-deploy check' do + before do + FileUtils.mkdir_p('output') + File.write('output/asdf.txt', 'staaale') + File.write('Checks', '') + end + + it 'succeeds' do + subject + end + end + end + end + + describe 'help' do + subject { Nanoc::CLI.run(%w[help check]) } + + it 'shows --deploy as deprecated' do + expect { subject }.to output(/--deploy.*\(deprecated\)/).to_stdout + end + end +end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/orig_cli/commands/deploy_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/orig_cli/commands/deploy_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/orig_cli/commands/deploy_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/orig_cli/commands/deploy_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,345 @@ +# frozen_string_literal: true + +describe Nanoc::OrigCLI::Commands::Deploy, site: true, stdio: true do + before do + skip_unless_have_command 'rsync' + end + + describe '#run' do + let(:config) { {} } + + before do + # Prevent double-loading + expect(Nanoc::CLI).to receive(:setup) + + File.write('nanoc.yaml', YAML.dump(config)) + end + + shared_examples 'no effective deploy' do + it 'does not write any files' do + expect { run rescue nil }.not_to change { Dir['remote/*'] } + expect(Dir['remote/*']).to be_empty + end + end + + shared_examples 'effective deploy' do + it 'writes files' do + expect { run }.to change { Dir['remote/*'] }.from([]).to(['remote/success.txt']) + expect(File.read('remote/success.txt')).to eql('hurrah') + end + end + + shared_examples 'attempted/effective deploy' do + context 'no checks' do + include_examples 'effective deploy' + end + + context 'checks fail' do + before do + File.write( + 'Checks', + "check :donkey do\n" \ + " add_issue('things are broken', subject: 'success.txt')\n" \ + "end\n" \ + "\n" \ + "deploy_check :donkey\n", + ) + end + + include_examples 'no effective deploy' + + context 'checks disabled' do + context '--no-check' do + let(:command) { super() + ['--no-check'] } + + include_examples 'effective deploy' + end + + context '--Ck' do + let(:command) { super() + ['-C'] } + + include_examples 'effective deploy' + end + end + end + + context 'checks pass' do + before do + File.write( + 'Checks', + "check :donkey do\n" \ + "end\n" \ + "\n" \ + "deploy_check :donkey\n", + ) + end + + include_examples 'effective deploy' + end + end + + describe 'listing deployers' do + shared_examples 'lists all deployers' do + let(:run) { Nanoc::CLI.run(command) } + + it 'lists all deployers' do + expect { run }.to output(/Available deployers:\n fog\n git\n rsync/).to_stdout + end + + include_examples 'no effective deploy' + end + + context '--list-deployers' do + let(:command) { %w[deploy --list-deployers] } + + include_examples 'lists all deployers' + end + + context '-D' do + let(:command) { %w[deploy -D] } + + include_examples 'lists all deployers' + end + end + + describe 'listing deployment configurations' do + shared_examples 'lists all deployment configurations' do + let(:run) { Nanoc::CLI.run(command) } + + context 'no deployment configurations' do + let(:config) { { donkeys: 'lots' } } + + it 'says nothing is found' do + expect { run }.to output(/No deployment configurations./).to_stdout + end + + include_examples 'no effective deploy' + end + + context 'some deployment configurations' do + let(:config) do + { + deploy: { + production: { + kind: 'rsync', + dst: 'remote', + }, + staging: { + kind: 'rsync', + dst: 'remote', + }, + }, + } + end + + it 'says some targets are found' do + expect { run }.to output(/Available deployment configurations:\n production\n staging/).to_stdout + end + + include_examples 'no effective deploy' + end + end + + context '--list' do + let(:command) { %w[deploy --list] } + + include_examples 'lists all deployment configurations' + end + + context '-L' do + let(:command) { %w[deploy -L] } + + include_examples 'lists all deployment configurations' + end + end + + describe 'deploying' do + let(:run) { Nanoc::CLI.run(command) } + let(:command) { %w[deploy] } + + before do + FileUtils.mkdir_p('output') + FileUtils.mkdir_p('remote') + File.write('output/success.txt', 'hurrah') + end + + shared_examples 'missing kind warning' do + it 'warns about missing kind' do + expect { run }.to output(/Warning: The specified deploy target does not have a kind attribute. Assuming rsync./).to_stderr + end + end + + context 'no deploy configs' do + it 'errors' do + expect { run }.to raise_error( + Nanoc::Core::TrivialError, + 'The site has no deployment configurations.', + ) + end + + include_examples 'no effective deploy' + + context 'configuration created in preprocessor' do + before do + File.write( + 'Rules', + "preprocess do\n" \ + " @config[:deploy] = {\n" \ + " default: { dst: 'remote' },\n" \ + " }\n" \ + "end\n\n" + File.read('Rules'), + ) + end + + include_examples 'attempted/effective deploy' + end + end + + context 'some deploy configs' do + let(:config) do + { + deploy: { + irrelevant: { + kind: 'rsync', + dst: 'remote', + }, + }, + } + end + + context 'default target' do + context 'requested deploy config does not exist' do + it 'errors' do + expect { run }.to raise_error( + Nanoc::Core::TrivialError, + 'The site has no deployment configuration named `default`.', + ) + end + + include_examples 'no effective deploy' + end + + context 'requested deploy config exists' do + let(:config) do + { + deploy: { + default: { + kind: 'rsync', + dst: 'remote', + }, + }, + } + end + + include_examples 'attempted/effective deploy' + + context 'dry run' do + let(:command) { super() + ['--dry-run'] } + + include_examples 'no effective deploy' + end + end + + context 'requested deploy config exists, but has no kind' do + let(:config) do + { + deploy: { + default: { + dst: 'remote', + }, + }, + } + end + + include_examples 'attempted/effective deploy' + include_examples 'missing kind warning' + + context 'dry run' do + let(:command) { super() + ['--dry-run'] } + + include_examples 'no effective deploy' + end + end + end + + shared_examples 'deploy with non-default target' do + context 'requested deploy config does not exist' do + it 'errors' do + expect { run }.to raise_error( + Nanoc::Core::TrivialError, + 'The site has no deployment configuration named `production`.', + ) + end + + include_examples 'no effective deploy' + end + + context 'requested deploy config exists' do + let(:config) do + { + deploy: { + production: { + kind: 'rsync', + dst: 'remote', + }, + }, + } + end + + include_examples 'attempted/effective deploy' + + context 'dry run' do + let(:command) { (super() + ['--dry-run']) } + + include_examples 'no effective deploy' + end + end + + context 'requested deploy config exists, but has no kind' do + let(:config) do + { + deploy: { + production: { + dst: 'remote', + }, + }, + } + end + + include_examples 'attempted/effective deploy' + include_examples 'missing kind warning' + + context 'dry run' do + let(:command) { (super() + ['--dry-run']) } + + include_examples 'no effective deploy' + end + end + end + + context 'non-default target, specified as argument' do + let(:command) { %w[deploy production] } + + include_examples 'deploy with non-default target' + end + + context 'non-default target, specified as option (--target)' do + let(:command) { %w[deploy --target production] } + + include_examples 'deploy with non-default target' + end + + context 'multiple targets specified' do + let(:command) { %w[deploy --target staging production] } + + it 'errors' do + expect { run }.to raise_error( + Nanoc::Core::TrivialError, + 'Only one deployment target can be specified on the command line.', + ) + end + end + end + end + end +end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/orig_cli/commands/show_rules_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/orig_cli/commands/show_rules_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/orig_cli/commands/show_rules_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/orig_cli/commands/show_rules_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,132 @@ +# frozen_string_literal: true + +describe Nanoc::OrigCLI::Commands::ShowRules, stdio: true, site: true do + describe '#run' do + subject { runner.run } + + let(:runner) do + described_class.new(options, arguments, command) + end + + let(:options) { {} } + + let(:arguments) { [] } + + let(:command) { double(:command) } + + let(:site) do + double( + :site, + items: items, + layouts: layouts, + compiler: compiler, + config: config, + ) + end + + let(:items) do + Nanoc::Core::ItemCollection.new( + config, + [ + Nanoc::Core::Item.new('About Me', {}, '/about.md'), + Nanoc::Core::Item.new('About My Dog', {}, '/dog.md'), + Nanoc::Core::Item.new('Raw Data', {}, '/other.dat'), + ], + ) + end + + let(:reps) do + Nanoc::Core::ItemRepRepo.new.tap do |reps| + reps << Nanoc::Core::ItemRep.new(items['/about.md'], :default) + reps << Nanoc::Core::ItemRep.new(items['/about.md'], :text) + reps << Nanoc::Core::ItemRep.new(items['/dog.md'], :default) + reps << Nanoc::Core::ItemRep.new(items['/dog.md'], :text) + reps << Nanoc::Core::ItemRep.new(items['/other.dat'], :default) + end + end + + let(:layouts) do + Nanoc::Core::LayoutCollection.new( + config, + [ + Nanoc::Core::Layout.new('Default', {}, '/default.erb'), + Nanoc::Core::Layout.new('Article', {}, '/article.haml'), + Nanoc::Core::Layout.new('Other', {}, '/other.xyzzy'), + ], + ) + end + + let(:config) { Nanoc::Core::Configuration.new(dir: Dir.getwd).with_defaults } + + let(:action_provider) do + Class.new(Nanoc::Core::ActionProvider) do + attr_reader :rules_collection + + def self.for(_context) + raise NotImplementedError + end + + def initialize(rules_collection) + @rules_collection = rules_collection + end + end.new(rules_collection) + end + + let(:compiler) { double(:compiler) } + + let(:rules_collection) do + Nanoc::RuleDSL::RulesCollection.new.tap do |rc| + rc.add_item_compilation_rule( + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/dog.*'), :default, proc {}), + ) + rc.add_item_compilation_rule( + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/*.md'), :default, proc {}), + ) + rc.add_item_compilation_rule( + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/**/*'), :text, proc {}), + ) + + rc.layout_filter_mapping[Nanoc::Core::Pattern.from('/*.haml')] = [:haml, {}] + rc.layout_filter_mapping[Nanoc::Core::Pattern.from('/*.erb')] = [:erb, {}] + end + end + + let(:expected_out) do + <<-EOS + \e[1m\e[33mItem /about.md\e[0m: + Rep default: /*.md + Rep text: /**/* + + \e[1m\e[33mItem /dog.md\e[0m: + Rep default: /dog.* + Rep text: /**/* + + \e[1m\e[33mItem /other.dat\e[0m: + Rep default: (none) + + \e[1m\e[33mLayout /article.haml\e[0m: + /*.haml + + \e[1m\e[33mLayout /default.erb\e[0m: + /*.erb + + \e[1m\e[33mLayout /other.xyzzy\e[0m: + (none) + + EOS + .gsub(/^ {8}/, '') + end + + it 'writes item and layout rules to stdout' do + expect(runner).to receive(:load_site).and_return(site) + expect(Nanoc::Core::Compiler).to receive(:new_for).with(site).and_return(compiler) + expect(compiler).to receive(:run_until_reps_built).and_return(reps: reps) + expect(Nanoc::RuleDSL::ActionProvider).to receive(:for).with(site).and_return(action_provider) + expect { subject }.to output(expected_out).to_stdout + end + + it 'writes status information to stderr' do + expect { subject }.to output("Loading site… done\n").to_stderr + end + end +end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/orig_cli_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/orig_cli_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/orig_cli_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/orig_cli_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +describe Nanoc::OrigCLI do + let(:all_commands) do + ObjectSpace.each_object(Cri::Command) + end + + let(:exceptions) do + # FIXME: [Nanoc 5] Get rid of these exceptions + [ + ['deploy', ['C']], + ['help', ['v']], + ['check', ['d']], + ] + end + + def ancestors_of_command(command) + if command.is_a?(Cri::Command) + [command] + ancestors_of_command(command.supercommand) + else + [] + end + end + + def short_options_for_command(command) + ancestors = ancestors_of_command(command) + ancestors.flat_map { |a| a.option_definitions.to_a.map(&:short) }.compact + end + + it 'has no commands that have conflicting options' do + all_commands.each do |command| + short_options = short_options_for_command(command) + + duplicate_options = short_options.select { |o| short_options.count(o) > 1 }.uniq + + next if exceptions.include?([command.name, duplicate_options]) + + expect(duplicate_options).to( + be_empty, + "The #{command.name} command’s option shorthands #{duplicate_options.uniq} are used by multiple options", + ) + end + end +end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1015_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1015_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1015_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1015_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -13,7 +13,7 @@ end it 'errors' do - expect { Nanoc::CLI.run(%w[compile --verbose]) }.to raise_exception(Nanoc::Int::ItemRepRouter::RouteWithoutSlashError) + expect { Nanoc::CLI.run(%w[compile --verbose]) }.to raise_exception(Nanoc::Core::ItemRepRouter::RouteWithoutSlashError) expect(File.file?('outputfoo.html')).not_to be end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1040_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1040_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1040_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1040_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -19,6 +19,6 @@ end it 'errors' do - expect { Nanoc::CLI.run(%w[compile]) }.to raise_error(Nanoc::Int::Errors::DependencyCycle) + expect { Nanoc::CLI.run(%w[compile]) }.to raise_error(Nanoc::Core::Errors::DependencyCycle) end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1047_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1047_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1047_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1047_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -19,7 +19,7 @@ File.write('content/foo.md', 'I am foo!') File.write('content/bar.md', '<%= @items["/foo.*"].compiled_content %><%= raise "boom" %>') - expect { Nanoc::CLI.run(%w[compile]) }.to raise_error(Nanoc::Int::Errors::CompilationError) + expect { Nanoc::CLI.run(%w[compile]) }.to raise_error(Nanoc::Core::Errors::CompilationError) expect(File.read('output/foo.md')).to eql('I am foo!') File.write('content/bar.md', '[<%= @items["/foo.*"].compiled_content %>]') diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1100_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1100_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1100_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1100_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -16,7 +16,7 @@ EOS end - it 'should not crash' do + it 'does not crash' do Nanoc::CLI.run(%w[compile]) end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1323_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1323_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1323_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1323_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -19,6 +19,6 @@ example do expect { Nanoc::CLI.run(%w[compile]) } - .to raise_error { |e| e.unwrap.is_a?(Nanoc::Int::Errors::FilterReturnedNil) } + .to raise_error { |e| e.unwrap.is_a?(Nanoc::Filter::FilterReturnedNilError) } end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1328_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1328_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1328_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1328_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -29,19 +29,19 @@ it 'fails check for foo.html' do expect { Nanoc::CLI.run(%w[check ilinks]) } - .to raise_error(Nanoc::Int::Errors::GenericTrivial, 'One or more checks failed') + .to raise_error(Nanoc::Core::TrivialError, 'One or more checks failed') .and output(%r{output/foo\.html:}).to_stdout end it 'fails check for foo.xhtml' do expect { Nanoc::CLI.run(%w[check ilinks]) } - .to raise_error(Nanoc::Int::Errors::GenericTrivial, 'One or more checks failed') + .to raise_error(Nanoc::Core::TrivialError, 'One or more checks failed') .and output(%r{output/foo\.xhtml:}).to_stdout end it 'fails check for foo.htm' do expect { Nanoc::CLI.run(%w[check ilinks]) } - .to raise_error(Nanoc::Int::Errors::GenericTrivial, 'One or more checks failed') + .to raise_error(Nanoc::Core::TrivialError, 'One or more checks failed') .and output(%r{output/foo\.htm:}).to_stdout end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1412_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1412_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1412_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1412_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +describe 'GH-1412', site: true, stdio: true do + before do + FileUtils.mkdir_p('content') + File.write('content/a.erb', 'A <%= @items["/b.*"].compiled_content %>') + File.write('content/b.erb', 'B <%= @items["/a.*"].compiled_content %>') + + FileUtils.mkdir_p('layouts') + File.write('layouts/default.erb', '[<%= yield %>]') + + File.write('Rules', <<~EOS) + compile '/*' do + layout '/default.*' + filter :erb + write ext: 'html' + end + + layout '/*', :erb + EOS + end + + example do + Nanoc::CLI.run([]) + + expect(File.file?('output/a.html')).to be(true) + expect(File.read('output/a.html')).to eq('[A B <%= @items["/a.*"].compiled_content %>]') + expect(File.file?('output/b.html')).to be(true) + expect(File.read('output/b.html')).to eq('[B A <%= @items["/b.*"].compiled_content %>]') + end +end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1428_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1428_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1428_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1428_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +describe 'GH-1428', site: true, stdio: true do + before do + FileUtils.mkdir_p('layouts') + File.write('layouts/default.erb', 'layout stuff') + + File.write('Rules', <<~EOS) + ignore '/*' + layout '/*', :erb + EOS + end + + example do + Nanoc::CLI.run([]) + Nanoc::CLI.run(['show-data']) + end +end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1463_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1463_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_1463_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_1463_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +describe 'GH-1463', site: true, stdio: true do + before do + FileUtils.mkdir_p('content') + FileUtils.mkdir_p('content/org1') + + File.write('content/org1.erb', <<~CONTENT) +
    + <% children_of(@item).each do |c| %> +
  • <%= c[:title] %>
  • + <% end %> +
+ CONTENT + + File.write('content/org1/oink.md', <<~CONTENT) + --- + title: Oink + --- + + here is oink content + CONTENT + + FileUtils.mkdir_p('lib') + File.write('lib/default.rb', <<~LIB) + include Nanoc::Helpers::ChildParent + LIB + + File.write('Rules', <<~RULES) + compile '/**/*' do + filter :erb + write ext: 'html' + end + RULES + end + + example do + Nanoc::CLI.run([]) + expect(File.file?('output/org1.html')).to be(true) + expect(File.read('output/org1.html')).to match(%r{
  • Oink
  • }) + + # Remove oink + FileUtils.rm('content/org1/oink.md') + Nanoc::CLI.run([]) + expect(File.file?('output/org1.html')).to be(true) + expect(File.read('output/org1.html')).not_to match(%r{
  • Oink
  • }) + + # Re-add oink + File.write('content/org1/oink.md', <<~CONTENT) + --- + title: Oink + --- + + here is oink content + CONTENT + Nanoc::CLI.run([]) + expect(File.file?('output/org1.html')).to be(true) + expect(File.read('output/org1.html')).to match(%r{
  • Oink
  • }) + end +end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_761_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_761_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_761_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_761_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -17,8 +17,8 @@ end it 'supports #compiled_content instead of yield' do - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile + site = Nanoc::Core::SiteLoader.new.new_from_cwd + Nanoc::Core::Compiler.compile(site) expect(File.read('output/donkey.html')).to eql('[Compiled content donkey!]') end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_767_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_767_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_767_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_767_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -15,7 +15,7 @@ end it 'does not expose #path on @item' do - site = Nanoc::Int::SiteLoader.new.new_from_cwd - expect { site.compile }.to raise_error(NoMethodError, /undefined method .*path.* for .*Nanoc::BasicItemView/) + site = Nanoc::Core::SiteLoader.new.new_from_cwd + expect { Nanoc::Core::Compiler.compile(site) }.to raise_error(NoMethodError, /undefined method .*path.* for .*Nanoc::Core::BasicItemView/) end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_769_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_769_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_769_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_769_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -24,8 +24,8 @@ end it 'finds the parent if the parent is root' do - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile + site = Nanoc::Core::SiteLoader.new.new_from_cwd + Nanoc::Core::Compiler.compile(site) expect(File.read('output/donkey/index.html')).to eql('Donkey! [/]') end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_776_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_776_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_776_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_776_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -15,10 +15,10 @@ EOS end - let(:site) { Nanoc::Int::SiteLoader.new.new_from_cwd } + let(:site) { Nanoc::Core::SiteLoader.new.new_from_cwd } before do - site.compile + Nanoc::Core::Compiler.compile(site) end context 'without pruning' do @@ -30,8 +30,8 @@ context 'with pruning' do before do - res = Nanoc::Int::Compiler.new_for(site).run_until_reps_built - Nanoc::Pruner.new(site.config, res.fetch(:reps)).run + res = Nanoc::Core::Compiler.new_for(site).run_until_reps_built + Nanoc::Core::Pruner.new(site.config, res.fetch(:reps)).run end it 'does not prune written snapshots' do diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_804_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_804_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/regressions/gh_804_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/regressions/gh_804_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -20,7 +20,7 @@ it 'does not crash' do expect { Nanoc::CLI.run(%w[check donkey]) }.to( - raise_error(Nanoc::Int::Errors::GenericTrivial, 'One or more checks failed').and( + raise_error(Nanoc::Core::TrivialError, 'One or more checks failed').and( output(/Issues found!\n \(global\):\n \[ (\e\[31m)?ERROR(\e\[0m)? \] donkey - Not enough donkeys\n \/catlady.md:\n \[ (\e\[31m)?ERROR(\e\[0m)? \] donkey - Too many cats\n/).to_stdout, ), ) diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/rule_dsl/action_recorder_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/rule_dsl/action_recorder_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/rule_dsl/action_recorder_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/rule_dsl/action_recorder_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -4,25 +4,25 @@ let(:recorder) { described_class.new(rep) } let(:action_sequence) { recorder.action_sequence } - let(:item) { Nanoc::Int::Item.new('stuff', {}, '/foo.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } + let(:item) { Nanoc::Core::Item.new('stuff', {}, '/foo.md') } + let(:rep) { Nanoc::Core::ItemRep.new(item, :default) } describe '#filter' do it 'records filter call without arguments' do recorder.filter(:erb) - expect(action_sequence.size).to eql(1) - expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Filter) - expect(action_sequence[0].filter_name).to eql(:erb) + expect(action_sequence.size).to be(1) + expect(action_sequence[0]).to be_a(Nanoc::Core::ProcessingActions::Filter) + expect(action_sequence[0].filter_name).to be(:erb) expect(action_sequence[0].params).to eql({}) end it 'records filter call with arguments' do recorder.filter(:erb, x: 123) - expect(action_sequence.size).to eql(1) - expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Filter) - expect(action_sequence[0].filter_name).to eql(:erb) + expect(action_sequence.size).to be(1) + expect(action_sequence[0]).to be_a(Nanoc::Core::ProcessingActions::Filter) + expect(action_sequence[0].filter_name).to be(:erb) expect(action_sequence[0].params).to eql(x: 123) end end @@ -31,13 +31,13 @@ it 'records layout call without arguments' do recorder.layout('/default.*') - expect(action_sequence.size).to eql(2) + expect(action_sequence.size).to be(2) - expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(action_sequence[0]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(action_sequence[0].snapshot_names).to eql([:pre]) expect(action_sequence[0].paths).to be_empty - expect(action_sequence[1]).to be_a(Nanoc::Int::ProcessingActions::Layout) + expect(action_sequence[1]).to be_a(Nanoc::Core::ProcessingActions::Layout) expect(action_sequence[1].layout_identifier).to eql('/default.*') expect(action_sequence[1].params).to eql({}) end @@ -45,13 +45,13 @@ it 'records layout call with arguments' do recorder.layout('/default.*', donkey: 123) - expect(action_sequence.size).to eql(2) + expect(action_sequence.size).to be(2) - expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(action_sequence[0]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(action_sequence[0].snapshot_names).to eql([:pre]) expect(action_sequence[0].paths).to be_empty - expect(action_sequence[1]).to be_a(Nanoc::Int::ProcessingActions::Layout) + expect(action_sequence[1]).to be_a(Nanoc::Core::ProcessingActions::Layout) expect(action_sequence[1].layout_identifier).to eql('/default.*') expect(action_sequence[1].params).to eql(donkey: 123) end @@ -69,7 +69,7 @@ it 'raises when creating same snapshot' do expect { recorder.snapshot(:foo) } - .to raise_error(Nanoc::Int::Errors::CannotCreateMultipleSnapshotsWithSameName) + .to raise_error(Nanoc::Core::ActionSequenceBuilder::CannotCreateMultipleSnapshotsWithSameNameError) end end @@ -78,8 +78,8 @@ it 'records' do subject - expect(action_sequence.size).to eql(1) - expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(action_sequence.size).to be(1) + expect(action_sequence[0]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(action_sequence[0].snapshot_names).to eql([:foo]) expect(action_sequence[0].paths).to be_empty end @@ -87,6 +87,7 @@ context 'final argument' do subject { recorder.snapshot(:foo, subject_params) } + let(:subject_params) { {} } context 'routing rule does not exist' do @@ -95,15 +96,15 @@ it 'records' do subject - expect(action_sequence.size).to eql(1) - expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(action_sequence.size).to be(1) + expect(action_sequence[0]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(action_sequence[0].snapshot_names).to eql([:foo]) expect(action_sequence[0].paths).to be_empty end it 'keeps skip_routing_rule' do expect { subject } - .not_to change { recorder.snapshots_for_which_to_skip_routing_rule } + .not_to change(recorder, :snapshots_for_which_to_skip_routing_rule) .from(Set.new) end end @@ -113,34 +114,34 @@ it 'records' do subject - expect(action_sequence.size).to eql(1) - expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(action_sequence.size).to be(1) + expect(action_sequence[0]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(action_sequence[0].snapshot_names).to eql([:foo]) expect(action_sequence[0].paths).to eql(['/routed-foo.html']) end it 'sets skip_routing_rule' do expect { subject } - .to change { recorder.snapshots_for_which_to_skip_routing_rule } + .to change(recorder, :snapshots_for_which_to_skip_routing_rule) .from(Set.new) .to(Set.new([:foo])) end end context 'explicit path given as identifier' do - let(:subject_params) { { path: Nanoc::Identifier.from('/routed-foo.html') } } + let(:subject_params) { { path: Nanoc::Core::Identifier.from('/routed-foo.html') } } it 'records' do subject - expect(action_sequence.size).to eql(1) - expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(action_sequence.size).to be(1) + expect(action_sequence[0]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(action_sequence[0].snapshot_names).to eql([:foo]) expect(action_sequence[0].paths).to eql(['/routed-foo.html']) end it 'sets skip_routing_rule' do expect { subject } - .to change { recorder.snapshots_for_which_to_skip_routing_rule } + .to change(recorder, :snapshots_for_which_to_skip_routing_rule) .from(Set.new) .to(Set.new([:foo])) end @@ -151,15 +152,15 @@ it 'records' do subject - expect(action_sequence.size).to eql(1) - expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(action_sequence.size).to be(1) + expect(action_sequence[0]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(action_sequence[0].snapshot_names).to eql([:foo]) expect(action_sequence[0].paths).to be_empty end it 'sets skip_routing_rule' do expect { subject } - .to change { recorder.snapshots_for_which_to_skip_routing_rule } + .to change(recorder, :snapshots_for_which_to_skip_routing_rule) .from(Set.new) .to(Set.new([:foo])) end @@ -176,10 +177,10 @@ recorder.snapshot(:foo) recorder.snapshot(:bar) - expect(action_sequence.size).to eql(2) - expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(action_sequence.size).to be(2) + expect(action_sequence[0]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(action_sequence[0].snapshot_names).to eql([:foo]) - expect(action_sequence[1]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(action_sequence[1]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(action_sequence[1].snapshot_names).to eql([:bar]) end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/rule_dsl/action_sequence_calculator_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/rule_dsl/action_sequence_calculator_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/rule_dsl/action_sequence_calculator_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/rule_dsl/action_sequence_calculator_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -7,9 +7,9 @@ let(:rules_collection) { Nanoc::RuleDSL::RulesCollection.new } - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd).with_defaults } - let(:items) { Nanoc::Int::ItemCollection.new(config) } - let(:layouts) { Nanoc::Int::LayoutCollection.new(config) } + let(:config) { Nanoc::Core::Configuration.new(dir: Dir.getwd).with_defaults } + let(:items) { Nanoc::Core::ItemCollection.new(config) } + let(:layouts) { Nanoc::Core::LayoutCollection.new(config) } let(:data_source_class) do Class.new(Nanoc::DataSource) do @@ -29,16 +29,16 @@ end let(:site) do - Nanoc::Int::Site.new(config: config, code_snippets: [], data_source: data_source) + Nanoc::Core::Site.new(config: config, code_snippets: [], data_source: data_source) end describe '#[]' do subject { action_sequence_calculator[obj] } context 'with item rep' do - let(:obj) { Nanoc::Int::ItemRep.new(item, :csv) } + let(:obj) { Nanoc::Core::ItemRep.new(item, :csv) } - let(:item) { Nanoc::Int::Item.new('content', {}, Nanoc::Identifier.from('/list.md')) } + let(:item) { Nanoc::Core::Item.new('content', {}, Nanoc::Core::Identifier.from('/list.md')) } context 'no rules exist' do it 'raises error' do @@ -54,106 +54,106 @@ layout '/default.*' filter :typohero end - rule = Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/list.*'), :csv, rules_proc) + rule = Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/list.*'), :csv, rules_proc) rules_collection.add_item_compilation_rule(rule) end example do subject - expect(subject[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(subject[0]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(subject[0].snapshot_names).to eql([:raw]) expect(subject[0].paths).to be_empty - expect(subject[1]).to be_a(Nanoc::Int::ProcessingActions::Filter) - expect(subject[1].filter_name).to eql(:erb) + expect(subject[1]).to be_a(Nanoc::Core::ProcessingActions::Filter) + expect(subject[1].filter_name).to be(:erb) expect(subject[1].params).to eql(speed: :over_9000) - expect(subject[2]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(subject[2]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(subject[2].snapshot_names).to eql([:pre]) expect(subject[2].paths).to be_empty - expect(subject[3]).to be_a(Nanoc::Int::ProcessingActions::Layout) + expect(subject[3]).to be_a(Nanoc::Core::ProcessingActions::Layout) expect(subject[3].layout_identifier).to eql('/default.*') expect(subject[3].params).to be_nil - expect(subject[4]).to be_a(Nanoc::Int::ProcessingActions::Filter) - expect(subject[4].filter_name).to eql(:typohero) + expect(subject[4]).to be_a(Nanoc::Core::ProcessingActions::Filter) + expect(subject[4].filter_name).to be(:typohero) expect(subject[4].params).to eql({}) - expect(subject[5]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(subject[5]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(subject[5].snapshot_names).to eql(%i[post last]) expect(subject[5].paths).to be_empty - expect(subject.size).to eql(6) + expect(subject.size).to be(6) end end context 'no routing rule exists' do before do # Add compilation rule - compilation_rule = Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/list.*'), :csv, proc {}) + compilation_rule = Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/list.*'), :csv, proc {}) rules_collection.add_item_compilation_rule(compilation_rule) end example do subject - expect(subject[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(subject[0]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(subject[0].snapshot_names).to eql(%i[raw last pre]) expect(subject[0].paths).to be_empty - expect(subject.size).to eql(1) + expect(subject.size).to be(1) end end context 'routing rule exists' do before do # Add compilation rule - compilation_rule = Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/list.*'), :csv, proc {}) + compilation_rule = Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/list.*'), :csv, proc {}) rules_collection.add_item_compilation_rule(compilation_rule) # Add routing rule - routing_rule = Nanoc::RuleDSL::RoutingRule.new(Nanoc::Int::Pattern.from('/list.*'), :csv, proc { '/foo.md' }, snapshot_name: :last) + routing_rule = Nanoc::RuleDSL::RoutingRule.new(Nanoc::Core::Pattern.from('/list.*'), :csv, proc { '/foo.md' }, snapshot_name: :last) rules_collection.add_item_routing_rule(routing_rule) end example do subject - expect(subject[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(subject[0]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(subject[0].snapshot_names).to eql(%i[raw last pre]) expect(subject[0].paths).to eq(['/foo.md']) - expect(subject.size).to eql(1) + expect(subject.size).to be(1) end end context 'routing rule for other rep exists' do before do # Add compilation rule - compilation_rule = Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/list.*'), :csv, proc {}) + compilation_rule = Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/list.*'), :csv, proc {}) rules_collection.add_item_compilation_rule(compilation_rule) # Add routing rule - routing_rule = Nanoc::RuleDSL::RoutingRule.new(Nanoc::Int::Pattern.from('/list.*'), :abc, proc { '/foo.md' }, snapshot_name: :last) + routing_rule = Nanoc::RuleDSL::RoutingRule.new(Nanoc::Core::Pattern.from('/list.*'), :abc, proc { '/foo.md' }, snapshot_name: :last) rules_collection.add_item_routing_rule(routing_rule) end example do subject - expect(subject[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(subject[0]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(subject[0].snapshot_names).to eql(%i[raw last pre]) expect(subject[0].paths).to be_empty - expect(subject.size).to eql(1) + expect(subject.size).to be(1) end end end context 'with layout' do - let(:obj) { Nanoc::Int::Layout.new('content', {}, '/default.erb') } + let(:obj) { Nanoc::Core::Layout.new('content', {}, '/default.erb') } context 'no rules exist' do it 'raises error' do @@ -164,14 +164,14 @@ context 'rule exists' do before do - pat = Nanoc::Int::Pattern.from('/*.erb') + pat = Nanoc::Core::Pattern.from('/*.erb') rules_collection.layout_filter_mapping[pat] = [:erb, { x: 123 }] end it 'contains memory for the rule' do - expect(subject.size).to eql(1) - expect(subject[0]).to be_a(Nanoc::Int::ProcessingActions::Filter) - expect(subject[0].filter_name).to eql(:erb) + expect(subject.size).to be(1) + expect(subject[0]).to be_a(Nanoc::Core::ProcessingActions::Filter) + expect(subject[0].filter_name).to be(:erb) expect(subject[0].params).to eql(x: 123) end end @@ -191,7 +191,7 @@ subject { action_sequence_calculator.compact_snapshots(action_sequence) } let(:action_sequence) do - Nanoc::Int::ActionSequence.build(rep) do |b| + Nanoc::Core::ActionSequenceBuilder.build(rep) do |b| b.add_snapshot(:a1, nil) b.add_snapshot(:a2, '/a2.md') b.add_snapshot(:a3, nil) @@ -204,27 +204,27 @@ end end - let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } + let(:item) { Nanoc::Core::Item.new('asdf', {}, '/foo.md') } + let(:rep) { Nanoc::Core::ItemRep.new(item, :default) } example do - expect(subject[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(subject[0]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(subject[0].snapshot_names).to eql(%i[a1 a2 a3]) expect(subject[0].paths).to eql(['/a2.md']) - expect(subject[1]).to be_a(Nanoc::Int::ProcessingActions::Filter) + expect(subject[1]).to be_a(Nanoc::Core::ProcessingActions::Filter) - expect(subject[2]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(subject[2]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(subject[2].snapshot_names).to eql(%i[b1 b2 b3]) expect(subject[2].paths).to eql(['/b1.md', '/b3.md']) - expect(subject[3]).to be_a(Nanoc::Int::ProcessingActions::Filter) + expect(subject[3]).to be_a(Nanoc::Core::ProcessingActions::Filter) - expect(subject[4]).to be_a(Nanoc::Int::ProcessingActions::Snapshot) + expect(subject[4]).to be_a(Nanoc::Core::ProcessingActions::Snapshot) expect(subject[4].snapshot_names).to eql([:c]) expect(subject[4].paths).to be_empty - expect(subject.size).to eql(5) + expect(subject.size).to be(5) end end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/rule_dsl/rule_context_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/rule_dsl/rule_context_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/rule_dsl/rule_context_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/rule_dsl/rule_context_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,14 +1,14 @@ # frozen_string_literal: true shared_examples 'a rule context' do - let(:item_identifier) { Nanoc::Identifier.new('/foo.md') } - let(:item) { Nanoc::Int::Item.new('content', {}, item_identifier) } - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd) } - let(:items) { Nanoc::Int::ItemCollection.new(config) } - let(:layouts) { Nanoc::Int::LayoutCollection.new(config) } + let(:item_identifier) { Nanoc::Core::Identifier.new('/foo.md') } + let(:item) { Nanoc::Core::Item.new('content', {}, item_identifier) } + let(:config) { Nanoc::Core::Configuration.new(dir: Dir.getwd) } + let(:items) { Nanoc::Core::ItemCollection.new(config) } + let(:layouts) { Nanoc::Core::LayoutCollection.new(config) } let(:site) do - Nanoc::Int::Site.new( + Nanoc::Core::Site.new( config: config, code_snippets: [], data_source: data_source, @@ -16,26 +16,26 @@ end let(:data_source) do - Nanoc::Int::InMemDataSource.new(items, layouts) + Nanoc::Core::InMemoryDataSource.new(items, layouts) end - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } + let(:rep) { Nanoc::Core::ItemRep.new(item, :default) } let(:reps) { double(:reps) } let(:compilation_context) { double(:compilation_context) } let(:view_context) do - Nanoc::ViewContextForPreCompilation.new(items: items) + Nanoc::Core::ViewContextForPreCompilation.new(items: items) end - let(:dependency_tracker) { double(:dependency_tracker) } + let(:dependency_tracker) { Nanoc::Core::DependencyTracker::Null.new } describe '#initialize' do it 'wraps objects in view classes' do - expect(subject.rep.class).to eql(Nanoc::BasicItemRepView) - expect(subject.item.class).to eql(Nanoc::BasicItemView) - expect(subject.config.class).to eql(Nanoc::ConfigView) - expect(subject.layouts.class).to eql(Nanoc::LayoutCollectionView) - expect(subject.items.class).to eql(Nanoc::ItemCollectionWithoutRepsView) + expect(subject.rep.class).to eql(Nanoc::Core::BasicItemRepView) + expect(subject.item.class).to eql(Nanoc::Core::BasicItemView) + expect(subject.config.class).to eql(Nanoc::Core::ConfigView) + expect(subject.layouts.class).to eql(Nanoc::Core::LayoutCollectionView) + expect(subject.items.class).to eql(Nanoc::Core::ItemCollectionWithoutRepsView) end it 'contains the right objects' do @@ -51,7 +51,7 @@ subject { rule_context.item } it 'is a view without reps access' do - expect(subject.class).to eql(Nanoc::BasicItemView) + expect(subject.class).to eql(Nanoc::Core::BasicItemView) end it 'contains the right item' do @@ -59,16 +59,16 @@ end context 'with legacy identifier and children/parent' do - let(:item_identifier) { Nanoc::Identifier.new('/foo/', type: :legacy) } + let(:item_identifier) { Nanoc::Core::Identifier.new('/foo/', type: :legacy) } - let(:parent_identifier) { Nanoc::Identifier.new('/', type: :legacy) } - let(:parent) { Nanoc::Int::Item.new('parent', {}, parent_identifier) } + let(:parent_identifier) { Nanoc::Core::Identifier.new('/', type: :legacy) } + let(:parent) { Nanoc::Core::Item.new('parent', {}, parent_identifier) } - let(:child_identifier) { Nanoc::Identifier.new('/foo/bar/', type: :legacy) } - let(:child) { Nanoc::Int::Item.new('child', {}, child_identifier) } + let(:child_identifier) { Nanoc::Core::Identifier.new('/foo/bar/', type: :legacy) } + let(:child) { Nanoc::Core::Item.new('child', {}, child_identifier) } let(:items) do - Nanoc::Int::ItemCollection.new(config, [item, parent, child]) + Nanoc::Core::ItemCollection.new(config, [item, parent, child]) end it 'has a parent' do @@ -76,7 +76,7 @@ end it 'wraps the parent in a view without reps access' do - expect(subject.parent.class).to eql(Nanoc::BasicItemView) + expect(subject.parent.class).to eql(Nanoc::Core::BasicItemView) expect(subject.parent).not_to respond_to(:compiled_content) expect(subject.parent).not_to respond_to(:path) expect(subject.parent).not_to respond_to(:reps) @@ -87,7 +87,7 @@ end it 'wraps the children in a view without reps access' do - expect(subject.children.map(&:class)).to eql([Nanoc::BasicItemView]) + expect(subject.children.map(&:class)).to eql([Nanoc::Core::BasicItemView]) expect(subject.children[0]).not_to respond_to(:compiled_content) expect(subject.children[0]).not_to respond_to(:path) expect(subject.children[0]).not_to respond_to(:reps) @@ -98,20 +98,20 @@ describe '#items' do subject { rule_context.items } - let(:item_identifier) { Nanoc::Identifier.new('/foo/', type: :legacy) } + let(:item_identifier) { Nanoc::Core::Identifier.new('/foo/', type: :legacy) } - let(:parent_identifier) { Nanoc::Identifier.new('/', type: :legacy) } - let(:parent) { Nanoc::Int::Item.new('parent', {}, parent_identifier) } + let(:parent_identifier) { Nanoc::Core::Identifier.new('/', type: :legacy) } + let(:parent) { Nanoc::Core::Item.new('parent', {}, parent_identifier) } - let(:child_identifier) { Nanoc::Identifier.new('/foo/bar/', type: :legacy) } - let(:child) { Nanoc::Int::Item.new('child', {}, child_identifier) } + let(:child_identifier) { Nanoc::Core::Identifier.new('/foo/bar/', type: :legacy) } + let(:child) { Nanoc::Core::Item.new('child', {}, child_identifier) } let(:items) do - Nanoc::Int::ItemCollection.new(config, [item, parent, child]) + Nanoc::Core::ItemCollection.new(config, [item, parent, child]) end it 'is a view without reps access' do - expect(subject.class).to eql(Nanoc::ItemCollectionWithoutRepsView) + expect(subject.class).to eql(Nanoc::Core::ItemCollectionWithoutRepsView) end it 'contains all items' do @@ -144,14 +144,14 @@ described_class.new(rep: rep, site: site, view_context: view_context) end - let(:item_identifier) { Nanoc::Identifier.new('/foo.md') } - let(:item) { Nanoc::Int::Item.new('content', {}, item_identifier) } - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd) } - let(:items) { Nanoc::Int::ItemCollection.new(config) } + let(:item_identifier) { Nanoc::Core::Identifier.new('/foo.md') } + let(:item) { Nanoc::Core::Item.new('content', {}, item_identifier) } + let(:rep) { Nanoc::Core::ItemRep.new(item, :default) } + let(:config) { Nanoc::Core::Configuration.new(dir: Dir.getwd) } + let(:items) { Nanoc::Core::ItemCollection.new(config) } let(:site) do - Nanoc::Int::Site.new( + Nanoc::Core::Site.new( config: config, code_snippets: [], data_source: data_source, @@ -159,7 +159,7 @@ end let(:view_context) do - Nanoc::ViewContextForPreCompilation.new(items: items) + Nanoc::Core::ViewContextForPreCompilation.new(items: items) end it_behaves_like 'a rule context' @@ -170,15 +170,15 @@ described_class.new(rep: rep, site: site, recorder: recorder, view_context: view_context) end - let(:item_identifier) { Nanoc::Identifier.new('/foo.md') } - let(:item) { Nanoc::Int::Item.new('content', {}, item_identifier) } - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd) } - let(:items) { Nanoc::Int::ItemCollection.new(config) } - let(:layouts) { Nanoc::Int::LayoutCollection.new(config) } + let(:item_identifier) { Nanoc::Core::Identifier.new('/foo.md') } + let(:item) { Nanoc::Core::Item.new('content', {}, item_identifier) } + let(:rep) { Nanoc::Core::ItemRep.new(item, :default) } + let(:config) { Nanoc::Core::Configuration.new(dir: Dir.getwd) } + let(:items) { Nanoc::Core::ItemCollection.new(config) } + let(:layouts) { Nanoc::Core::LayoutCollection.new(config) } let(:site) do - Nanoc::Int::Site.new( + Nanoc::Core::Site.new( config: config, code_snippets: [], data_source: data_source, @@ -186,13 +186,13 @@ end let(:data_source) do - Nanoc::Int::InMemDataSource.new(items, layouts) + Nanoc::Core::InMemoryDataSource.new(items, layouts) end - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } + let(:rep) { Nanoc::Core::ItemRep.new(item, :default) } let(:view_context) do - Nanoc::ViewContextForPreCompilation.new(items: items) + Nanoc::Core::ViewContextForPreCompilation.new(items: items) end let(:recorder) { Nanoc::RuleDSL::ActionRecorder.new(rep) } @@ -263,7 +263,8 @@ context 'with identifier' do context 'calling once' do subject { rule_context.write(identifier) } - let(:identifier) { Nanoc::Identifier.new('/foo.html') } + + let(:identifier) { Nanoc::Core::Identifier.new('/foo.html') } it 'makes a request to the recorder' do expect(recorder).to receive(:snapshot).with(:_0, path: '/foo.html') @@ -277,8 +278,8 @@ rule_context.write(identifier_b) end - let(:identifier_a) { Nanoc::Identifier.new('/foo.html') } - let(:identifier_b) { Nanoc::Identifier.new('/bar.html') } + let(:identifier_a) { Nanoc::Core::Identifier.new('/foo.html') } + let(:identifier_b) { Nanoc::Core::Identifier.new('/bar.html') } it 'makes two requests to the recorder with unique snapshot names' do expect(recorder).to receive(:snapshot).with(:_0, path: '/foo.html') diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/rule_dsl/rules_collection_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/rule_dsl/rules_collection_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/rule_dsl/rules_collection_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/rule_dsl/rules_collection_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -17,13 +17,13 @@ end describe '#compilation_rule_for' do - let(:item) { Nanoc::Int::Item.new('content', {}, '/foo.md') } + subject { rules_collection.compilation_rule_for(rep) } - let(:rep) { Nanoc::Int::ItemRep.new(item, rep_name) } + let(:item) { Nanoc::Core::Item.new('content', {}, '/foo.md') } - let(:rep_name) { :default } + let(:rep) { Nanoc::Core::ItemRep.new(item, rep_name) } - subject { rules_collection.compilation_rule_for(rep) } + let(:rep_name) { :default } context 'no rules' do it 'is nil' do @@ -37,7 +37,7 @@ end let(:rule) do - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/bar.*'), :default, proc {}) + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/bar.*'), :default, proc {}) end it 'is nil' do @@ -52,11 +52,11 @@ end let(:rule_a) do - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/foo.*'), :default, proc {}) + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/foo.*'), :default, proc {}) end let(:rule_b) do - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/bar.*'), :default, proc {}) + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/bar.*'), :default, proc {}) end context 'rep name does not match' do @@ -82,15 +82,15 @@ end let(:rule_a) do - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/foo.*'), :default, proc {}) + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/foo.*'), :default, proc {}) end let(:rule_b) do - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/*.*'), :default, proc {}) + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/*.*'), :default, proc {}) end let(:rule_c) do - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/*.*'), :foo, proc {}) + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/*.*'), :foo, proc {}) end context 'no rep name matches' do @@ -118,10 +118,10 @@ end describe '#item_compilation_rules_for' do - let(:item) { Nanoc::Int::Item.new('content', {}, '/foo.md') } - subject { rules_collection.item_compilation_rules_for(item) } + let(:item) { Nanoc::Core::Item.new('content', {}, '/foo.md') } + context 'no rules' do it 'is none' do expect(subject).to be_empty @@ -134,7 +134,7 @@ end let(:rule) do - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/bar.*'), :default, proc {}) + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/bar.*'), :default, proc {}) end it 'is none' do @@ -149,11 +149,11 @@ end let(:rule_a) do - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/foo.*'), :default, proc {}) + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/foo.*'), :default, proc {}) end let(:rule_b) do - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/bar.*'), :default, proc {}) + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/bar.*'), :default, proc {}) end it 'is the single rule' do @@ -168,11 +168,11 @@ end let(:rule_a) do - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/foo.*'), :default, proc {}) + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/foo.*'), :default, proc {}) end let(:rule_b) do - Nanoc::RuleDSL::CompilationRule.new(Nanoc::Int::Pattern.from('/*.*'), :default, proc {}) + Nanoc::RuleDSL::CompilationRule.new(Nanoc::Core::Pattern.from('/*.*'), :default, proc {}) end it 'is all matching rule' do @@ -182,52 +182,52 @@ end describe '#routing_rules_for' do - let(:item) { Nanoc::Int::Item.new('content', {}, '/foo.md') } + subject { rules_collection.routing_rules_for(rep) } - let(:rep) { Nanoc::Int::ItemRep.new(item, :default) } + let(:item) { Nanoc::Core::Item.new('content', {}, '/foo.md') } - subject { rules_collection.routing_rules_for(rep) } + let(:rep) { Nanoc::Core::ItemRep.new(item, :default) } let(:rules) do [ # Matching item, matching rep Nanoc::RuleDSL::RoutingRule.new( - Nanoc::Int::Pattern.from('/foo.*'), :default, proc {}, snapshot_name: :a + Nanoc::Core::Pattern.from('/foo.*'), :default, proc {}, snapshot_name: :a ), Nanoc::RuleDSL::RoutingRule.new( - Nanoc::Int::Pattern.from('/foo.*'), :default, proc {}, snapshot_name: :b + Nanoc::Core::Pattern.from('/foo.*'), :default, proc {}, snapshot_name: :b ), # Matching item, non-matching rep Nanoc::RuleDSL::RoutingRule.new( - Nanoc::Int::Pattern.from('/foo.*'), :raw, proc {}, snapshot_name: :a + Nanoc::Core::Pattern.from('/foo.*'), :raw, proc {}, snapshot_name: :a ), Nanoc::RuleDSL::RoutingRule.new( - Nanoc::Int::Pattern.from('/foo.*'), :raw, proc {}, snapshot_name: :b + Nanoc::Core::Pattern.from('/foo.*'), :raw, proc {}, snapshot_name: :b ), # Non-matching item, matching rep Nanoc::RuleDSL::RoutingRule.new( - Nanoc::Int::Pattern.from('/bar.*'), :default, proc {}, snapshot_name: :a + Nanoc::Core::Pattern.from('/bar.*'), :default, proc {}, snapshot_name: :a ), Nanoc::RuleDSL::RoutingRule.new( - Nanoc::Int::Pattern.from('/bar.*'), :default, proc {}, snapshot_name: :b + Nanoc::Core::Pattern.from('/bar.*'), :default, proc {}, snapshot_name: :b ), # Non-matching item, non-matching rep Nanoc::RuleDSL::RoutingRule.new( - Nanoc::Int::Pattern.from('/bar.*'), :raw, proc {}, snapshot_name: :a + Nanoc::Core::Pattern.from('/bar.*'), :raw, proc {}, snapshot_name: :a ), Nanoc::RuleDSL::RoutingRule.new( - Nanoc::Int::Pattern.from('/bar.*'), :raw, proc {}, snapshot_name: :b + Nanoc::Core::Pattern.from('/bar.*'), :raw, proc {}, snapshot_name: :b ), # Matching item, matching rep, but not the first Nanoc::RuleDSL::RoutingRule.new( - Nanoc::Int::Pattern.from('/*.*'), :default, proc {}, snapshot_name: :a + Nanoc::Core::Pattern.from('/*.*'), :default, proc {}, snapshot_name: :a ), Nanoc::RuleDSL::RoutingRule.new( - Nanoc::Int::Pattern.from('/*.*'), :default, proc {}, snapshot_name: :b + Nanoc::Core::Pattern.from('/*.*'), :default, proc {}, snapshot_name: :b ), ] end @@ -247,15 +247,15 @@ end describe '#filter_for_layout' do - let(:layout) { Nanoc::Int::Layout.new('Some content', {}, '/foo.md') } - subject { rules_collection.filter_for_layout(layout) } + let(:layout) { Nanoc::Core::Layout.new('Some content', {}, '/foo.md') } + let(:mapping) { {} } before do mapping.each_pair do |key, value| - rules_collection.layout_filter_mapping[Nanoc::Int::Pattern.from(key)] = value + rules_collection.layout_filter_mapping[Nanoc::Core::Pattern.from(key)] = value end end diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/rule_dsl/rule_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/rule_dsl/rule_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/rule_dsl/rule_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/rule_dsl/rule_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -5,19 +5,21 @@ described_class.new(pattern, :xml, block) end - let(:pattern) { Nanoc::Int::Pattern.from(%r{/(.*)/(.*)/}) } + let(:pattern) { Nanoc::Core::Pattern.from(%r{/(.*)/(.*)/}) } let(:block) { proc {} } describe '#matches' do subject { rule.matches(identifier) } context 'does not match' do - let(:identifier) { Nanoc::Identifier.new('/moo/', type: :legacy) } + let(:identifier) { Nanoc::Core::Identifier.new('/moo/', type: :legacy) } + it { is_expected.to be_nil } end context 'matches' do - let(:identifier) { Nanoc::Identifier.new('/foo/bar/', type: :legacy) } + let(:identifier) { Nanoc::Core::Identifier.new('/foo/bar/', type: :legacy) } + it { is_expected.to eql(%w[foo bar]) } end end @@ -25,22 +27,24 @@ describe '#initialize' do subject { rule } - its(:rep_name) { is_expected.to eql(:xml) } + its(:rep_name) { is_expected.to be(:xml) } its(:pattern) { is_expected.to eql(pattern) } end describe '#applicable_to?' do subject { rule.applicable_to?(item) } - let(:item) { Nanoc::Int::Item.new('', {}, '/foo.md') } + let(:item) { Nanoc::Core::Item.new('', {}, '/foo.md') } context 'pattern matches' do - let(:pattern) { Nanoc::Int::Pattern.from(%r{^/foo.*}) } + let(:pattern) { Nanoc::Core::Pattern.from(%r{^/foo.*}) } + it { is_expected.to be } end context 'pattern does not match' do - let(:pattern) { Nanoc::Int::Pattern.from(%r{^/bar.*}) } + let(:pattern) { Nanoc::Core::Pattern.from(%r{^/bar.*}) } + it { is_expected.not_to be } end end @@ -51,15 +55,15 @@ proc { self } end - let(:item) { Nanoc::Int::Item.new('', {}, '/foo.md') } - let(:rep) { Nanoc::Int::ItemRep.new(item, :amazings) } + let(:item) { Nanoc::Core::Item.new('', {}, '/foo.md') } + let(:rep) { Nanoc::Core::ItemRep.new(item, :amazings) } - let(:site) { Nanoc::Int::Site.new(config: config, data_source: data_source, code_snippets: []) } - let(:data_source) { Nanoc::Int::InMemDataSource.new(items, layouts) } - let(:config) { Nanoc::Int::Configuration.new(dir: Dir.getwd) } - let(:view_context) { Nanoc::ViewContextForPreCompilation.new(items: items) } - let(:items) { Nanoc::Int::ItemCollection.new(config, []) } - let(:layouts) { Nanoc::Int::LayoutCollection.new(config, []) } + let(:site) { Nanoc::Core::Site.new(config: config, data_source: data_source, code_snippets: []) } + let(:data_source) { Nanoc::Core::InMemoryDataSource.new(items, layouts) } + let(:config) { Nanoc::Core::Configuration.new(dir: Dir.getwd) } + let(:view_context) { Nanoc::Core::ViewContextForPreCompilation.new(items: items) } + let(:items) { Nanoc::Core::ItemCollection.new(config, []) } + let(:layouts) { Nanoc::Core::LayoutCollection.new(config, []) } it 'makes rep accessible' do expect(subject.instance_eval { rep }._unwrap).to eql(rep) @@ -97,7 +101,7 @@ described_class.new(pattern, :xml, block) end - let(:pattern) { Nanoc::Int::Pattern.from(%r{/(.*)/(.*)/}) } + let(:pattern) { Nanoc::Core::Pattern.from(%r{/(.*)/(.*)/}) } let(:block) { proc {} } it_behaves_like 'a generic rule' @@ -106,16 +110,17 @@ context 'without snapshot_name' do subject { described_class.new(pattern, :xml, proc {}) } - its(:rep_name) { is_expected.to eql(:xml) } + its(:rep_name) { is_expected.to be(:xml) } its(:pattern) { is_expected.to eql(pattern) } its(:snapshot_name) { is_expected.to be_nil } end + context 'with snapshot_name' do subject { described_class.new(pattern, :xml, proc {}, snapshot_name: :donkey) } - its(:rep_name) { is_expected.to eql(:xml) } + its(:rep_name) { is_expected.to be(:xml) } its(:pattern) { is_expected.to eql(pattern) } - its(:snapshot_name) { is_expected.to eql(:donkey) } + its(:snapshot_name) { is_expected.to be(:donkey) } end end @@ -131,7 +136,7 @@ described_class.new(pattern, :xml, block) end - let(:pattern) { Nanoc::Int::Pattern.from(%r{/(.*)/(.*)/}) } + let(:pattern) { Nanoc::Core::Pattern.from(%r{/(.*)/(.*)/}) } let(:block) { proc {} } it_behaves_like 'a generic rule' diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/spec_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/spec_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/spec_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/spec_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,12 +1,12 @@ # frozen_string_literal: true describe Nanoc::Spec::HelperContext do + subject(:ctx) { described_class.new(helper) } + let(:helper) do Module.new {} end - subject(:ctx) { described_class.new(helper) } - it 'has no items by default' do # TODO: Add #empty? to item collection view expect(subject.items.size).to eq(0) @@ -51,12 +51,12 @@ end describe '#create_rep' do + subject { ctx.create_rep(ctx.items['/foo.md'], '/foo.html') } + before do ctx.create_item('foo', {}, '/foo.md') end - subject { ctx.create_rep(ctx.items['/foo.md'], '/foo.html') } - it 'creates rep' do expect { subject } .to change { ctx.items['/foo.md'].reps.size } diff -Nru nanoc-4.11.0/nanoc/spec/nanoc/version_spec.rb nanoc-4.11.14/nanoc/spec/nanoc/version_spec.rb --- nanoc-4.11.0/nanoc/spec/nanoc/version_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/nanoc/version_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +describe Nanoc::VERSION do + it 'is the same as Nanoc::Core::VERSION' do + expect(Nanoc::VERSION).to eq(Nanoc::Core::VERSION) + end +end diff -Nru nanoc-4.11.0/nanoc/spec/regression_filenames_spec.rb nanoc-4.11.14/nanoc/spec/regression_filenames_spec.rb --- nanoc-4.11.0/nanoc/spec/regression_filenames_spec.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/spec/regression_filenames_spec.rb 2019-11-10 09:34:31.000000000 +0000 @@ -10,7 +10,7 @@ .map { |fn| File.readlines(fn).find { |l| l =~ /^describe/ }.match(/GH-(\d+)/)[1] } end - it 'should have the proper filenames' do + it 'has the proper filenames' do regression_test_filenames.zip(regression_test_numbers) do |fn, num| expect(fn).to match(/gh_#{num}[a-z]*_spec/), "#{fn} has the wrong name in its #define block" end diff -Nru nanoc-4.11.0/nanoc/test/base/test_compiler.rb nanoc-4.11.14/nanoc/test/base/test_compiler.rb --- nanoc-4.11.0/nanoc/test/base/test_compiler.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/base/test_compiler.rb 2019-11-10 09:34:31.000000000 +0000 @@ -2,7 +2,7 @@ require 'helper' -class Nanoc::Int::CompilerTest < Nanoc::TestCase +class Nanoc::Core::CompilerTest < Nanoc::TestCase def test_compile_rep_should_write_proper_snapshots_real with_site do |_site| File.write('content/moo.txt', '<%= 1 %> <%%= 2 %> <%%%= 3 %>') @@ -35,8 +35,8 @@ io.write "layout '/**/*', :erb\n" end - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile + site = Nanoc::Core::SiteLoader.new.new_from_cwd + Nanoc::Core::Compiler.compile(site) assert File.file?('output/moo-raw.txt') assert File.file?('output/moo-pre.txt') @@ -51,7 +51,7 @@ def test_compile_with_no_reps with_site do |site| - site.compile + Nanoc::Core::Compiler.compile(site) assert Dir['output/*'].empty? end @@ -61,8 +61,8 @@ with_site do |_site| File.open('content/index.html', 'w') { |io| io.write('o hello') } - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile + site = Nanoc::Core::SiteLoader.new.new_from_cwd + Nanoc::Core::Compiler.compile(site) assert Dir['output/*'].size == 1 assert File.file?('output/index.html') @@ -75,8 +75,8 @@ File.open('content/foo.html', 'w') { |io| io.write('o hai') } File.open('content/bar.html', 'w') { |io| io.write('o bai') } - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile + site = Nanoc::Core::SiteLoader.new.new_from_cwd + Nanoc::Core::Compiler.compile(site) assert Dir['output/*'].size == 2 assert File.file?('output/foo/index.html') @@ -95,8 +95,8 @@ io.write('manatee') end - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile + site = Nanoc::Core::SiteLoader.new.new_from_cwd + Nanoc::Core::Compiler.compile(site) assert Dir['output/*'].size == 2 assert File.file?('output/foo/index.html') @@ -115,9 +115,9 @@ io.write('<%= @items.find { |i| i.identifier == "/foo/" }.compiled_content %>') end - site = Nanoc::Int::SiteLoader.new.new_from_cwd - assert_raises Nanoc::Int::Errors::DependencyCycle do - site.compile + site = Nanoc::Core::SiteLoader.new.new_from_cwd + assert_raises Nanoc::Core::Errors::DependencyCycle do + Nanoc::Core::Compiler.compile(site) end end end @@ -141,9 +141,9 @@ end # Create site - site = Nanoc::Int::SiteLoader.new.new_from_cwd + site = Nanoc::Core::SiteLoader.new.new_from_cwd error = assert_raises(Nanoc::Error) do - site.compile + Nanoc::Core::Compiler.compile(site) end assert_match(/^The path returned for the.*does not start with a slash. Please ensure that all routing rules return a path that starts with a slash./, error.message) end @@ -172,8 +172,8 @@ end # Compile - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile + site = Nanoc::Core::SiteLoader.new.new_from_cwd + Nanoc::Core::Compiler.compile(site) # Check assert_equal '[[[<%= @item.compiled_content(:snapshot => :aaa) %>]]]', File.read('output/index.html') @@ -205,8 +205,8 @@ end # Compile - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile + site = Nanoc::Core::SiteLoader.new.new_from_cwd + Nanoc::Core::Compiler.compile(site) # Check assert_equal '[stuff]', File.read('output/a/index.html') @@ -222,8 +222,8 @@ end # Compile - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile + site = Nanoc::Core::SiteLoader.new.new_from_cwd + Nanoc::Core::Compiler.compile(site) # Check assert Dir['tmp/text_items/*'].empty? diff -Nru nanoc-4.11.0/nanoc/test/base/test_site.rb nanoc-4.11.14/nanoc/test/base/test_site.rb --- nanoc-4.11.0/nanoc/test/base/test_site.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/base/test_site.rb 2019-11-10 09:34:31.000000000 +0000 @@ -4,26 +4,26 @@ class Nanoc::Int::SiteTest < Nanoc::TestCase def test_initialize_with_dir_without_config_yaml - assert_raises(Nanoc::Int::ConfigLoader::NoConfigFileFoundError) do - Nanoc::Int::SiteLoader.new.new_from_cwd + assert_raises(Nanoc::Core::ConfigLoader::NoConfigFileFoundError) do + Nanoc::Core::SiteLoader.new.new_from_cwd end end def test_initialize_with_dir_with_config_yaml File.open('config.yaml', 'w') { |io| io.write('output_dir: public_html') } - site = Nanoc::Int::SiteLoader.new.new_from_cwd + site = Nanoc::Core::SiteLoader.new.new_from_cwd assert_equal Dir.getwd + '/public_html', site.config.output_dir end def test_initialize_with_dir_with_nanoc_yaml File.open('nanoc.yaml', 'w') { |io| io.write('output_dir: public_html') } - site = Nanoc::Int::SiteLoader.new.new_from_cwd + site = Nanoc::Core::SiteLoader.new.new_from_cwd assert_equal Dir.getwd + '/public_html', site.config.output_dir end def test_initialize_with_incomplete_data_source_config File.open('nanoc.yaml', 'w') { |io| io.write('data_sources: [{ items_root: "/bar/" }]') } - site = Nanoc::Int::SiteLoader.new.new_from_cwd + site = Nanoc::Core::SiteLoader.new.new_from_cwd assert_equal('filesystem', site.config[:data_sources][0][:type]) assert_equal('/bar/', site.config[:data_sources][0][:items_root]) assert_equal('/', site.config[:data_sources][0][:layouts_root]) @@ -56,7 +56,7 @@ end end - site = Nanoc::Int::SiteLoader.new.new_from_cwd + site = Nanoc::Core::SiteLoader.new.new_from_cwd assert_nil site.config[:parent_config_file] assert site.config[:enable_output_diff] assert_equal 'bar', site.config[:foo] @@ -70,8 +70,8 @@ EOF end - assert_raises(Nanoc::Int::ConfigLoader::NoParentConfigFileFoundError) do - Nanoc::Int::SiteLoader.new.new_from_cwd + assert_raises(Nanoc::Core::ConfigLoader::NoParentConfigFileFoundError) do + Nanoc::Core::SiteLoader.new.new_from_cwd end end @@ -90,8 +90,8 @@ end end - assert_raises(Nanoc::Int::ConfigLoader::CyclicalConfigFileError) do - Nanoc::Int::SiteLoader.new.new_from_cwd + assert_raises(Nanoc::Core::ConfigLoader::CyclicalConfigFileError) do + Nanoc::Core::SiteLoader.new.new_from_cwd end end @@ -104,14 +104,14 @@ File.open('content/foo_bar.md', 'w') { |io| io << 'asdf' } File.open('layouts/detail.erb', 'w') { |io| io << 'asdf' } - site = Nanoc::Int::SiteLoader.new.new_from_cwd + site = Nanoc::Core::SiteLoader.new.new_from_cwd site.items.each do |item| - assert_equal Nanoc::Identifier, item.identifier.class + assert_equal Nanoc::Core::Identifier, item.identifier.class end site.layouts.each do |layout| - assert_equal Nanoc::Identifier, layout.identifier.class + assert_equal Nanoc::Core::Identifier, layout.identifier.class end end end @@ -122,8 +122,8 @@ FileUtils.mkdir_p('content/sam') File.open('content/sam/index.html', 'w') { |io| io.write('I am Sam, too!') } - assert_raises(Nanoc::Int::Errors::DuplicateIdentifier) do - Nanoc::Int::SiteLoader.new.new_from_cwd + assert_raises(Nanoc::Core::Site::DuplicateIdentifierError) do + Nanoc::Core::SiteLoader.new.new_from_cwd end end end @@ -134,8 +134,8 @@ FileUtils.mkdir_p('layouts/sam') File.open('layouts/sam/index.html', 'w') { |io| io.write('I am Sam, too!') } - assert_raises(Nanoc::Int::Errors::DuplicateIdentifier) do - Nanoc::Int::SiteLoader.new.new_from_cwd + assert_raises(Nanoc::Core::Site::DuplicateIdentifierError) do + Nanoc::Core::SiteLoader.new.new_from_cwd end end end diff -Nru nanoc-4.11.0/nanoc/test/checking/checks/test_internal_links.rb nanoc-4.11.14/nanoc/test/checking/checks/test_internal_links.rb --- nanoc-4.11.0/nanoc/test/checking/checks/test_internal_links.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/checking/checks/test_internal_links.rb 2019-11-10 09:34:31.000000000 +0000 @@ -3,13 +3,12 @@ require 'helper' class Nanoc::Checking::Checks::InternalLinksTest < Nanoc::TestCase - def test_run + def test_no_issues with_site do |site| # Create files FileUtils.mkdir_p('output') - FileUtils.mkdir_p('output/stuff') - File.open('output/foo.txt', 'w') { |io| io.write('broken') } - File.open('output/bar.html', 'w') { |io| io.write('not broken') } + File.open('output/foo.xhtml', 'w') { |io| io.write('not broken') } + File.open('output/bar.html', 'w') { |io| io.write('not broken') } # Create check check = Nanoc::Checking::Checks::InternalLinks.create(site) @@ -20,6 +19,21 @@ end end + def test_has_issues + with_site do |site| + # Create files + FileUtils.mkdir_p('output') + File.open('output/foo.html', 'w') { |io| io.write('broken') } + + # Create check + check = Nanoc::Checking::Checks::InternalLinks.create(site) + check.run + + # Test + refute check.issues.empty? + end + end + def test_resource_uris with_site do |site| # Create files @@ -38,7 +52,6 @@ def test_valid? with_site do |site| # Create files - FileUtils.mkdir_p('output') FileUtils.mkdir_p('output/stuff') File.open('output/origin', 'w') { |io| io.write('hi') } File.open('output/foo', 'w') { |io| io.write('hi') } @@ -48,12 +61,12 @@ check = Nanoc::Checking::Checks::InternalLinks.create(site) # Test - assert check.send(:valid?, 'foo', 'output/origin') - assert check.send(:valid?, 'origin', 'output/origin') - assert check.send(:valid?, 'stuff/blah', 'output/origin') - assert check.send(:valid?, '/foo', 'output/origin') - assert check.send(:valid?, '/origin', 'output/origin') - assert check.send(:valid?, '/stuff/blah', 'output/origin') + assert check.send(:valid?, path_to_file_uri('foo', site), 'output/origin') + assert check.send(:valid?, path_to_file_uri('origin', site), 'output/origin') + assert check.send(:valid?, path_to_file_uri('stuff/blah', site), 'output/origin') + assert check.send(:valid?, path_to_file_uri('/foo', site), 'output/origin') + assert check.send(:valid?, path_to_file_uri('/origin', site), 'output/origin') + assert check.send(:valid?, path_to_file_uri('/stuff/blah', site), 'output/origin') end end @@ -64,7 +77,8 @@ check = Nanoc::Checking::Checks::InternalLinks.create(site) - assert check.send(:valid?, 'stuff/right?foo=123', 'output/origin') + assert check.send(:valid?, '/stuff/right?foo=123', 'output/origin') + assert check.send(:valid?, 'stuff/right?foo=456', 'output/origin') refute check.send(:valid?, 'stuff/wrong?foo=123', 'output/origin') end end @@ -75,9 +89,9 @@ check = Nanoc::Checking::Checks::InternalLinks.create(site) - assert check.send(:valid?, '/excluded1', 'output/origin') - assert check.send(:valid?, '/excluded2', 'output/origin') - assert !check.send(:valid?, '/excluded_not', 'output/origin') + assert check.send(:valid?, path_to_file_uri('/excluded1', site), 'output/origin') + assert check.send(:valid?, path_to_file_uri('/excluded2', site), 'output/origin') + refute check.send(:valid?, path_to_file_uri('/excluded_not', site), 'output/origin') end end @@ -87,9 +101,9 @@ check = Nanoc::Checking::Checks::InternalLinks.create(site) - assert check.send(:valid?, '/excluded1', 'output/origin') - assert check.send(:valid?, '/excluded2', 'output/origin') - assert !check.send(:valid?, '/excluded_not', 'output/origin') + assert check.send(:valid?, path_to_file_uri('/excluded1', site), 'output/origin') + assert check.send(:valid?, path_to_file_uri('/excluded2/two', site), 'output/origin') + assert !check.send(:valid?, path_to_file_uri('/excluded_not', site), 'output/origin') end end @@ -99,8 +113,8 @@ check = Nanoc::Checking::Checks::InternalLinks.create(site) - assert check.send(:valid?, '/foo', 'output/excluded') - assert !check.send(:valid?, '/foo', 'output/not_excluded') + assert check.send(:valid?, path_to_file_uri('/foo', site), 'output/excluded') + assert !check.send(:valid?, path_to_file_uri('/foo', site), 'output/not_excluded') end end @@ -111,8 +125,36 @@ check = Nanoc::Checking::Checks::InternalLinks.create(site) - assert check.send(:valid?, 'stuff/right%20foo', 'output/origin') - refute check.send(:valid?, 'stuff/wrong%20foo', 'output/origin') + assert check.send(:valid?, path_to_file_uri('stuff/right%20foo', site), 'output/origin') + refute check.send(:valid?, path_to_file_uri('stuff/wrong%20foo', site), 'output/origin') + end + end + + def test_deeply_nesten_relative_paths + with_site do |site| + FileUtils.mkdir_p('output/one/two/three') + File.open('output/one/two/three/a.html', 'w') { |io| io.write('b') } + File.open('output/one/b.html', 'w') { |io| io.write('a') } + File.open('output/one/c.html', 'w') { |io| io.write('c') } + + check = Nanoc::Checking::Checks::InternalLinks.create(site) + check.run + + assert check.issues.empty? + end + end + + def test_protocol_relative_url + # Protocol-relative URLs are not internal links. + + with_site do |site| + FileUtils.mkdir_p('output') + File.write('output/a.html', 'broken') + + check = Nanoc::Checking::Checks::InternalLinks.create(site) + check.run + + assert check.issues.empty? end end end diff -Nru nanoc-4.11.0/nanoc/test/checking/checks/test_mixed_content.rb nanoc-4.11.14/nanoc/test/checking/checks/test_mixed_content.rb --- nanoc-4.11.0/nanoc/test/checking/checks/test_mixed_content.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/checking/checks/test_mixed_content.rb 2019-11-10 09:34:31.000000000 +0000 @@ -126,7 +126,6 @@ def test_http_content with_site do |site| create_output_file('foo.html', [ - '', '', '', '', @@ -139,7 +138,7 @@ check.run issues = check.issues.to_a - assert_equal 8, issues.count + assert_equal 7, issues.count descriptions = issues.map(&:description) issues.each do |issue| @@ -150,7 +149,7 @@ # `assert_include` helper to avoid asserting those details assert_include descriptions, 'mixed content include: http://nanoc.ws/logo.png' - assert_include descriptions, 'mixed content include: HTTP://nanoc.ws/logo.png' + refute_includes descriptions, 'mixed content include: HTTP://nanoc.ws/logo.png' assert_include descriptions, 'mixed content include: http://nanoc.ws/style.css' diff -Nru nanoc-4.11.0/nanoc/test/checking/checks/test_stale.rb nanoc-4.11.14/nanoc/test/checking/checks/test_stale.rb --- nanoc-4.11.0/nanoc/test/checking/checks/test_stale.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/checking/checks/test_stale.rb 2019-11-10 09:34:31.000000000 +0000 @@ -8,7 +8,7 @@ end def calc_issues - site = Nanoc::Int::SiteLoader.new.new_from_cwd + site = Nanoc::Core::SiteLoader.new.new_from_cwd runner = Nanoc::Checking::Runner.new(site) runner.send(:run_checks, [check_class]) end diff -Nru nanoc-4.11.0/nanoc/test/cli/commands/test_check.rb nanoc-4.11.14/nanoc/test/cli/commands/test_check.rb --- nanoc-4.11.0/nanoc/test/cli/commands/test_check.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/cli/commands/test_check.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -require 'helper' - -class Nanoc::CLI::Commands::CheckTest < Nanoc::TestCase - def test_check_stale - with_site do |_site| - FileUtils.mkdir_p('output') - - # Should not raise now - Nanoc::CLI.run %w[check stale] - - # Should raise now - File.open('output/blah.html', 'w') { |io| io.write 'moo' } - assert_raises Nanoc::Int::Errors::GenericTrivial do - Nanoc::CLI.run %w[check stale] - end - end - end -end diff -Nru nanoc-4.11.0/nanoc/test/cli/commands/test_compile.rb nanoc-4.11.14/nanoc/test/cli/commands/test_compile.rb --- nanoc-4.11.0/nanoc/test/cli/commands/test_compile.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/cli/commands/test_compile.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,199 +0,0 @@ -# frozen_string_literal: true - -require 'helper' - -class Nanoc::CLI::Commands::CompileTest < Nanoc::TestCase - def test_profiling_information - with_site do |_site| - File.open('content/foo.md', 'w') { |io| io << 'asdf' } - File.open('content/bar.md', 'w') { |io| io << 'asdf' } - File.open('content/baz.md', 'w') { |io| io << 'asdf' } - - File.open('Rules', 'w') do |io| - io.write "compile '*' do\n" - io.write " filter :erb\n" - io.write "end\n" - io.write "\n" - io.write "route '*' do\n" - io.write " if item.binary?\n" - io.write " item.identifier.chop + '.' + item[:extension]\n" - io.write " else\n" - io.write " item.identifier + 'index.html'\n" - io.write " end\n" - io.write "end\n" - io.write "\n" - io.write "layout '*', :erb\n" - end - - Nanoc::CLI.run %w[compile --verbose] - end - end - - def test_auto_prune - with_site do |_site| - File.open('content/foo.md', 'w') { |io| io << 'asdf' } - File.open('content/bar.md', 'w') { |io| io << 'asdf' } - File.open('content/baz.md', 'w') { |io| io << 'asdf' } - - File.open('Rules', 'w') do |io| - io.write "compile '*' do\n" - io.write " filter :erb\n" - io.write "end\n" - io.write "\n" - io.write "route '*' do\n" - io.write " if item.binary?\n" - io.write " item.identifier.chop + '.' + item[:extension]\n" - io.write " else\n" - io.write " item.identifier + 'index.html'\n" - io.write " end\n" - io.write "end\n" - io.write "\n" - io.write "layout '*', :erb\n" - end - - File.open('nanoc.yaml', 'w') do |io| - io.write "string_pattern_type: legacy\n" - io.write "prune:\n" - io.write " auto_prune: false\n" - end - - File.open('output/stray.html', 'w') do |io| - io.write 'I am a stray file and I am about to be deleted!' - end - - assert File.file?('output/stray.html') - Nanoc::CLI.run %w[compile] - assert File.file?('output/stray.html') - - File.open('nanoc.yaml', 'w') do |io| - io.write "string_pattern_type: legacy\n" - io.write "prune:\n" - io.write " auto_prune: true\n" - end - - assert File.file?('output/stray.html') - Nanoc::CLI.run %w[compile] - refute File.file?('output/stray.html') - end - end - - def test_auto_prune_with_exclude - with_site do |_site| - File.open('content/foo.md', 'w') { |io| io << 'asdf' } - File.open('content/bar.md', 'w') { |io| io << 'asdf' } - File.open('content/baz.md', 'w') { |io| io << 'asdf' } - - File.open('Rules', 'w') do |io| - io.write "compile '*' do\n" - io.write " filter :erb\n" - io.write "end\n" - io.write "\n" - io.write "route '*' do\n" - io.write " if item.binary?\n" - io.write " item.identifier.chop + '.' + item[:extension]\n" - io.write " else\n" - io.write " item.identifier + 'index.html'\n" - io.write " end\n" - io.write "end\n" - io.write "\n" - io.write "layout '*', :erb\n" - end - - Dir.mkdir('output/excluded_dir') - - File.open('nanoc.yaml', 'w') do |io| - io.write "string_pattern_type: legacy\n" - io.write "prune:\n" - io.write " auto_prune: false\n" - end - - File.open('output/stray.html', 'w') do |io| - io.write 'I am a stray file and I am about to be deleted!' - end - - assert File.file?('output/stray.html') - Nanoc::CLI.run %w[compile] - assert File.file?('output/stray.html') - - File.open('nanoc.yaml', 'w') do |io| - io.write "string_pattern_type: legacy\n" - io.write "prune:\n" - io.write " auto_prune: true\n" - io.write " exclude: [ 'excluded_dir' ]\n" - end - - assert File.file?('output/stray.html') - Nanoc::CLI.run %w[compile] - refute File.file?('output/stray.html') - assert File.directory?('output/excluded_dir'), 'excluded_dir should still be there' - end - end - - def test_file_action_printer_normal - # Create data - item = Nanoc::Int::Item.new('content', {}, '/a') - rep = Nanoc::Int::ItemRep.new(item, :default) - rep.raw_paths[:last] = ['output/foo.txt'] - rep.compiled = true - - # Listen - listener = new_file_action_printer([rep]) - listener.start - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - Nanoc::Int::NotificationCenter.post(:rep_write_ended, rep, false, rep.raw_path, false, true) - listener.stop - - # Check - assert_equal 1, listener.events.size - assert_equal :high, listener.events[0][:level] - assert_equal :update, listener.events[0][:action] - assert_equal 'output/foo.txt', listener.events[0][:path] - assert_in_delta 0.0, listener.events[0][:duration], 1.0 - end - - def test_file_action_printer_skip - # Create data - item = Nanoc::Int::Item.new('content', {}, '/a') - rep = Nanoc::Int::ItemRep.new(item, :default) - rep.raw_paths[:last] = ['output/foo.txt'] - - # Listen - listener = new_file_action_printer([rep]) - listener.start - Nanoc::Int::NotificationCenter.post(:compilation_started, rep) - listener.stop - - # Check - assert_equal 1, listener.events.size - assert_equal :low, listener.events[0][:level] - assert_equal :skip, listener.events[0][:action] - assert_equal 'output/foo.txt', listener.events[0][:path] - assert_nil listener.events[0][:duration] - end - - def new_file_action_printer(reps) - # Ensure CLI is loaded - begin - Nanoc::CLI.run(%w[help %]) - rescue SystemExit - end - - listener = Nanoc::CLI::Commands::CompileListeners::FileActionPrinter.new(reps: reps) - - def listener.log(level, action, path, duration) - @events ||= [] - @events << { - level: level, - action: action, - path: path, - duration: duration, - } - end - - def listener.events - @events - end - - listener - end -end diff -Nru nanoc-4.11.0/nanoc/test/cli/commands/test_create_site.rb nanoc-4.11.14/nanoc/test/cli/commands/test_create_site.rb --- nanoc-4.11.0/nanoc/test/cli/commands/test_create_site.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/cli/commands/test_create_site.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -# frozen_string_literal: true - -require 'helper' - -class Nanoc::CLI::Commands::CreateSiteTest < Nanoc::TestCase - def test_create_site_with_existing_name - Nanoc::CLI.run %w[create_site foo] - assert_raises(::Nanoc::Int::Errors::GenericTrivial) do - Nanoc::CLI.run %w[create_site foo] - end - end - - def test_can_compile_new_site - Nanoc::CLI.run %w[create_site foo] - - FileUtils.cd('foo') do - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile - end - end - - def test_can_compile_new_site_in_current_directory - FileUtils.mkdir('foo') - - FileUtils.cd('foo') do - Nanoc::CLI.run %w[create_site ./] - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile - end - end - - def test_can_compile_new_site_with_binary_items - Nanoc::CLI.run %w[create_site foo] - - FileUtils.cd('foo') do - File.open('content/blah', 'w') { |io| io << 'asdf' } - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile - - assert File.file?('output/blah') - end - end - - def test_can_compile_site_in_nonempty_directory - FileUtils.mkdir('foo') - FileUtils.touch(File.join('foo', 'SomeFile.txt')) - Nanoc::CLI.run %w[create_site foo --force] - - FileUtils.cd('foo') do - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile - end - end - - def test_compiled_site_output - FileUtils.mkdir('foo') - FileUtils.touch(File.join('foo', 'SomeFile.txt')) - Nanoc::CLI.run %w[create_site foo --force] - - FileUtils.cd('foo') do - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile - - assert File.file?('output/index.html') - end - end - - def test_default_encoding - unless defined?(Encoding) - skip 'No Encoding class' - return - end - - original_encoding = Encoding.default_external - Encoding.default_external = 'ISO-8859-1' # ew! - - Nanoc::CLI.run %w[create_site foo] - - FileUtils.cd('foo') do - # Try with encoding = default encoding = utf-8 - File.open('content/index.html', 'w') { |io| io.write('Hello ' + 0xD6.chr + "!\n") } - exception = assert_raises(Nanoc::DataSources::Filesystem::Errors::InvalidEncoding) do - Nanoc::Int::SiteLoader.new.new_from_cwd - end - assert_equal 'Could not read content/index.html because the file is not valid UTF-8.', exception.message - - # Try with encoding = specific - File.open('nanoc.yaml', 'w') do |io| - io.write("string_pattern_type: glob\n") - io.write("data_sources:\n") - io.write(" -\n") - io.write(" type: filesystem\n") - io.write(" identifier_type: full\n") - end - site = Nanoc::Int::SiteLoader.new.new_from_cwd - site.compile - end - FileUtils - ensure - Encoding.default_external = original_encoding - end - - def test_new_site_has_correct_stylesheets - Nanoc::CLI.run %w[create_site foo] - FileUtils.cd('foo') do - Nanoc::CLI.run %w[compile] - - assert File.file?('content/stylesheet.css') - assert_match(/\/stylesheet.css/, File.read('output/index.html')) - end - end - - def test_new_site_prunes_by_default - FileUtils.mkdir('foo') - FileUtils.touch(File.join('foo', 'SomeFile.txt')) - Nanoc::CLI.run %w[create_site foo --force] - - FileUtils.cd('foo') do - File.write('output/blah.txt', 'stuff') - - Nanoc::CLI.run %w[compile] - - refute File.file?('output/blah.txt') - end - end -end diff -Nru nanoc-4.11.0/nanoc/test/cli/commands/test_help.rb nanoc-4.11.14/nanoc/test/cli/commands/test_help.rb --- nanoc-4.11.0/nanoc/test/cli/commands/test_help.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/cli/commands/test_help.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -require 'helper' - -class Nanoc::CLI::Commands::HelpTest < Nanoc::TestCase - def test_run - Nanoc::CLI.run %w[help] - Nanoc::CLI.run %w[help co] - end -end diff -Nru nanoc-4.11.0/nanoc/test/cli/commands/test_prune.rb nanoc-4.11.14/nanoc/test/cli/commands/test_prune.rb --- nanoc-4.11.0/nanoc/test/cli/commands/test_prune.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/cli/commands/test_prune.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,162 +0,0 @@ -# frozen_string_literal: true - -require 'helper' - -class Nanoc::CLI::Commands::PruneTest < Nanoc::TestCase - def test_run_without_yes - with_site do |_site| - # Set output dir - File.open('nanoc.yaml', 'w') { |io| io.write "output_dir: output2\nstring_pattern_type: legacy\n" } - FileUtils.mkdir_p('output2') - - # Create source files - File.open('content/index.html', 'w') { |io| io.write 'stuff' } - - # Create output files - File.open('output2/foo.html', 'w') { |io| io.write 'this is a foo.' } - File.open('output2/index.html', 'w') { |io| io.write 'this is a index.' } - - assert_raises SystemExit do - Nanoc::CLI.run %w[prune] - end - - assert File.file?('output2/index.html') - assert File.file?('output2/foo.html') - end - end - - def test_run_with_yes - with_site do |_site| - # Set output dir - File.open('nanoc.yaml', 'w') do |io| - io << 'output_dir: output2' << "\n" - io << 'string_pattern_type: legacy' << "\n" - io << 'data_sources:' << "\n" - io << ' -' << "\n" - io << ' type: filesystem' << "\n" - io << ' identifier_type: legacy' << "\n" - end - FileUtils.mkdir_p('output2') - - # Create source files - File.open('content/index.html', 'w') { |io| io.write 'stuff' } - - # Create output files - File.open('output2/foo.html', 'w') { |io| io.write 'this is a foo.' } - File.open('output2/index.html', 'w') { |io| io.write 'this is a index.' } - - Nanoc::CLI.run %w[prune --yes] - - assert File.file?('output2/index.html') - assert !File.file?('output2/foo.html') - end - end - - def test_run_with_dry_run - with_site do |_site| - # Set output dir - File.open('nanoc.yaml', 'w') { |io| io.write "string_pattern_type: legacy\noutput_dir: output2" } - FileUtils.mkdir_p('output2') - - # Create source files - File.open('content/index.html', 'w') { |io| io.write 'stuff' } - - # Create output files - File.open('output2/foo.html', 'w') { |io| io.write 'this is a foo.' } - File.open('output2/index.html', 'w') { |io| io.write 'this is a index.' } - - Nanoc::CLI.run %w[prune --dry-run] - - assert File.file?('output2/index.html') - assert File.file?('output2/foo.html') - end - end - - def test_run_with_exclude - with_site do |_site| - # Set output dir - File.open('nanoc.yaml', 'w') do |io| - io << 'prune:' << "\n" - io << ' exclude: [ "good-dir", "good-file.html" ]' << "\n" - io << 'string_pattern_type: legacy' << "\n" - io << 'data_sources:' << "\n" - io << ' -' << "\n" - io << ' type: filesystem' << "\n" - io << ' identifier_type: legacy' << "\n" - end - FileUtils.mkdir_p('output') - - # Create source files - File.open('content/index.html', 'w') { |io| io.write 'stuff' } - - # Create output files - FileUtils.mkdir_p('output/good-dir') - FileUtils.mkdir_p('output/bad-dir') - File.open('output/good-file.html', 'w') { |io| io.write 'stuff' } - File.open('output/good-dir/blah', 'w') { |io| io.write 'stuff' } - File.open('output/bad-file.html', 'w') { |io| io.write 'stuff' } - File.open('output/bad-dir/blah', 'w') { |io| io.write 'stuff' } - File.open('output/index.html', 'w') { |io| io.write 'stuff' } - - Nanoc::CLI.run %w[prune --yes] - - assert File.file?('output/index.html') - assert File.file?('output/good-dir/blah') - assert File.file?('output/good-file.html') - assert !File.file?('output/bad-dir/blah') - assert !File.file?('output/bad-file.html') - end - end - - def test_run_with_symlink_to_output_dir - skip_unless_symlinks_supported - - if defined?(JRUBY_VERSION) - skip 'JRuby has buggy File.find behavior (see https://github.com/jruby/jruby/issues/1647)' - end - - if Nanoc.on_windows? - skip 'Symlinks to output dirs are currently not supported on Windows.' - end - - with_site do |_site| - # Set output dir - FileUtils.rm_rf('output') - FileUtils.mkdir_p('output-real') - File.symlink('output-real', 'output') - - # Create source files - File.open('content/index.html', 'w') { |io| io.write 'stuff' } - - # Create output files - FileUtils.mkdir_p('output-real/some-dir') - File.open('output-real/some-file.html', 'w') { |io| io.write 'stuff' } - File.open('output-real/index.html', 'w') { |io| io.write 'stuff' } - - Nanoc::CLI.run %w[prune --yes] - - assert File.file?('output-real/index.html') - assert !File.directory?('output-real/some-dir') - assert !File.file?('output-real/some-file.html') - end - end - - def test_run_with_nested_empty_dirs - with_site do |_site| - # Set output dir - File.open('nanoc.yaml', 'w') { |io| io.write 'output_dir: output' } - FileUtils.mkdir_p('output') - - # Create output files - FileUtils.mkdir_p('output/a/b/c') - File.open('output/a/b/c/index.html', 'w') { |io| io.write 'stuff' } - - Nanoc::CLI.run %w[prune --yes] - - assert !File.file?('output/a/b/c/index.html') - assert !File.directory?('output/a/b/c') - assert !File.directory?('output/a/b') - assert !File.directory?('output/a') - end - end -end diff -Nru nanoc-4.11.0/nanoc/test/cli/test_cleaning_stream.rb nanoc-4.11.14/nanoc/test/cli/test_cleaning_stream.rb --- nanoc-4.11.0/nanoc/test/cli/test_cleaning_stream.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/cli/test_cleaning_stream.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -# frozen_string_literal: true - -require 'helper' - -class Nanoc::CLI::CleaningStreamTest < Nanoc::TestCase - class Stream - attr_accessor :called_methods - - def initialize - @called_methods = [] - end - - def method_missing(symbol, *_args) # rubocop:disable Style/MethodMissingSuper - @called_methods << symbol - end - - def respond_to_missing?(*_args) - true - end - end - - def test_forward - methods = %i[write << tty? tty? flush tell print puts string reopen exist? exists? close] - - s = Stream.new - cs = Nanoc::CLI::CleaningStream.new(s) - - cs.write('aaa') - cs << 'bb' - cs.tty? - cs.isatty - cs.flush - cs.tell - cs.print('cc') - cs.puts('dd') - cs.string - cs.reopen('/dev/null', 'r') - cs.exist? - cs.exists? - cs.close - - methods.each do |m| - assert s.called_methods.include?(m), "expected #{m} to be called" - end - end - - def test_forward_tty_cached - s = Stream.new - cs = Nanoc::CLI::CleaningStream.new(s) - - cs.tty? - cs.isatty - - assert_equal [:tty?], s.called_methods - end - - def test_works_with_logger - require 'logger' - stream = StringIO.new - cleaning_stream = Nanoc::CLI::CleaningStream.new(stream) - logger = Logger.new(cleaning_stream) - logger.info('Some info') - logger.warn('Something could start going wrong!') - end - - def test_broken_pipe - stream = StringIO.new - def stream.write(_str) - raise Errno::EPIPE.new - end - - cleaning_stream = Nanoc::CLI::CleaningStream.new(stream) - cleaning_stream.write('lol') - end - - def test_non_string - obj = Object.new - def obj.to_s - 'Hello… world!' - end - - stream = StringIO.new - cleaning_stream = Nanoc::CLI::CleaningStream.new(stream) - cleaning_stream << obj - assert_equal 'Hello… world!', stream.string - end - - def test_invalid_string - s = [128].pack('C').force_encoding('UTF-8') - stream = StringIO.new - cleaning_stream = Nanoc::CLI::CleaningStream.new(stream) - cleaning_stream << s - assert_equal "\xef\xbf\xbd", stream.string - end -end diff -Nru nanoc-4.11.0/nanoc/test/cli/test_cli.rb nanoc-4.11.14/nanoc/test/cli/test_cli.rb --- nanoc-4.11.0/nanoc/test/cli/test_cli.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/cli/test_cli.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,195 +0,0 @@ -# frozen_string_literal: true - -require 'helper' - -class Nanoc::CLITest < Nanoc::TestCase - COMMAND_CODE = <<~EOS - usage '_test [options]' - summary 'meh' - description 'longer meh' - - run do |opts, args, cmd| - File.open('_test.out', 'w') { |io| io.write('It works!') } - end - EOS - - SUBCOMMAND_CODE = <<~EOS - usage '_sub [options]' - summary 'meh sub' - description 'longer meh sub' - - run do |opts, args, cmd| - File.open('_test_sub.out', 'w') { |io| io.write('It works sub!') } - end - EOS - - def test_load_custom_commands - Nanoc::CLI.run %w[create_site foo] - - FileUtils.cd('foo') do - # Create command - FileUtils.mkdir_p('commands') - File.open('commands/_test.rb', 'w') { |io| io.write(COMMAND_CODE) } - - # Run command - begin - Nanoc::CLI.run %w[_test] - rescue SystemExit - assert false, 'Running _test should not cause system exit' - end - - # Check - assert File.file?('_test.out') - assert_equal 'It works!', File.read('_test.out') - end - end - - def test_load_custom_commands_nested - Nanoc::CLI.run %w[create_site foo] - FileUtils.cd('foo') do - # Create command - FileUtils.mkdir_p('commands') - File.open('commands/_test.rb', 'w') do |io| - io.write(COMMAND_CODE) - end - - # Create subcommand - FileUtils.mkdir_p('commands/_test') - File.open('commands/_test/_sub.rb', 'w') do |io| - io.write(SUBCOMMAND_CODE) - end - - # Run command - begin - Nanoc::CLI.run %w[_test _sub] - rescue SystemExit - assert false, 'Running _test sub should not cause system exit' - end - - # Check - assert File.file?('_test_sub.out') - assert_equal 'It works sub!', File.read('_test_sub.out') - end - end - - def test_load_custom_commands_non_default_commands_dirs - Nanoc::CLI.run %w[create_site foo] - FileUtils.cd('foo') do - File.open('nanoc.yaml', 'w') { |io| io.write('commands_dirs: [commands, commands_alt]') } - - # Create command - FileUtils.mkdir_p('commands_alt') - File.open('commands_alt/_test.rb', 'w') do |io| - io.write(COMMAND_CODE) - end - - # Create subcommand - FileUtils.mkdir_p('commands_alt/_test') - File.open('commands_alt/_test/_sub.rb', 'w') do |io| - io.write(SUBCOMMAND_CODE) - end - - # Run command - begin - Nanoc::CLI.run %w[_test _sub] - rescue SystemExit - assert false, 'Running _test sub should not cause system exit' - end - - # Check - assert File.file?('_test_sub.out') - assert_equal 'It works sub!', File.read('_test_sub.out') - end - end - - def test_load_custom_commands_broken - Nanoc::CLI.run %w[create_site foo] - - FileUtils.cd('foo') do - # Create command - FileUtils.mkdir_p('commands') - File.open('commands/_test.rb', 'w') { |io| io.write('raise "meh"') } - - # Run command - position_before = $stderr.tell - Nanoc::CLI::ErrorHandler.disable - assert_raises RuntimeError do - Nanoc::CLI.run %w[_test] - end - Nanoc::CLI::ErrorHandler.enable - assert_raises SystemExit do - Nanoc::CLI.run %w[_test] - end - position_after = $stderr.tell - - # Check error output - stderr_addition = $stderr.string[position_before, position_after] - assert_match(/commands\/_test.rb/, stderr_addition) - end - end - - def test_load_command_at_with_non_utf8_encoding - Encoding.default_external = Encoding::US_ASCII - Nanoc::CLI.load_command_at(root_dir + '/lib/nanoc/cli/commands/create-site.rb') - ensure - Encoding.default_external = Encoding::UTF_8 - end - - def test_after_setup - $after_setup_success = false - Nanoc::CLI.after_setup do - $after_setup_success = true - end - Nanoc::CLI.setup - assert $after_setup_success - end - - def test_enable_utf8_only_on_tty - new_env_diff = { - 'LC_ALL' => 'en_US.ISO-8859-1', - 'LC_CTYPE' => 'en_US.ISO-8859-1', - 'LANG' => 'en_US.ISO-8859-1', - } - with_env_vars(new_env_diff) do - io = StringIO.new - def io.tty? - true - end - refute Nanoc::CLI.enable_utf8?(io) - - io = StringIO.new - def io.tty? - false - end - assert Nanoc::CLI.enable_utf8?(io) - end - end - - def test_enable_utf8 - io = StringIO.new - def io.tty? - true - end - - new_env_diff = { - 'LC_ALL' => 'en_US.ISO-8859-1', - 'LC_CTYPE' => 'en_US.ISO-8859-1', - 'LANG' => 'en_US.ISO-8859-1', - } - with_env_vars(new_env_diff) do - refute Nanoc::CLI.enable_utf8?(io) - - with_env_vars('LC_ALL' => 'en_US.UTF-8') { assert Nanoc::CLI.enable_utf8?(io) } - with_env_vars('LC_CTYPE' => 'en_US.UTF-8') { assert Nanoc::CLI.enable_utf8?(io) } - with_env_vars('LANG' => 'en_US.UTF-8') { assert Nanoc::CLI.enable_utf8?(io) } - - with_env_vars('LC_ALL' => 'en_US.utf-8') { assert Nanoc::CLI.enable_utf8?(io) } - with_env_vars('LC_CTYPE' => 'en_US.utf-8') { assert Nanoc::CLI.enable_utf8?(io) } - with_env_vars('LANG' => 'en_US.utf-8') { assert Nanoc::CLI.enable_utf8?(io) } - - with_env_vars('LC_ALL' => 'en_US.utf8') { assert Nanoc::CLI.enable_utf8?(io) } - with_env_vars('LC_CTYPE' => 'en_US.utf8') { assert Nanoc::CLI.enable_utf8?(io) } - with_env_vars('LANG' => 'en_US.utf8') { assert Nanoc::CLI.enable_utf8?(io) } - end - end -end diff -Nru nanoc-4.11.0/nanoc/test/cli/test_error_handler.rb nanoc-4.11.14/nanoc/test/cli/test_error_handler.rb --- nanoc-4.11.0/nanoc/test/cli/test_error_handler.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/cli/test_error_handler.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,102 +0,0 @@ -# frozen_string_literal: true - -require 'helper' - -class Nanoc::CLI::ErrorHandlerTest < Nanoc::TestCase - def setup - super - @handler = Nanoc::CLI::ErrorHandler.new - end - - def test_resolution_for_with_unknown_gem - error = LoadError.new('no such file to load -- afjlrestjlsgrshter') - assert_nil @handler.send(:resolution_for, error) - end - - def test_resolution_for_with_known_gem_without_bundler - def @handler.using_bundler? - false - end - error = LoadError.new('no such file to load -- kramdown') - assert_match(/^Install the 'kramdown' gem using `gem install kramdown`./, @handler.send(:resolution_for, error)) - end - - def test_resolution_for_with_known_gem_with_bundler - def @handler.using_bundler? - true - end - error = LoadError.new('no such file to load -- kramdown') - assert_match(/^1\. Add.*to your Gemfile/, @handler.send(:resolution_for, error)) - end - - def test_resolution_for_with_not_load_error - error = RuntimeError.new('nuclear meltdown detected') - assert_nil @handler.send(:resolution_for, error) - end - - def test_write_stack_trace_verbose - error = new_error(20) - - stream = StringIO.new - @handler.send(:write_stack_trace, stream, error, verbose: false) - assert_match(/ lines omitted \(see crash\.log for details\)/, stream.string) - - stream = StringIO.new - @handler.send(:write_stack_trace, stream, error, verbose: false) - assert_match(/ lines omitted \(see crash\.log for details\)/, stream.string) - - stream = StringIO.new - @handler.send(:write_stack_trace, stream, error, verbose: true) - refute_match(/ lines omitted \(see crash\.log for details\)/, stream.string) - end - - def test_write_error_message_wrapped - stream = StringIO.new - @handler.send(:write_error_message, stream, new_wrapped_error(new_error), verbose: true) - refute_match(/CompilationError/, stream.string) - end - - def test_write_stack_trace_wrapped - stream = StringIO.new - @handler.send(:write_stack_trace, stream, new_wrapped_error(new_error), verbose: false) - assert_match(/new_error/, stream.string) - end - - def test_write_item_rep - stream = StringIO.new - @handler.send(:write_item_rep, stream, new_wrapped_error(new_error), verbose: false) - assert_match(/^Current item: \/about\.md \(:latex representation\)$/, stream.string) - end - - def test_resolution_for_wrapped - def @handler.using_bundler? - true - end - error = new_wrapped_error(LoadError.new('no such file to load -- kramdown')) - assert_match(/^1\. Add.*to your Gemfile/, @handler.send(:resolution_for, error)) - end - - def new_wrapped_error(wrapped) - item = Nanoc::Int::Item.new('asdf', {}, '/about.md') - item_rep = Nanoc::Int::ItemRep.new(item, :latex) - raise Nanoc::Int::Errors::CompilationError.new(wrapped, item_rep) - rescue => e - e - end - - def new_error(amount_factor = 1) - backtrace_generator = lambda do |af| - if af.zero? - raise 'finally!' - else - backtrace_generator.call(af - 1) - end - end - - begin - backtrace_generator.call(amount_factor) - rescue => e - return e - end - end -end diff -Nru nanoc-4.11.0/nanoc/test/cli/test_logger.rb nanoc-4.11.14/nanoc/test/cli/test_logger.rb --- nanoc-4.11.0/nanoc/test/cli/test_logger.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/cli/test_logger.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -require 'helper' - -class Nanoc::CLI::LoggerTest < Nanoc::TestCase - def test_stub; end -end diff -Nru nanoc-4.11.0/nanoc/test/data_sources/test_filesystem.rb nanoc-4.11.14/nanoc/test/data_sources/test_filesystem.rb --- nanoc-4.11.0/nanoc/test/data_sources/test_filesystem.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/data_sources/test_filesystem.rb 2019-11-10 09:34:31.000000000 +0000 @@ -101,13 +101,13 @@ File.open('foo/stuff.dat', 'w') { |io| io.write('random binary data') } # Load - items = data_source.send(:load_objects, 'foo', Nanoc::Int::Item) + items = data_source.send(:load_objects, 'foo', Nanoc::Core::Item) # Check assert_equal 1, items.size assert items[0].content.binary? assert_equal "#{Dir.getwd}/foo/stuff.dat", items[0].content.filename - assert_equal Nanoc::Int::BinaryContent, items[0].content.class + assert_equal Nanoc::Core::BinaryContent, items[0].content.class end def test_load_layouts_with_nil_dir_name @@ -135,7 +135,7 @@ # Load assert_raises(Nanoc::DataSources::Filesystem::Errors::BinaryLayout) do - data_source.send(:load_objects, 'foo', Nanoc::Int::Layout) + data_source.send(:load_objects, 'foo', Nanoc::Core::Layout) end end @@ -468,7 +468,7 @@ File.write('foo/donkey.jpeg', 'data') File.write('foo/donkey.yaml', "---\nalt: Donkey\n") - objects = data_source.send(:load_objects, 'foo', Nanoc::Int::Item) + objects = data_source.send(:load_objects, 'foo', Nanoc::Core::Item) assert_equal 1, objects.size assert_equal '/donkey.jpeg', objects.first.identifier.to_s end diff -Nru nanoc-4.11.0/nanoc/test/data_sources/test_filesystem_tools.rb nanoc-4.11.14/nanoc/test/data_sources/test_filesystem_tools.rb --- nanoc-4.11.0/nanoc/test/data_sources/test_filesystem_tools.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/data_sources/test_filesystem_tools.rb 2019-11-10 09:34:31.000000000 +0000 @@ -139,7 +139,7 @@ pattern = { dotfiles: '**/.other' } - assert_raises Nanoc::Int::Errors::GenericTrivial, "Do not know how to handle extra_files: #{pattern.inspect}" do + assert_raises Nanoc::Core::TrivialError, "Do not know how to handle extra_files: #{pattern.inspect}" do Nanoc::DataSources::Filesystem::Tools.all_files_in('dir0', pattern) end end diff -Nru nanoc-4.11.0/nanoc/test/deploying/test_git.rb nanoc-4.11.14/nanoc/test/deploying/test_git.rb --- nanoc-4.11.0/nanoc/test/deploying/test_git.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/deploying/test_git.rb 2019-11-10 09:34:31.000000000 +0000 @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'helper' + class Nanoc::Deploying::Deployers::GitTest < Nanoc::TestCase def test_run_with_defaults_options # Create deployer @@ -220,10 +222,8 @@ FileUtils.mkdir_p('output') - piper = Nanoc::Extra::Piper.new(stdout: $stdout, stderr: $stderr) - Dir.chdir('output') do - piper.run('git init', nil) + TTY::Command.new.run('git', 'init') assert git.send(:clean_repo?) end end @@ -237,9 +237,8 @@ FileUtils.mkdir_p('output') - piper = Nanoc::Extra::Piper.new(stdout: $stdout, stderr: $stderr) Dir.chdir('output') do - piper.run('git init', nil) + TTY::Command.new.run('git', 'init') FileUtils.touch('foobar') refute git.send(:clean_repo?) end @@ -255,7 +254,7 @@ FileUtils.mkdir_p('output') Dir.chdir('output') do - assert_raises Nanoc::Extra::Piper::Error do + assert_raises TTY::Command::ExitError do git.send(:clean_repo?) end end diff -Nru nanoc-4.11.0/nanoc/test/extra/test_link_collector.rb nanoc-4.11.14/nanoc/test/extra/test_link_collector.rb --- nanoc-4.11.0/nanoc/test/extra/test_link_collector.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/extra/test_link_collector.rb 2019-11-10 09:34:31.000000000 +0000 @@ -5,106 +5,166 @@ class Nanoc::Extra::LinkCollectorTest < Nanoc::TestCase def test_all # Create dummy data - File.open('file-a.html', 'w') do |io| - io << %(A 1 -) - io << %(A 2 -) - io << %( -) + FileUtils.mkdir_p('testdir') + file_a = File.join(Dir.pwd, 'file-a.html') + file_b = File.join(Dir.pwd, 'testdir', 'file-b.html') + File.open(file_a, 'w') do |io| + io << %(A 1) + io << %(A 2) + io << %() io << %(A 4) - io << %(A 5 -) + io << %(A 5) end - File.open('file-b.html', 'w') do |io| - io << %(B 1 -) - io << %(B 2 -) - io << %(B 3 -) + File.open(file_b, 'w') do |io| + io << %(B 1) + io << %(B 2) + io << %(B 2) end # Create validator - collector = Nanoc::Extra::LinkCollector.new(%w[file-a.html file-b.html]) + collector = Nanoc::Extra::LinkCollector.new([file_a, file_b]) # Test hrefs_with_filenames = collector.filenames_per_href hrefs = hrefs_with_filenames.keys assert_includes hrefs, 'http://example.com/' assert_includes hrefs, 'https://example.com/' - assert_includes hrefs, 'stuff/' - refute_includes hrefs, nil - assert_includes hrefs, 'mailto:bob@example.com' - assert_includes hrefs, '../stuff' - assert_includes hrefs, '/stuff' + assert_includes hrefs, path_to_file_uri('stuff/', Dir.pwd) refute_includes hrefs, 'https://example.com/with-fragment#moo' assert_includes hrefs, 'https://example.com/with-fragment' + refute_includes hrefs, nil + assert_includes hrefs, 'mailto:bob@example.com' + assert_includes hrefs, 'file:///stuff' if URI('file:///.').to_s == 'file:///.' # Ruby 2.4 + assert_includes hrefs, 'file:/stuff' unless URI('file:///.').to_s == 'file:///.' # Ruby 2.5+ + assert_includes hrefs, path_to_file_uri('stuff', Dir.pwd) end def test_external # Create dummy data - File.open('file-a.html', 'w') do |io| - io << %(A 1 -) - io << %(A 2 -) - io << %( -) - end - File.open('file-b.html', 'w') do |io| - io << %(B 1 -) - io << %(B 2 -) - io << %(B 3 -) + file_a = File.join(Dir.pwd, 'file-a.html') + file_b = File.join(Dir.pwd, 'file-b.html') + File.open(file_a, 'w') do |io| + io << %(A 1) + io << %(A 2) + io << %() + end + File.open(file_b, 'w') do |io| + io << %(B 1) + io << %(B 2) + io << %(B 3) end # Create validator - collector = Nanoc::Extra::LinkCollector.new(%w[file-a.html file-b.html], :external) + collector = Nanoc::Extra::LinkCollector.new([file_a, file_b], :external) # Test hrefs_with_filenames = collector.filenames_per_href hrefs = hrefs_with_filenames.keys assert_includes hrefs, 'http://example.com/' assert_includes hrefs, 'https://example.com/' - refute_includes hrefs, 'stuff/' + refute_includes hrefs, path_to_file_uri('/', Dir.pwd) assert_includes hrefs, 'mailto:bob@example.com' - refute_includes hrefs, '../stuff' - refute_includes hrefs, '/stuff' + refute_includes hrefs, path_to_file_uri('/stuff', Dir.pwd) + refute_includes hrefs, path_to_file_uri('/stuff/', Dir.pwd) end - def test_internal + def test_internal_excludes_external # Create dummy data - File.open('file-a.html', 'w') do |io| - io << %(A 1 -) - io << %(A 2 -) - io << %( -) - end - File.open('file-b.html', 'w') do |io| - io << %(B 1 -) - io << %(B 2 -) - io << %(B 3 -) + output_dir = Dir.pwd + file_a = File.join(output_dir, 'file-a.html') + file_b = File.join(output_dir, 'file-b.html') + File.open(file_a, 'w') do |io| + io << %(A 1) + io << %(A 2) + end + File.open(file_b, 'w') do |io| + io << %(B 1) + io << %(B 2) end # Create validator - collector = Nanoc::Extra::LinkCollector.new(%w[file-a.html file-b.html], :internal) + collector = Nanoc::Extra::LinkCollector.new([file_a, file_b], :internal) # Test hrefs_with_filenames = collector.filenames_per_href hrefs = hrefs_with_filenames.keys refute_includes hrefs, 'http://example.com/' refute_includes hrefs, 'https://example.com/' - assert_includes hrefs, 'stuff/' + refute_includes hrefs, 'https://nanoc.ws' refute_includes hrefs, 'mailto:bob@example.com' - assert_includes hrefs, '../stuff' - assert_includes hrefs, '/stuff' + end + + def test_collect_links_from_space_separated_lists + # The white-space variations in this file’s attributes are intentional + File.open('file-a.html', 'w') do |io| + io << %() + io << %() + io << %(A 1) + end + + file_a = File.join(Dir.pwd, 'file-a.html') + + collector = Nanoc::Extra::LinkCollector.new([file_a], :internal) + + # Test + hrefs_with_filenames = collector.filenames_per_href + hrefs = hrefs_with_filenames.keys + assert_includes hrefs, path_to_file_uri('image.jpeg', Dir.pwd) + assert_includes hrefs, path_to_file_uri('image-large.jpeg', Dir.pwd) + assert_includes hrefs, path_to_file_uri('image-medium.jpeg', Dir.pwd) + assert_includes hrefs, path_to_file_uri('image-small.jpeg', Dir.pwd) + assert_includes hrefs, path_to_file_uri('image-large.webp', Dir.pwd) + assert_includes hrefs, path_to_file_uri('image-medium.webp', Dir.pwd) + assert_includes hrefs, path_to_file_uri('image-small.webp', Dir.pwd) + assert_includes hrefs, path_to_file_uri('ping1', Dir.pwd) + assert_includes hrefs, path_to_file_uri('ping2', Dir.pwd) + refute_includes hrefs, 'http://example.com/ping3' + refute_includes hrefs, nil + refute_includes hrefs, path_to_file_uri('/', Dir.pwd) + end + + def test_collects_exotic_links + file_a = File.join(Dir.pwd, 'file-a.html') + File.open(file_a, 'w') do |io| + io << %(
    A 1
    ) + io << %(A 2) + io << %(
    A 3
    ) + io << %() + end + + collector = Nanoc::Extra::LinkCollector.new([file_a], :external) + + # Test + hrefs_with_filenames = collector.filenames_per_href + hrefs = hrefs_with_filenames.keys + assert_includes hrefs, 'urn:uuid:6650eb58-86e6-416c-906a-35336e5ac8b2' + assert_includes hrefs, 'ms-settings:windows-update' + assert_includes hrefs, 'https://tracking.nanoc.ws/ping' + refute_includes hrefs, 'https://nanoc.ws/#static-generator' + assert_includes hrefs, 'https://nanoc.ws/' + assert_includes hrefs, 'https://nanoc.ws/all-your-base-are-belong-to-us' + end + + def test_protocol_relative_urls + File.write('a.html', 'broken') + + external_collector = + Nanoc::Extra::LinkCollector.new(['a.html'], :external) + + internal_collector = + Nanoc::Extra::LinkCollector.new(['a.html'], :internal) + + hrefs = external_collector.filenames_per_href.keys + assert_includes hrefs, '//example.com/broken' + refute_includes hrefs, 'http://example.com/broken' + refute_includes hrefs, 'file:///example.com/broken' + refute_includes hrefs, 'file://example.com/broken' + + hrefs = internal_collector.filenames_per_href.keys + refute_includes hrefs, '//example.com/broken' + refute_includes hrefs, 'http://example.com/broken' + refute_includes hrefs, 'file:///example.com/broken' + refute_includes hrefs, 'file://example.com/broken' end end diff -Nru nanoc-4.11.0/nanoc/test/extra/test_piper.rb nanoc-4.11.14/nanoc/test/extra/test_piper.rb --- nanoc-4.11.0/nanoc/test/extra/test_piper.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/extra/test_piper.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -require 'helper' - -class Nanoc::Extra::PiperTest < Nanoc::TestCase - def test_basic - stdout = StringIO.new - stderr = StringIO.new - - cmd = %w[ls -l] - - File.open('foo.txt', 'w') { |io| io.write('hi') } - File.open('bar.txt', 'w') { |io| io.write('ho') } - - piper = Nanoc::Extra::Piper.new(stdout: stdout, stderr: stderr) - piper.run(cmd, nil) - - assert_match(/foo\.txt/, stdout.string) - assert_match(/bar\.txt/, stdout.string) - assert stderr.string.empty? - end - - def test_stdin - stdout = StringIO.new - stderr = StringIO.new - - input = 'Hello World!' - cmd = %w[cat] - - piper = Nanoc::Extra::Piper.new(stdout: stdout, stderr: stderr) - piper.run(cmd, input) - - assert_equal(input, stdout.string) - assert_equal('', stderr.string) - end - - def test_no_such_command - stdout = StringIO.new - stderr = StringIO.new - - cmd = %w[cat kafhawilgoiwaejagoualjdsfilofiewaguihaifeowuiga] - - piper = Nanoc::Extra::Piper.new(stdout: stdout, stderr: stderr) - assert_raises(Nanoc::Extra::Piper::Error) do - piper.run(cmd, nil) - end - end -end diff -Nru nanoc-4.11.0/nanoc/test/filters/colorize_syntax/test_pygments.rb nanoc-4.11.14/nanoc/test/filters/colorize_syntax/test_pygments.rb --- nanoc-4.11.0/nanoc/test/filters/colorize_syntax/test_pygments.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/filters/colorize_syntax/test_pygments.rb 2019-11-10 09:34:31.000000000 +0000 @@ -4,7 +4,7 @@ class Nanoc::Filters::ColorizeSyntax::PygmentsTest < Nanoc::TestCase def test_pygmentsrb - skip 'pygments.rb does not support Windows' if on_windows? + skip 'pygments.rb does not support Windows' if Nanoc::Core.on_windows? if_have 'pygments', 'nokogiri' do # Create filter filter = ::Nanoc::Filters::ColorizeSyntax.new diff -Nru nanoc-4.11.0/nanoc/test/filters/test_erubi.rb nanoc-4.11.14/nanoc/test/filters/test_erubi.rb --- nanoc-4.11.0/nanoc/test/filters/test_erubi.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/filters/test_erubi.rb 2019-11-10 09:34:31.000000000 +0000 @@ -23,8 +23,8 @@ def test_filter_syntax_error # Create filter - item = Nanoc::Int::Item.new('asdf', {}, '/about.md') - item_rep = Nanoc::Int::ItemRep.new(item, :xml) + item = Nanoc::Core::Item.new('asdf', {}, '/about.md') + item_rep = Nanoc::Core::ItemRep.new(item, :xml) filter = ::Nanoc::Filters::Erubi.new(item: item, item_rep: item_rep) # Run filter @@ -41,8 +41,8 @@ def test_filter_regular_error # Create filter - item = Nanoc::Int::Item.new('asdf', {}, '/about.md') - item_rep = Nanoc::Int::ItemRep.new(item, :xml) + item = Nanoc::Core::Item.new('asdf', {}, '/about.md') + item_rep = Nanoc::Core::ItemRep.new(item, :xml) filter = ::Nanoc::Filters::Erubi.new(item: item, item_rep: item_rep) # Run filter diff -Nru nanoc-4.11.0/nanoc/test/filters/test_handlebars.rb nanoc-4.11.14/nanoc/test/filters/test_handlebars.rb --- nanoc-4.11.0/nanoc/test/filters/test_handlebars.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/filters/test_handlebars.rb 2019-11-10 09:34:31.000000000 +0000 @@ -6,12 +6,12 @@ def test_filter if_have 'handlebars' do # Create data - item = Nanoc::Int::Item.new( + item = Nanoc::Core::Item.new( 'content', { title: 'Max Payne', protagonist: 'Max Payne', location: 'here' }, '/games/max-payne', ) - layout = Nanoc::Int::Layout.new( + layout = Nanoc::Core::Layout.new( 'layout content', { name: 'Max Payne' }, '/default', @@ -40,7 +40,7 @@ def test_filter_without_layout if_have 'handlebars' do # Create data - item = Nanoc::Int::Item.new( + item = Nanoc::Core::Item.new( 'content', { title: 'Max Payne', protagonist: 'Max Payne', location: 'here' }, '/games/max-payne', diff -Nru nanoc-4.11.0/nanoc/test/filters/test_kramdown.rb nanoc-4.11.14/nanoc/test/filters/test_kramdown.rb --- nanoc-4.11.0/nanoc/test/filters/test_kramdown.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/filters/test_kramdown.rb 2019-11-10 09:34:31.000000000 +0000 @@ -14,10 +14,10 @@ def test_warnings # Create item - item = Nanoc::Int::Item.new('foo', {}, '/foo.md') - item_view = Nanoc::CompilationItemView.new(item, nil) - item_rep = Nanoc::Int::ItemRep.new(item, :default) - item_rep_view = Nanoc::CompilationItemRepView.new(item_rep, nil) + item = Nanoc::Core::Item.new('foo', {}, '/foo.md') + item_view = Nanoc::Core::CompilationItemView.new(item, nil) + item_rep = Nanoc::Core::ItemRep.new(item, :default) + item_rep_view = Nanoc::Core::CompilationItemRepView.new(item_rep, nil) # Create filter filter = ::Nanoc::Filters::Kramdown.new(item: item_view, item_rep: item_rep_view) @@ -32,10 +32,10 @@ def test_warning_filters # Create item - item = Nanoc::Int::Item.new('foo', {}, '/foo.md') - item_view = Nanoc::CompilationItemView.new(item, nil) - item_rep = Nanoc::Int::ItemRep.new(item, :default) - item_rep_view = Nanoc::CompilationItemRepView.new(item_rep, nil) + item = Nanoc::Core::Item.new('foo', {}, '/foo.md') + item_view = Nanoc::Core::CompilationItemView.new(item, nil) + item_rep = Nanoc::Core::ItemRep.new(item, :default) + item_rep_view = Nanoc::Core::CompilationItemRepView.new(item_rep, nil) # Create filter filter = ::Nanoc::Filters::Kramdown.new(item: item_view, item_rep: item_rep_view) diff -Nru nanoc-4.11.0/nanoc/test/filters/test_mustache.rb nanoc-4.11.14/nanoc/test/filters/test_mustache.rb --- nanoc-4.11.0/nanoc/test/filters/test_mustache.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/filters/test_mustache.rb 2019-11-10 09:34:31.000000000 +0000 @@ -5,7 +5,7 @@ class Nanoc::Filters::MustacheTest < Nanoc::TestCase def test_filter # Create item - item = Nanoc::Int::Item.new( + item = Nanoc::Core::Item.new( 'content', { title: 'Max Payne', protagonist: 'Max Payne' }, '/games/max-payne', @@ -21,7 +21,7 @@ def test_filter_with_yield # Create item - item = Nanoc::Int::Item.new( + item = Nanoc::Core::Item.new( 'content', { title: 'Max Payne', protagonist: 'Max Payne' }, '/games/max-payne', diff -Nru nanoc-4.11.0/nanoc/test/filters/test_pandoc.rb nanoc-4.11.14/nanoc/test/filters/test_pandoc.rb --- nanoc-4.11.0/nanoc/test/filters/test_pandoc.rb 2018-12-01 12:51:52.000000000 +0000 +++ nanoc-4.11.14/nanoc/test/filters/test_pandoc.rb 2019-11-10 09:34:31.000000000 +0000 @@ -40,7 +40,7 @@ # Run filter args = [:s, { f: :markdown, to: :html }, 'wrap=none', :toc] result = filter.setup_and_run("# Heading\n", args: args) - assert_match '