class CLIntegracon::FileTreeSpec
FileTreeSpec
represents a single specification, which is mirrored on the file system in the spec directory by a direct children. It contains a before directory (before_path
) and an after directory (after_path
) or if it is initialized with a base_spec
, the before directory of this spec is used. The before directory contents in the spec_path
of the child spec, can contain further files, which overwrite, if given, the inherited contents.
Attributes
@return [String|NilClass]
The name of an optional #base_spec.
@return [FileTreeSpecContext]
The context, which configures path and file behaviors
@return [String]
The concrete spec folder
Public Class Methods
Init a spec with a given context
@param [FileTreeSpecContext] context
The context, which configures path and file behaviors
@param [String] spec_folder
The concrete spec folder
@param [String] based_on
@see #base_spec_name
# File lib/CLIntegracon/file_tree_spec.rb, line 90 def initialize(context, spec_folder, based_on: nil) @context = context @spec_folder = spec_folder @base_spec_name = based_on end
Public Instance Methods
@return [Pathname]
The concrete after directory for this spec
# File lib/CLIntegracon/file_tree_spec.rb, line 38 def after_path spec_path + context.after_dir end
@return [FileTreeSpec|NilClass]
The spec on whose #after_path will be used as #before_path for this spec.
# File lib/CLIntegracon/file_tree_spec.rb, line 75 def base_spec has_base? ? context.spec(base_spec_name) : nil end
@return [Pathname]
The concrete before directory for this spec
# File lib/CLIntegracon/file_tree_spec.rb, line 32 def before_path spec_path + context.before_dir end
Compares the expected and produced directory by using the rules defined in the context for unexpected files.
This is separate because you probably don't want to define an extra test case for each file, which wasn't expected at all. So you can keep your test cases consistent.
@param [Block<(Array)->()>] diff_block
The block, where you will likely define a test that no unexpected files exists. It will receive an Array.
# File lib/CLIntegracon/file_tree_spec.rb, line 151 def check_unexpected_files(&block) expected_files = glob_all after_path produced_files = glob_all unexpected_files = produced_files - expected_files # Select only files unexpected_files.select! { |path| path.file? } # Filter ignored paths unexpected_files.reject! { |path| context.ignores?(path) } block.call unexpected_files end
Compares the expected and produced directory by using the rules defined in the context
@param [Block<(Diff
)->()>] diff_block
The block, where you will likely define a test for each file to compare. It will receive a Diff of each of the expected and produced files.
# File lib/CLIntegracon/file_tree_spec.rb, line 121 def compare(&diff_block) # Get a copy of the outputs before any transformations are applied FileUtils.cp_r("#{temp_transformed_path}/.", temp_raw_path) transform_paths! glob_all(after_path).each do |relative_path| expected = after_path + relative_path next unless expected.file? next if context.ignores?(relative_path) block = context.preprocessors_for(relative_path).first diff = diff_files(expected, relative_path, &block) diff_block.call diff end end
Return a Formatter
@return [Formatter]
# File lib/CLIntegracon/file_tree_spec.rb, line 169 def formatter @formatter ||= Formatter.new(self) end
Return whether this spec is based on another spec.
@return [Bool]
# File lib/CLIntegracon/file_tree_spec.rb, line 68 def has_base? !base_spec_name.nil? end
Run this spec
@param [Block<(FileTreeSpec
)->()>] block
The block, which will be executed after chdir into the created temporary directory. In this block you will likely run your modifications to the file system and use the received FileTreeSpec instance to make asserts with the test framework of your choice.
# File lib/CLIntegracon/file_tree_spec.rb, line 104 def run(&block) prepare! copy_files! Dir.chdir(temp_transformed_path) do block.call self end end
@return [Pathname]
The concrete spec path
# File lib/CLIntegracon/file_tree_spec.rb, line 26 def spec_path context.spec_path + spec_folder end
@return [Pathname]
The concrete temp directory for this spec
# File lib/CLIntegracon/file_tree_spec.rb, line 44 def temp_path context.temp_path + spec_folder end
@return [Pathname]
The concrete temp raw directory for this spec
# File lib/CLIntegracon/file_tree_spec.rb, line 50 def temp_raw_path temp_path + 'raw' end
@return [Pathname]
The concrete transformed temp directory for this spec
# File lib/CLIntegracon/file_tree_spec.rb, line 56 def temp_transformed_path temp_path + 'transformed' end
Protected Instance Methods
Copies the before subdirectory of the given tests folder in the raw directory.
# File lib/CLIntegracon/file_tree_spec.rb, line 189 def copy_files! destination = temp_transformed_path if has_base? FileUtils.cp_r("#{base_spec.temp_raw_path}/.", destination) end begin FileUtils.cp_r("#{before_path}/.", destination) rescue Errno::ENOENT => e raise e unless has_base? end end
Compares two files to check if they are identical and produces a clear diff to highlight the differences.
@param [Pathname] expected
The file in the after directory
@param [Pathname] relative_path
The file in the temp directory
@param [Block<(Pathname)->(to_s)>] block
the block, which transforms the files in a better comparable form
@return [Diff]
An object holding a diff
# File lib/CLIntegracon/file_tree_spec.rb, line 245 def diff_files(expected, relative_path, &block) produced = temp_transformed_path + relative_path Diff.new(expected, produced, relative_path, &block) end
Searches recursively for all files and take care for including hidden files if this is configured in the context.
@param [String] path
The relative or absolute path to search in (optional)
@return [Array<Pathname>]
# File lib/CLIntegracon/file_tree_spec.rb, line 222 def glob_all(path=nil) Dir.chdir path || '.' do Pathname.glob("**/*", context.include_hidden_files? ? File::FNM_DOTMATCH : 0).sort.reject do |p| %w(. ..).include?(p.basename.to_s) end end end
Prepare the temporary directory
# File lib/CLIntegracon/file_tree_spec.rb, line 177 def prepare! context.prepare! temp_path.rmtree if temp_path.exist? temp_path.mkdir temp_raw_path.mkdir temp_transformed_path.mkdir end
Applies the in the context configured transformations.
# File lib/CLIntegracon/file_tree_spec.rb, line 205 def transform_paths! glob_all.each do |path| context.transformers_for(path).each do |transformer| transformer.call(path) if path.exist? end path.rmtree if context.ignores?(path) && path.exist? end end