cutest-1.2.3/0000755000004100000410000000000013312076364013061 5ustar www-datawww-datacutest-1.2.3/test/0000755000004100000410000000000013312076364014040 5ustar www-datawww-datacutest-1.2.3/test/run.rb0000644000004100000410000000566313312076364015203 0ustar www-datawww-datatest "output of successful run" do expected = ".\n" out = %x{./bin/cutest test/fixtures/success.rb} assert_equal(expected, out) end test "exit code of successful run" do %x{./bin/cutest test/fixtures/success.rb} assert_equal 0, $?.to_i end test "output of failed run" do expected = "\n" + " test: failed assertion\n" + " line: assert false\n" + " file: test/fixtures/failure.rb +2\n\n" + "Cutest::AssertionFailed: expression returned false\n\n" out = %x{./bin/cutest test/fixtures/failure.rb} assert_equal(expected, out) end test "output of failed run" do expected = "\n" + " test: some unhandled exception\n" + " line: raise \"Oops\"\n" + " file: test/fixtures/exception.rb +2\n\n" + "RuntimeError: Oops\n\n" out = %x{./bin/cutest test/fixtures/exception.rb} assert_equal(expected, out) end test "exit code of failed run" do %x{./bin/cutest test/fixtures/failure.rb} assert $?.to_i != 0 end test "output of an assertion with custom message" do expected = "\n" + " test: failed with custom message\n" + " line: assert(\"hello\".empty?, \"not empty\")\n" + " file: test/fixtures/fail_custom_message.rb +2\n\n" + "Cutest::AssertionFailed: not empty\n\n" out = %x{./bin/cutest test/fixtures/fail_custom_message.rb} assert_equal(expected, out) end test "output of custom assertion" do expected = "\n" + " test: failed custom assertion\n" + " line: assert_empty \"foo\"\n" + " file: test/fixtures/fail_custom_assertion.rb +6\n\n" + "Cutest::AssertionFailed: not empty\n\n" out = %x{./bin/cutest test/fixtures/fail_custom_assertion.rb} assert_equal(expected, out) end test "output of failure in nested file" do expected = "\n" + " test: failed assertion\n" + " line: assert false\n" + " file: test/fixtures/failure.rb +2\n\n" + "Cutest::AssertionFailed: expression returned false\n\n" out = %x{./bin/cutest test/fixtures/failure_in_loaded_file.rb} assert_equal(expected, out) end test "output of failure outside block" do expected = ".\n" + " test: \n" + " line: assert false\n" + " file: test/fixtures/outside_block.rb +5\n\n" + "Cutest::AssertionFailed: expression returned false\n\n" out = %x{./bin/cutest test/fixtures/outside_block.rb} assert_equal(expected, out) end test "only runs given scope name" do out = %x{./bin/cutest test/fixtures/only_run_given_scope_name.rb -s scope} assert out =~ /This is raised/ end test "runs by given scope and test names" do %x{./bin/cutest test/fixtures/only_run_given_scope_name.rb -s scope -o test} assert_equal 0, $?.to_i end test "only prints the version" do expected = "#{Cutest::VERSION}\n" out = %x{./bin/cutest test/fixtures/success.rb -v} assert_equal(expected, out) end cutest-1.2.3/test/fixtures/0000755000004100000410000000000013312076364015711 5ustar www-datawww-datacutest-1.2.3/test/fixtures/outside_block.rb0000644000004100000410000000007013312076364021061 0ustar www-datawww-datatest "named success" do assert true end assert false cutest-1.2.3/test/fixtures/success.rb0000644000004100000410000000012413312076364017703 0ustar www-datawww-datadef foo raise "Invalid code" end test "external exceptions" do assert true end cutest-1.2.3/test/fixtures/only_run_given_scope_name.rb0000644000004100000410000000026513312076364023467 0ustar www-datawww-datascope "another scope" do test do raise "This is not raised" end end scope "scope" do test "test" do assert true end test do raise "This is raised" end end cutest-1.2.3/test/fixtures/failure.rb0000644000004100000410000000005613312076364017666 0ustar www-datawww-datatest "failed assertion" do assert false end cutest-1.2.3/test/fixtures/fail_custom_message.rb0000644000004100000410000000011713312076364022246 0ustar www-datawww-datatest "failed with custom message" do assert("hello".empty?, "not empty") end cutest-1.2.3/test/fixtures/failure_in_loaded_file.rb0000644000004100000410000000004113312076364022655 0ustar www-datawww-dataload("test/fixtures/failure.rb") cutest-1.2.3/test/fixtures/fail_custom_assertion.rb0000644000004100000410000000017613312076364022636 0ustar www-datawww-datadef assert_empty(string) assert(string.empty?, "not empty") end test "failed custom assertion" do assert_empty "foo" end cutest-1.2.3/test/fixtures/exception.rb0000644000004100000410000000011113312076364020225 0ustar www-datawww-datadef foo raise "Oops" end test "some unhandled exception" do foo end cutest-1.2.3/test/assert_raise.rb0000644000004100000410000000152113312076364017050 0ustar www-datawww-datatest "catches default exception" do assert_raise do raise end end test "catches the right exception" do assert_raise(RuntimeError) do raise RuntimeError end end test "catches exceptions lower than StandardError" do assert_raise(NotImplementedError) do raise NotImplementedError end end test "raises if nothing raised" do assert_raise(Cutest::AssertionFailed) do assert_raise {} end end test "raises if the expectation is not met" do assert_raise(Cutest::AssertionFailed) do assert_raise(RuntimeError) do raise ArgumentError end end end test "returns the exception" do exception = assert_raise(RuntimeError) do raise RuntimeError, "error" end assert_equal "error", exception.message end test "catches a custom exception" do assert_raise do raise Class.new(Exception) end end cutest-1.2.3/test/prepare.rb0000644000004100000410000000047213312076364016026 0ustar www-datawww-dataprepare do $foo = [] end prepare do $foo << true end test "all the prepare blocks are called" do assert $foo == [true] end prepare do $foo << false end test "and are cumulative" do assert $foo == [true, false] end scope do test "and run inside scopes" do assert $foo = [true, false] end end cutest-1.2.3/test/assert_equal.rb0000644000004100000410000000022513312076364017054 0ustar www-datawww-datatest do assert_equal 1, 1 end test "raises if the assertion fails" do assert_raise(Cutest::AssertionFailed) do assert_equal 1, 2 end end cutest-1.2.3/test/scopes.rb0000644000004100000410000000050513312076364015661 0ustar www-datawww-data@bar = true scope do @foo = true test "something" do assert defined?(@foo) assert !defined?(@bar) end end scope do test "something" do assert !defined?(@foo) assert !defined?(@bar) end end scope do @baz = true scope do test "something" do assert !defined?(@baz) end end end cutest-1.2.3/test/setup.rb0000644000004100000410000000111113312076364015517 0ustar www-datawww-datasetup do {:a => 23, :b => 43} end test "should receive the result of the setup block as a parameter" do |params| assert params == {:a => 23, :b => 43} end test "if the params are modified..." do |params| params[:a] = nil end test "...it should preserve the original values from the setup" do |params| assert_equal 23, params[:a] end setup do "Hello world!" end test "only the most recently defined setup block is executed" do |value| assert "Hello world!" == value end scope do test "works inside scopes too" do |value| assert "Hello world!" == value end end cutest-1.2.3/test/assert.rb0000644000004100000410000000025113312076364015664 0ustar www-datawww-datatest "succeeds if the value is true" do assert true end test "raises if the assertion fails" do assert_raise(Cutest::AssertionFailed) do assert false end end cutest-1.2.3/Makefile0000644000004100000410000000011713312076364014520 0ustar www-datawww-dataTESTS=$(shell ls test/*.rb) test: ruby -W2 bin/cutest $(TESTS) .PHONY: test cutest-1.2.3/bin/0000755000004100000410000000000013312076364013631 5ustar www-datawww-datacutest-1.2.3/bin/cutest0000755000004100000410000000073713312076364015075 0ustar www-datawww-data#!/usr/bin/env ruby if ARGV.empty? puts "usage: cutest [-v] [-r lib] [-o test] [-s scope] file ..." exit end require_relative "../lib/cutest" require "clap" files = Clap.run ARGV, "-r" => lambda { |file| require file }, "-o" => lambda { |name| cutest[:only] = name }, "-s" => lambda { |name| cutest[:scope] = name }, "-v" => lambda { puts Cutest::VERSION; exit } if files.any? success = Cutest.run(Dir[*files]) exit(1) unless success end cutest-1.2.3/CHANGELOG.md0000644000004100000410000000107613312076364014676 0ustar www-datawww-data1.2.3 - 2015-12-04 ================== * `assert_raise` now works with lower-level exceptions. * `assert` can now receive a custom failure message, which should help write better custom assertions. * `cutest -v` now exits after printing the version number. 1.2.2 - 2014-11-05 ================== * `assert_raise` now returns the raised exception. * Use `-s` to run a single scope. 1.2.1 - 2013-08-14 ================== * `cutest(1)` now exits with a non-zero status when a test fails. Previous versions ================= Check the commit list for earlier changes. cutest-1.2.3/.gitignore0000644000004100000410000000000513312076364015044 0ustar www-datawww-data/pkg cutest-1.2.3/LICENSE0000644000004100000410000000206413312076364014070 0ustar www-datawww-dataCopyright (c) 2010 Damian Janowski & Michel Martens 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. cutest-1.2.3/lib/0000755000004100000410000000000013312076364013627 5ustar www-datawww-datacutest-1.2.3/lib/cutest.rb0000644000004100000410000001151413312076364015465 0ustar www-datawww-dataclass Cutest unless defined?(VERSION) VERSION = "1.2.3" FILTER = %r[/(ruby|jruby|rbx)[-/]([0-9\.])+] CACHE = Hash.new { |h, k| h[k] = File.readlines(k) } end def self.run(files) status = files.all? do |file| run_file(file) Process.wait2.last.success? end puts status end def self.run_file(file) fork do begin load(file) rescue LoadError, SyntaxError display_error exit 1 rescue StandardError trace = $!.backtrace pivot = trace.index { |line| line.match(file) } puts "\n test: %s" % cutest[:test] if pivot other = trace[0..pivot].select { |line| line !~ FILTER } other.reverse.each { |line| display_trace(line) } else display_trace(trace.first) end display_error exit 1 end end end def self.code(fn, ln) begin CACHE[fn][ln.to_i - 1].strip rescue "(Can't display line)" end end def self.display_error print "\n#{$!.class}: " print "#{$!.message}\n" end def self.display_trace(line) fn, ln = line.split(":") puts " line: #{code(fn, ln)}" puts " file: #{fn} +#{ln}" end class AssertionFailed < StandardError end class Scope def initialize(&scope) @scope = scope end def call instance_eval(&@scope) end end end module Kernel private # Use Thread.current[:cutest] to store information about test preparation # and setup. Thread.current[:cutest] ||= { :prepare => [] } # Shortcut to access Thread.current[:cutest]. def cutest Thread.current[:cutest] end # Create an instance where the block will be evaluated. Recommended to improve # isolation between tests. def scope(name = nil, &block) if !cutest[:scope] || cutest[:scope] == name Cutest::Scope.new(&block).call end end # Prepare the environment in order to run the tests. This method can be # called many times, and each new block is appended to a list of # preparation blocks. When a test is executed, all the preparation blocks # are ran in the order they were declared. If called without a block, it # returns the array of preparation blocks. def prepare(&block) cutest[:prepare] << block if block_given? cutest[:prepare] end # Setup parameters for the tests. The block passed to setup is evaluated # before running each test, and the result of the setup block is passed to # the test as a parameter. If the setup and the tests are declared at the # same level (in the global scope or in a sub scope), it is possible to use # instance variables, but the parameter passing pattern is recommended to # ensure there are no side effects. # # If the setup blocks are declared in the global scope and the tests are # declared in sub scopes, the parameter passing usage is required. # # Setup blocks can be defined many times, but each new definition overrides # the previous one. It is recommended to split the tests in many different # files (the report is per file, not per assertion). Usually one setup # block per file is enough, but nothing forbids having different scopes # with different setup blocks. def setup(&block) cutest[:setup] = block if block_given? cutest[:setup] end # Kernel includes a test method for performing tests on files. undef test if defined? test # Call the prepare and setup blocks before executing the test. Even # though the assertions can live anywhere (it's not mandatory to put them # inside test blocks), it is necessary to wrap them in test blocks in order # to execute preparation and setup blocks. def test(name = nil, &block) cutest[:test] = name if !cutest[:only] || cutest[:only] == name prepare.each { |blk| blk.call } block.call(setup && setup.call) end cutest[:test] = nil end # Assert that value is not nil or false. def assert(value, msg = "expression returned #{value.inspect}") flunk(msg) unless value success end # Assert that actual and expected values are equal. def assert_equal(actual, expected) assert(actual == expected, "#{actual.inspect} != #{expected.inspect}") end # Assert that the block raises an expected exception. def assert_raise(expected = Exception) begin yield rescue expected => exception exception ensure assert(exception.kind_of?(expected), "got #{exception.inspect} instead") end end # Stop the tests and raise an error where the message is the last line # executed before flunking. def flunk(message = nil) backtrace = caller.find { |line| line.include? 'top (required)' } exception = Cutest::AssertionFailed.new(message) exception.set_backtrace(backtrace) raise exception end # Executed when an assertion succeeds. def success print "." end end cutest-1.2.3/cutest.gemspec0000644000004100000410000000113413312076364015734 0ustar www-datawww-datarequire "./lib/cutest" Gem::Specification.new do |s| s.name = "cutest" s.version = Cutest::VERSION s.summary = "Forking tests." s.description = "Run tests in separate processes to avoid shared state." s.authors = ["Damian Janowski", "Michel Martens", "Cyril David"] s.email = ["djanowski@dimaion.com", "michel@soveran.com", "me@cyrildavid.com"] s.homepage = "https://github.com/djanowski/cutest" s.license = "MIT" s.files = `git ls-files`.split("\n") s.executables.push "cutest" s.add_dependency "clap" end cutest-1.2.3/README.markdown0000644000004100000410000001172413312076364015567 0ustar www-datawww-dataCutest ======= [![Gem Version](https://badge.fury.io/rb/cutest.svg)](https://badge.fury.io/rb/cutest) Forking tests. Description ----------- Each test file is run in a forked process to avoid shared state. Once a failure is found, you get a report detailing what failed and how to locate the error and the rest of the file is skipped. You can use the `scope` command around tests: it guarantees that no instance variables are shared between tests. There are two commands very similar in nature, but with a subtle difference that makes them easy to combine in order to satisfy different needs: `prepare` and `setup`. The `prepare` blocks are executed before each test. If you call `prepare` many times, each passed block is appended to an array. When the test is run, all those prepare blocks are executed in order. The result of the block is discarded, so it is only useful for preparing the environment (flushing the database, removing a directory, etc.). The `setup` block is executed before each test and the result is passed as a parameter to the `test` block. Unlike `prepare`, each definition of `setup` overrides the previous one. Even if you can declare instance variables and share them between tests, the recommended usage is to pass the result of the block as a parameter to the `test` blocks. The `test` method executes the passed block after running `prepare` and `setup`. This is where assertions must be declared. Three assertions are available: `assert`, that accepts a value and raises if it's false or nil; `assert_equal`, that raises if its arguments are not equal; and `assert_raise`, that executes a passed block and compares the raised exception to the expected one. In all cases, if the expectation is no met, an `AssertionFailed` exception is raised. You can customize the output of `assert` by providing a second argument with a string you want to get as an error report if the assertion is not fulfilled. This can also be used as a simple building block to build custom assertions. Usage ----- In your terminal: $ cutest test/*.rb In your tests: ````ruby setup do {:a => 23, :b => 43} end test "should receive the result of the setup block as a parameter" do |params| assert params == {:a => 23, :b => 43} end test "should evaluate the setup block before each test" do |params| params[:a] = nil end test "should preserve the original values from the setup" do |params| assert 23 == params[:a] end ``` An example working with a prepare block: ````ruby prepare do Ohm.flush end setup do Ohm.redis.get("foo") end test do |foo| assert foo.nil? end ```` And working with scopes: ````ruby setup do @foo = true end @bar = true scope do test "should not share instance variables" do |foo| assert !defined?(@foo) assert !defined?(@bar) assert foo == true end end ```` The tests in these two examples will pass. Unlike other testing frameworks, Cutest does not compile all the tests before running them. A simple example for adding a custom `empty` assertion: ````ruby def assert_empty(string) assert(string.empty?, "not empty") end test "failed custom assertion" do assert_empty "foo" end ```` Handling errors --------------- If you get an error when running the tests, this is what you will see: ````bash Exception: assert_equal 24, params[:a] # 24 != 23 test/setup.rb +14 ```` Running the build ----------------- Using Rake: ````ruby task :test do exec "cutest test/*.rb" end task :default => :test ```` Using Make: ````yml .PHONY: test test: cutest test/*.rb ```` Command-line interface ---------------------- The tool `cutest` accepts a list of files and sends them to `Cutest.run`. If you need to require a file or library before running the tests, as is the case with test helpers, use the `-r` flag: $ cutest -r ./test/helper.rb ./test/*_test.rb If you want to check which version you are running, try the `-v` flag. Installation ------------ $ gem install cutest License ------- Copyright (c) 2010 Damian Janowski and Michel Martens 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.