test_construct-2.0.2/0000755000004100000410000000000013475622037014637 5ustar www-datawww-datatest_construct-2.0.2/test/0000755000004100000410000000000013475622037015616 5ustar www-datawww-datatest_construct-2.0.2/test/test_construct_test.rb0000644000004100000410000003332313475622037022271 0ustar www-datawww-datarequire 'test_helper' class TestConstructTest < Minitest::Test include TestConstruct::Helpers def teardown Dir.chdir File.expand_path("../..", __FILE__) TestConstruct.destroy_all! end testing 'using within_construct explicitly' do test 'creates construct' do num = rand(1_000_000_000) TestConstruct.stubs(:rand).returns(num) directory = false TestConstruct::within_construct do |construct| directory = File.directory?(File.join(TestConstruct.tmpdir, "construct_container-#{$PROCESS_ID}-#{num}")) end assert directory directory = false TestConstruct.within_construct do |construct| directory = File.directory?(File.join(TestConstruct.tmpdir, "construct_container-#{$PROCESS_ID}-#{num}")) end assert directory end end testing 'creating a construct container' do test 'exists' do num = rand(1_000_000_000) self.stubs(:rand).returns(num) within_construct do |construct| assert File.directory?(File.join(TestConstruct.tmpdir, "construct_container-#{$PROCESS_ID}-#{num}")) end end test 'yields to its block' do sensor = 'no yield' within_construct do sensor = 'yielded' end assert_equal 'yielded', sensor end test 'block argument is container directory Pathname' do num = rand(1_000_000_000) self.stubs(:rand).returns(num) within_construct do |container_path| expected_path = (Pathname(TestConstruct.tmpdir) + "construct_container-#{$PROCESS_ID}-#{num}") assert_equal(expected_path, container_path) end end test 'does not exist afterwards' do path = nil within_construct do |container_path| path = container_path end assert !path.exist? end test 'removes entire tree afterwards' do path = nil within_construct do |container_path| path = container_path (container_path + 'foo').mkdir end assert !path.exist? end test 'removes dir if block raises exception' do path = nil begin within_construct do |container_path| path = container_path raise 'something bad happens here' end rescue end assert !path.exist? end test 'does not capture exceptions raised in block' do err = RuntimeError.new('an error') begin within_construct do raise err end rescue RuntimeError => e assert_same err, e end end end testing 'creating a file in a container' do test 'exists while in construct block' do within_construct do |construct| construct.file('foo.txt') assert File.exist?(construct + 'foo.txt') end end test 'does not exist after construct block' do filepath = 'unset' within_construct do |construct| filepath = construct.file('foo.txt') end assert !File.exist?(filepath) end test 'has empty file contents by default' do within_construct do |construct| construct.file('foo.txt') assert_equal '', File.read(construct + 'foo.txt') end end test 'writes contents to file' do within_construct do |construct| construct.file('foo.txt','abcxyz') assert_equal 'abcxyz', File.read(construct+'foo.txt') end end test 'contents can be given in a block' do within_construct do |construct| construct.file('foo.txt') do <<-EOS File Contents EOS end assert_equal "File\nContents\n", File.read(construct+'foo.txt') end end test 'contents block overwrites contents argument' do within_construct do |construct| construct.file('foo.txt','abc') do 'xyz' end assert_equal 'xyz', File.read(construct+'foo.txt') end end test 'block is passed File object' do within_construct do |construct| construct.file('foo.txt') do |file| assert_equal((construct+'foo.txt').to_s, file.path) end end end test 'writes to File object passed to block' do within_construct do |construct| construct.file('foo.txt') do |file| file << 'abc' end assert_equal 'abc', File.read(construct+'foo.txt') end end test 'closes file after block ends' do within_construct do |construct| construct_file = nil construct.file('foo.txt') do |file| construct_file = file end assert construct_file.closed? end end test 'block return value not used as content if passed File object' do within_construct do |construct| construct.file('foo.txt') do |file| file << 'abc' 'xyz' end assert_equal 'abc', File.read(construct+'foo.txt') end end test 'contents argument is ignored if block takes File arg' do within_construct do |construct| construct.file('foo.txt','xyz') do |file| file << 'abc' end assert_equal 'abc', File.read(construct+'foo.txt') end end test 'returns file path' do within_construct do |construct| assert_equal(construct+'foo.txt', construct.file('foo.txt')) end end test 'creates file including path in one call' do within_construct do |construct| construct.file('foo/bar/baz.txt') assert (construct+'foo/bar/baz.txt').exist? end end test 'creates file including path in one call when directories exists' do within_construct do |construct| construct.directory('foo/bar') construct.file('foo/bar/baz.txt') assert (construct+'foo/bar/baz.txt').exist? end end test 'creates file including path with chained calls' do within_construct do |construct| construct.directory('foo').directory('bar').file('baz.txt') assert (construct+'foo/bar/baz.txt').exist? end end end testing 'creating a subdirectory in container' do test 'exists while in construct block' do within_construct do |construct| construct.directory 'foo' assert (construct+'foo').directory? end end test 'does not exist after construct block' do subdir = 'unset' within_construct do |construct| construct.directory 'foo' subdir = construct + 'foo' end assert !subdir.directory? end test 'returns the new path name' do within_construct do |construct| assert_equal((construct+'foo'), construct.directory('foo')) end end test 'yield to block' do sensor = 'unset' within_construct do |construct| construct.directory('bar') do sensor = 'yielded' end end assert_equal 'yielded', sensor end test 'block argument is subdirectory path' do within_construct do |construct| construct.directory('baz') do |dir| assert_equal((construct+'baz'),dir) end end end test 'creates nested directory in one call' do within_construct do |construct| construct.directory('foo/bar') assert (construct+'foo/bar').directory? end end test 'creates a nested directory in two calls' do within_construct do |construct| construct.directory('foo').directory('bar') assert (construct+'foo/bar').directory? end end end testing "subdirectories changing the working directory" do test 'forces directory stays the same' do within_construct do |construct| old_pwd = Dir.pwd construct.directory('foo', :chdir => false) do assert_equal old_pwd, Dir.pwd end end end test 'defaults chdir setting from construct' do within_construct(:chdir => false) do |construct| old_pwd = Dir.pwd construct.directory('foo') do assert_equal old_pwd, Dir.pwd end end end test 'overrides construct default' do within_construct(:chdir => false) do |construct| construct.directory('foo', :chdir => true) do |dir| assert_equal dir.to_s, Dir.pwd end end end test 'current working directory is within subdirectory' do within_construct do |construct| construct.directory('foo') do |dir| assert_equal dir.to_s, Dir.pwd end end end test 'current working directory is unchanged outside of subdirectory' do within_construct do |construct| old_pwd = Dir.pwd construct.directory('foo') assert_equal old_pwd, Dir.pwd end end test 'current working directory is unchanged after exception' do within_construct do |construct| old_pwd = Dir.pwd begin construct.directory('foo') do raise 'something bad happens here' end rescue end assert_equal old_pwd, Dir.pwd end end test 'captures exceptions raised in block' do within_construct do |construct| error = assert_raises RuntimeError do construct.directory('foo') do raise 'fail!' end end assert_equal 'fail!', error.message end end test 'checking for a file is relative to subdirectory' do within_construct do |construct| construct.directory('bar') do |dir| dir.file('foo.txt') assert File.exist?('foo.txt') end end end test 'checking for a directory is relative to subdirectory' do within_construct do |construct| construct.directory('foo') do |dir| dir.directory('mydir') assert File.directory?('mydir') end end end end testing "changing the working directory" do test 'forces directory stays the same' do old_pwd = Dir.pwd within_construct(:chdir => false) do |construct| assert_equal old_pwd, Dir.pwd end end test 'current working directory is within construct' do within_construct do |construct| assert_equal construct.to_s, Dir.pwd end end test 'current working directory is unchanged outside of construct' do old_pwd = Dir.pwd within_construct do |construct| end assert_equal old_pwd, Dir.pwd end test 'current working directory is unchanged after exception' do old_pwd = Dir.pwd begin within_construct do |construct| raise 'something bad happens here' end rescue end assert_equal old_pwd, Dir.pwd end test 'does not capture exceptions raised in block' do error = assert_raises RuntimeError do within_construct do raise 'fail!' end end assert_equal 'fail!', error.message end test 'checking for a file is relative to container' do within_construct do |construct| construct.file('foo.txt') assert File.exist?('foo.txt') end end test 'checking for a directory is relative to container' do within_construct do |construct| construct.directory('mydir') assert File.directory?('mydir') end end end testing "#create_construct" do test "returns a working Construct" do it = create_construct it.directory "foo" it.file "bar", "CONTENTS" assert (it + "foo").directory? assert_equal "CONTENTS", (it + "bar").read end end testing "#chdir" do test "executes its block in the context of the construct" do it = create_construct refute_equal it.to_s, Dir.pwd sensor = :unset it.chdir do sensor = Dir.pwd end assert_equal it.to_s, sensor end test "leaves construct directory on block exit" do it = create_construct it.chdir do # NOOP end refute_equal it.to_s, Dir.pwd end end testing "#destroy!" do test "removes the construct container" do it = create_construct it.destroy! assert !File.exist?(it.to_s) end end testing "#finalize" do test "removes the construct container" do it = create_construct it.finalize assert !File.exist?(it.to_s) end test "leaves the container if keep is flagged" do it = create_construct it.keep it.finalize assert File.exist?(it.to_s) end test "leaves the container if keep is flagged in a subdir" do it = create_construct subdir = it.directory "subdir" subdir.keep it.finalize assert File.exist?(it.to_s) end end testing "keep_on_error = true" do test 'keeps dir when block raises exception' do path = nil begin within_construct(keep_on_error: true) do |container_path| path = container_path raise 'something bad happens here' end rescue end assert path.exist? end test 'updates exception message to include location of files' do path = nil begin within_construct(keep_on_error: true) do |container_path| path = container_path raise 'bad stuff' end rescue => e error = e end assert_equal "bad stuff\nTestConstruct files kept at: #{path}", error.message end end testing 'base_dir option' do test 'determines the location of construct dirs' do base_dir = File.expand_path("../temp", __FILE__) within_construct(base_dir: base_dir) do |container| assert_equal base_dir, container.dirname.to_s end end end testing 'name option' do test 'used in generation of the directory name' do within_construct(name: "My best test ever!") do |container| assert_match(/my-best-test-ever-$/, container.basename.to_s) end end end end test_construct-2.0.2/test/rspec_integration_test.rb0000644000004100000410000000121413475622037022717 0ustar www-datawww-datarequire 'test_helper' class RspecIntegrationTest < Minitest::Test include TestConstruct::Helpers test 'rspec integration' do lib_path = File.realpath('lib') within_construct do |construct| spec_file_name = 'rspec_spec.rb' construct.file(spec_file_name, <<-RSPEC) require 'test_construct/rspec_integration' describe 'test_construct', test_construct: true do it 'accesses metadata' do |example| f = example.metadata[:construct].file "somefile", "abcd" expect(f.size).to eq 4 end end RSPEC output = `rspec -I '#{lib_path}' #{spec_file_name}` assert $CHILD_STATUS.success?, output end end end test_construct-2.0.2/test/test_helper.rb0000644000004100000410000000101213475622037020453 0ustar www-datawww-datarequire 'minitest' require "minitest/autorun" require 'mocha/setup' require 'test_construct' class Minitest::Test def self.testing(name) @group = name yield @group = nil end def self.test(name, &block) name = name.strip.gsub(/\s\s+/, " ") group = "#{@group}: " if defined? @group test_name = "test_: #{group}#{name}".to_sym defined = instance_methods.include? test_name raise "#{test_name} is already defined in #{self}" if defined define_method(test_name, &block) end end test_construct-2.0.2/README.md0000644000004100000410000001675413475622037016133 0ustar www-datawww-data[![Gem Version](https://badge.fury.io/rb/test_construct.svg)](https://badge.fury.io/rb/test_construct) # TestConstruct > "This is the construct. It's our loading program. We can load anything, from clothing to equipment, weapons, and training simulations, anything we need" -- Morpheus TestConstruct is a DSL for creating temporary files and directories during testing. ## SYNOPSIS class ExampleTest < Test::Unit::TestCase include TestConstruct::Helpers def test_example within_construct do |c| c.directory 'alice/rabbithole' do |d| d.file 'white_rabbit.txt', "I'm late!" assert_equal "I'm late!", File.read('white_rabbit.txt') end end end end ## Installation Add this line to your application's Gemfile: gem 'test_construct' And then execute: $ bundle Or install it yourself as: $ gem install test_construct ## Usage To use TestConstruct, you need to include the TestConstruct module in your class like so: include TestConstruct::Helpers Using construct is as simple as calling `within_construct` and providing a block. All files and directories that are created within that block are created within a temporary directory. The temporary directory is always deleted before `within_construct` finishes. There is nothing special about the files and directories created with TestConstruct, so you can use plain old Ruby IO methods to interact with them. ### Creating files The most basic use of TestConstruct is creating an empty file with the: within_construct do |construct| construct.file('foo.txt') end Note that the working directory is, by default, automatically changed to the temporary directory created by TestConstruct, so the following assertion will pass: within_construct do |construct| construct.file('foo.txt') assert File.exist?('foo.txt') end You can also provide content for the file, either with an optional argument or using the return value of a supplied block: within_construct do |construct| construct.file('foo.txt', 'Here is some content') construct.file('bar.txt') do <<-EOS The block will return this string, which will be used as the content. EOS end end If you provide block that accepts a parameter, construct will pass in the IO object. In this case, you are responsible for writing content to the file yourself - the return value of the block will not be used: within_construct do |construct| construct.file('foo.txt') do |file| file << "Some content\n" file << "Some more content" end end Finally, you can provide the entire path to a file and the parent directories will be created automatically: within_construct do |construct| construct.file('foo/bar/baz.txt') end ### Creating directories It is easy to create a directory: within_construct do |construct| construct.directory('foo') end You can also provide a block. The object passed to the block can be used to create nested files and directories (it's just a [Pathname](http://www.ruby-doc.org/stdlib/libdoc/pathname/rdoc/index.html) instance with some extra functionality, so you can use it to get the path of the current directory). Again, note that the working directory is automatically changed while in the block: within_construct do |construct| construct.directory('foo') do |dir| dir.file('bar.txt') assert File.exist?('bar.txt') # This assertion will pass end end Again, you can provide paths and the necessary directories will be automatically created: within_construct do |construct| construct.directory('foo/bar/') do |dir| dir.directory('baz') dir.directory('bazz') end end Please read test/construct_test.rb for more examples. ### Disabling chdir In some cases, you may wish to disable the default behavior of automatically changing the current directory. For example, changing the current directory will prevent Ruby debuggers from displaying source code correctly. If you disable, automatic chdir, note that your old assertions will not work: ``` within_construct(:chdir => false) do |construct| construct.file("foo.txt") # Fails. foo.txt was created in construct, but # the current directory is not the construct! assert File.exists?("foo.txt") end ``` To fix, simply use the `Pathname` passed to the block: ``` within_construct(:chdir => false) do |construct| construct.file("foo.txt") # Passes assert File.exists?(construct+"foo.txt") end ``` ### Keeping directories around You may find it convenient to keep the created directory around after a test has completed, in order to manually inspect its contents. ```ruby within_construct do |construct| # ... construct.keep end ``` Most likely you only want the directory to stick around if something goes wrong. To do this, use the `:keep_on_error` option. ```ruby within_construct(keep_on_error: true) do |construct| # ... raise "some error" end ``` TestConstruct will also annotate the exception error message to tell you where the generated files can be found. ### Setting the base directory By default, TestConstruct puts its temporary container directories in your system temp dir. You can change this with the `:base_dir` option: ```ruby tmp_dir = File.expand_path("../../tmp", __FILE__) within_construct(base_dir: tmp_dir) do |construct| construct.file("foo.txt") # Passes assert File.exists?(tmp_dir+"/foo.txt") end ``` ### Naming the created directories Normally TestConstruct names the container directories it creates using a combination of a `test-construct-` prefix, the current process ID, and a random number. This ensures that the name is unlikely to clash with directories left over from previous runs. However, it isn't very meaningful. You can optionally make the directory names more recognizable by specifying a `:name` option. TestConstruct will take the string passed, turn it into a normalized "slug" without any funny characters, and append it to the end of the generated dirname. ```ruby within_construct(name: "My best test ever!") do |construct| # will generate something like: # /tmp/construct-container-1234-5678-my-best-test-ever end ``` ### RSpec Integration TestConstruct comes with RSpec integration. Just require the `test_construct/rspec_integration` file in your `spec_helper.rb` or in your spec file. Then tag the tests you want to execute in the context of a construct container with `test_construct: true` using RSpec metadata: ```ruby require "test_construct/rspec_integration" describe Foo, test_construct: true do it "should do stuff" do example.metadata[:construct].file "somefile" example.metadata[:construct].directory "somedir" # ... end end ``` By default, the current working directory will be switched to the construct container within tests; the container name will be derived from the name of the current example; and if a test fails, the container will be kept around. Information about where to find it will be added to the test failure message. You can tweak any TestConstruct options by passing a hash as the value of the `:test_construct` metadata key. ```ruby require "test_construct/rspec_integration" describe Foo, test_construct: {keep_on_error: false} do # ... end ``` ## Contributing 1. Fork it 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) 5. Create new Pull Request test_construct-2.0.2/CHANGELOG.md0000644000004100000410000000066313475622037016455 0ustar www-datawww-data# TestConstruct Changelog ## v2.0.2 * Fixes line endings on Windows (@MSP-Greg) ## v2.0.1 * Adds support for RSpec 3 (@jcouball) ## v2.0.0 Enhancements: * Add RSpec 2 support (@avdi) * Option to persist directories after test run or after failure (@avdi) * Add naming of created directories (@avdi) Other: * Non-backwards-compatible change to `TestConstruct::Helpers#create_construct` method signature (takes option hash now) test_construct-2.0.2/.gitignore0000644000004100000410000000025013475622037016624 0ustar www-datawww-data*.gem *.rbc .bundle .config .yardoc .ruby-version Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp test_construct-2.0.2/examples/0000755000004100000410000000000013475622037016455 5ustar www-datawww-datatest_construct-2.0.2/examples/foobar_test.rb0000644000004100000410000000144413475622037021314 0ustar www-datawww-data# Run with: # ruby -Ilib examples/foobar_test.rb require 'test_construct' require 'test/unit' class FoobarTest < Test::Unit::TestCase include TestConstruct::Helpers def test_directory_and_files within_construct do |c| c.directory 'alice/rabbithole' do |d| d.file 'white_rabbit.txt', "I'm late!" assert_equal "I'm late!", File.read('white_rabbit.txt') end end end def test_keeping_directory_on_error within_construct(keep_on_error: true) do |c| c.directory 'd' do |d| d.file 'doughnut.txt' raise "whoops" end end end def test_deleting_directory_on_error within_construct(keep_on_error: false) do |c| c.directory 'd' do |d| d.file 'doughnut.txt' raise "whoops" end end end end test_construct-2.0.2/examples/foobar_spec.rb0000644000004100000410000000144613475622037021271 0ustar www-datawww-data# Run with: # rspec -Ilib examples/foobar_spec.rb require 'rspec' require 'test_construct/rspec_integration' describe "Foobar", test_construct: true do it "creates file" do example.metadata[:construct].directory "alice/rabbithole" do |d| d.file "white_rabbit.txt", "I'm late!" File.read("white_rabbit.txt").should == "I'm late!" end end it "leaves file on error" do example.metadata[:construct].directory "alice/rabbithole" do |d| d.file "white_rabbit.txt", "I'm late!" raise "Whoops" end end end describe "Foobar", test_construct: { keep_on_error: false} do it "doesn't leave file on error" do example.metadata[:construct].directory "alice/rabbithole" do |d| d.file "white_rabbit.txt", "I'm late!" raise "Whoops" end end end test_construct-2.0.2/Rakefile0000644000004100000410000000026413475622037016306 0ustar www-datawww-datarequire "bundler/gem_tasks" require "rake/testtask" Rake::TestTask.new do |t| t.libs << "test" t.libs << "lib" t.pattern = "test/**/*_test.rb" end task :default => [:test] test_construct-2.0.2/lib/0000755000004100000410000000000013475622037015405 5ustar www-datawww-datatest_construct-2.0.2/lib/test_construct.rb0000644000004100000410000000067713475622037021027 0ustar www-datawww-datarequire "tmpdir" require "test_construct/version" require "test_construct/helpers" require "test_construct/pathname_extensions" module TestConstruct CONTAINER_PREFIX = 'construct_container' def self.tmpdir dir = nil Dir.chdir Dir.tmpdir do dir = Dir.pwd end # HACK FOR OS X dir end def self.destroy_all! Pathname.glob(File.join(tmpdir, CONTAINER_PREFIX + "*")) do |container| container.rmtree end end end test_construct-2.0.2/lib/test_construct/0000755000004100000410000000000013475622037020470 5ustar www-datawww-datatest_construct-2.0.2/lib/test_construct/version.rb0000644000004100000410000000005513475622037022502 0ustar www-datawww-datamodule TestConstruct VERSION = "2.0.2" end test_construct-2.0.2/lib/test_construct/helpers.rb0000644000004100000410000000375013475622037022464 0ustar www-datawww-datarequire 'English' require 'pathname' module TestConstruct module Helpers extend self def within_construct(opts = {}) container = setup_construct(opts) yield(container) rescue Exception => error raise unless container teardown_construct(container, error, opts) raise error else teardown_construct(container, nil, opts) end def create_construct(opts = {}) chdir_default = opts.delete(:chdir) { true } base_path = Pathname(opts.delete(:base_dir) { TestConstruct.tmpdir }) name = opts.delete(:name) { "" } slug = name.downcase.tr_s("^a-z0-9", "-")[0..63] if opts.any? raise "[TestConstruct] Unrecognized options: #{opts.keys}" end dir = "#{CONTAINER_PREFIX}-#{$PROCESS_ID}-#{rand(1_000_000_000)}" dir << "-" << slug unless slug.empty? path = base_path + dir path.mkpath path.extend(PathnameExtensions) path.construct__chdir_default = chdir_default path end # THIS METHOD MAY HAVE EXTERNAL SIDE-EFFECTS, including: # - creating the container directory tree # - changing the current working directory # # It is intended to be paired with #teardown_construct def setup_construct(opts = {}) opts = opts.dup chdir = opts.fetch(:chdir, true) opts.delete(:keep_on_error) { false } # not used in setup container = create_construct(opts) container.maybe_change_dir(chdir) container end # THIS METHOD MAY HAVE EXTERNAL SIDE-EFFECTS, including: # - removing the container directory tree # - changing the current working directory # - modifying any exception passed as `error` # # It is intended to be paired with #setup_construct def teardown_construct(container, error = nil, opts = {}) if error && opts[:keep_on_error] container.keep container.annotate_exception!(error) end container.finalize end end extend Helpers end test_construct-2.0.2/lib/test_construct/rspec_integration.rb0000644000004100000410000000361513475622037024541 0ustar www-datawww-datarequire "test_construct" require "rspec" module TestConstruct module RSpecIntegration module_function # the :test_construct metadata key can be either: # - true (for all defaults) # - a Hash of options # - false/missing (disable the construct for this test) def test_construct_options(example) options = test_construct_default_options options[:name] = example.full_description metadata_options = example.metadata[:test_construct] if metadata_options.is_a?(Hash) options.merge!(metadata_options) end options end def test_construct_enabled?(example) !!example.metadata[:test_construct] end def test_construct_default_options { base_dir: TestConstruct.tmpdir, chdir: true, keep_on_error: true, } end end end RSpec.configure do |config| config.include TestConstruct::Helpers config.include TestConstruct::RSpecIntegration version = RSpec::Version::STRING major, minor, patch, rest = version.split(".") major, minor, patch = [major, minor, patch].map(&:to_i) def before_each(example) return unless test_construct_enabled?(example) options = test_construct_options(example) example.metadata[:construct] = setup_construct(options) end def after_each(example) return unless test_construct_enabled?(example) options = test_construct_options(example) teardown_construct( example.metadata[:construct], example.exception, options) end if major == 2 && minor >= 7 config.before :each do before_each(example) end config.after :each do after_each(example) end elsif major == 3 config.before :each do |example| before_each(example) end config.after :each do |example| after_each(example) end else raise "TestConstruct does not support RSpec #{version}" end end test_construct-2.0.2/lib/test_construct/pathname_extensions.rb0000644000004100000410000000345713475622037025102 0ustar www-datawww-datamodule TestConstruct module PathnameExtensions attr_accessor :construct__chdir_default, :construct__root, :construct__orig_dir def directory(path, opts = {}) chdir = opts.fetch(:chdir, construct__chdir_default) subdir = (self + path) subdir.mkpath subdir.extend(PathnameExtensions) subdir.construct__root = construct__root || self subdir.maybe_change_dir(chdir) do yield(subdir) if block_given? end subdir end def file(filepath, contents = nil, &block) path = (self+filepath) path.dirname.mkpath mode = RUBY_PLATFORM =~ /mingw|mswin/ ? 'wb:UTF-8' : 'w' File.open(path, mode) do |f| if(block) if(block.arity==1) block.call(f) else f << block.call end else f << contents end end path end def maybe_change_dir(chdir, &block) if(chdir) self.construct__orig_dir ||= Pathname.pwd self.chdir(&block) else block.call if block end end def revert_cwd if construct__orig_dir Dir.chdir(construct__orig_dir) end end # Note: Pathname implements #chdir directly, but it is deprecated in favor # of Dir.chdir def chdir(&block) Dir.chdir(self, &block) end def destroy! rmtree end def finalize revert_cwd destroy! unless keep? end def keep if construct__root construct__root.keep else @keep = true end end def keep? defined?(@keep) && @keep end def annotate_exception!(error) error.message << exception_message_annotation error end def exception_message_annotation "\nTestConstruct files kept at: #{self}" end end end test_construct-2.0.2/test_construct.gemspec0000644000004100000410000000214413475622037021270 0ustar www-datawww-data# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'test_construct/version' Gem::Specification.new do |spec| spec.name = "test_construct" spec.version = TestConstruct::VERSION spec.authors = ["Ben Brinckerhoff", "Avdi Grimm"] spec.email = ["ben@bbrinck.com", "avdi@avdi.org"] spec.description = %q{Creates temporary files and directories for testing.} spec.summary = %q{Creates temporary files and directories for testing.} spec.homepage = "https://github.com/bhb/test_construct" spec.license = "MIT" spec.files = `git ls-files`.split($/) spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ["lib"] spec.add_development_dependency "bundler", "~> 1.3" spec.add_development_dependency "rake" spec.add_development_dependency "minitest", "~> 5.0.8" spec.add_development_dependency "mocha", "~> 0.14.0" spec.add_development_dependency "rspec", "~> 3.0" end test_construct-2.0.2/Gemfile0000644000004100000410000000014313475622037016130 0ustar www-datawww-datasource 'https://rubygems.org' # Specify your gem's dependencies in test_construct.gemspec gemspec test_construct-2.0.2/LICENSE.txt0000644000004100000410000000206613475622037016466 0ustar www-datawww-dataCopyright (c) 2013-2019 Ben Brinckerhoff MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.