testrus 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in testrus.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Simon H. Eskildsen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # Testrus
2
+
3
+ Aids in testing your programs in informatics competitions.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'testrus'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install testrus
18
+
19
+ ## Contributing
20
+
21
+ 1. Fork it
22
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
23
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
24
+ 4. Push to the branch (`git push origin my-new-feature`)
25
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "lib"
6
+ t.libs << "test"
7
+ t.pattern = "test/**/*_test.rb"
8
+ end
data/bin/testrus ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'testrus'
4
+
5
+ tester = Testrus::Tester.new(source: :file, formatter: :default, command: ARGV[0..-1].join(" "))
6
+ tester.run
data/lib/testrus.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "testrus/version"
2
+
3
+ Dir[File.dirname(__FILE__) + "/testrus/**/*.rb"].each do |file|
4
+ require file
5
+ end
@@ -0,0 +1,36 @@
1
+ module Testrus
2
+ class Input
3
+ attr_accessor :options
4
+
5
+ # Public: Initializes a new Input. An Input is the standard object from
6
+ # an Input source to the Tester.
7
+ #
8
+ # options - The Hash specifying the input options:
9
+ # :input - The String input matching the expected output.
10
+ # :output - The String expected output from the program for the
11
+ # associated input.
12
+ # :name - The String name of the input, this is usually the
13
+ # number of the test relative to the others, and should be
14
+ # provided by the source.
15
+ #
16
+ def initialize(options)
17
+ @options = options
18
+ end
19
+
20
+ # Public: Returns the name of the input/output pair.
21
+ def name
22
+ @options[:name].strip
23
+ end
24
+
25
+ # Public: Returns the formatted input.
26
+ def input
27
+ @options[:input].strip
28
+ end
29
+
30
+ # Public: Returns the formatted expected output.
31
+ def output
32
+ @options[:output].strip
33
+ end
34
+ alias_method :expected_output, :output
35
+ end
36
+ end
@@ -0,0 +1,99 @@
1
+ module Testrus
2
+ class Input
3
+ class File
4
+ # Public: Create a new Input::File object to handle file sources for input
5
+ # and output.
6
+ #
7
+ # context - The Hash specifying context:
8
+ # :pwd - Working directory for the file source.
9
+ #
10
+ def initialize(context = {})
11
+ @context = context
12
+ end
13
+
14
+ # Public: The working directory of the file input source.
15
+ #
16
+ # Returns the String of the working directory.
17
+ def pwd
18
+ @pwd ||= @context[:pwd].nil? || @context[:pwd].empty? ? default_pwd : @context[:pwd]
19
+ end
20
+
21
+ # Public: Associated the file input and output into Input objects, also
22
+ # caches it so we do not repeat this relatively costly operation on the
23
+ # file system.
24
+ #
25
+ # Returns an Array of Input objects.
26
+ def input
27
+ @input ||= input_files.map do |input|
28
+ Input.new input: ::File.read(input),
29
+ output: ::File.read(output_from_input(input)),
30
+ name: name_from_file_name(input)
31
+ end
32
+ end
33
+ alias_method :tests, :input
34
+
35
+ private
36
+ # Internal: Finds the input files on the filesystem and expands the paths.
37
+ #
38
+ # Returns an Array of Strings of paths to the input files.
39
+ def input_files
40
+ @input_files ||= files("input.*")
41
+ end
42
+
43
+ # Internal: Finds the output files on the filesystem and expands the paths.
44
+ #
45
+ # Returns an Array of Strings of paths to the output files.
46
+ def output_files
47
+ @output_files ||= files("output.*")
48
+ end
49
+
50
+ # Internal: Finds the files with the given wildcard and expands the paths.
51
+ #
52
+ # Returns an Array of Strings of expanded paths.
53
+ def files(wildcard)
54
+ Dir["#{pwd}/#{wildcard}"].map { |file| ::File.expand_path(file) }
55
+ end
56
+
57
+ # Internal: Finds the input file's counterpart in the Array of
58
+ # output_files by querying on the suffix number.
59
+ #
60
+ # Examples
61
+ #
62
+ # output_from_input("/home/testrus/input.2")
63
+ # #=> "/home/testrus/output.2"
64
+ #
65
+ # Returns the full path to the associated output file.
66
+ def output_from_input(input)
67
+ output_files.find do |output|
68
+ name_from_file_name(input) == name_from_file_name(output)
69
+ end
70
+ end
71
+
72
+ # Internal: The name of an input or output file is defined as the last
73
+ # number in the path name. This method returns an input or output file's
74
+ # name.
75
+ #
76
+ # path - The String path of the input or output file.
77
+ #
78
+ # Example
79
+ #
80
+ # name_from_file_name("/home/testrus/input.2")
81
+ # #=> "2"
82
+ #
83
+ # name_from_file_name("/home/testrus/input.ohai.2")
84
+ # #=> "2"
85
+ #
86
+ # Returns a String name of the input or output file.
87
+ def name_from_file_name(path)
88
+ path.match(/\d+$/)[0]
89
+ end
90
+
91
+ # Internal: Default working directory if none was passed.
92
+ #
93
+ # Returns the String path of the working directory.
94
+ def default_pwd
95
+ `pwd`.strip
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,36 @@
1
+ module Testrus
2
+ class Runner
3
+ attr_reader :command
4
+
5
+ # Internal: Specifies the log file.
6
+ LOG_FILE = "/tmp/testrus"
7
+
8
+ # Responsible for running the actual test against a given command (program)
9
+ # a run object about the execution of the program against the given input.
10
+ #
11
+ # command - The String command to pass the input to
12
+ #
13
+ def initialize(command)
14
+ @command = command
15
+ end
16
+
17
+ # Public: Returns an object with the results of running the program against
18
+ # the input.
19
+ #
20
+ # input - The String of input to pass to the program
21
+ #
22
+ # Returns a Runner::Run object with information about the run.
23
+ def run(test)
24
+ system "echo '#{test.input}' | /usr/bin/time -l #{full_command} &> #{LOG_FILE}"
25
+ Run.new File.read(LOG_FILE), test
26
+ end
27
+
28
+ private
29
+ # Internal: Returns the full command, where the script is prefixed with its
30
+ # full path. All options are passed along.
31
+ def full_command
32
+ parts = command.split(" ")
33
+ "#{parts[0..-2].join(" ")} #{`pwd`.strip}/#{parts.last}"
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,71 @@
1
+ module Testrus
2
+ class Runner
3
+ class Run
4
+ attr_reader :output, :test
5
+
6
+ # Responsible for extracting data from the run of the program. See the
7
+ # public methods for what information can be extracted. This class only
8
+ # reads output that is run with the command: `/usr/bin/time -l
9
+ # #{program}`.
10
+ #
11
+ # TODO: Test if this runner works on all UNIX-based operating systems, or
12
+ # only OS X.
13
+ #
14
+ # output - The String output from the command `/usr/bin/time -l program`
15
+ # test - The Test that the input origins from.
16
+ def initialize(output, test)
17
+ @output = output
18
+ @test = test
19
+ end
20
+
21
+ # Public: Extracts the memory usage from the output.
22
+ def memory_usage
23
+ bytes_to_mb(raw_memory_usage)
24
+ end
25
+
26
+ # Public: Extracts the real time from the output.
27
+ def real_time
28
+ time "real"
29
+ end
30
+
31
+ # Public: Extracts the user time from the output.
32
+ def user_time
33
+ time "user"
34
+ end
35
+
36
+ # Public: Extracts the sys time from the output.
37
+ def sys_time
38
+ time "sys"
39
+ end
40
+
41
+ # Public: Boolean value of whether the test passed.
42
+ def passed?
43
+ output == @test.expected_output
44
+ end
45
+
46
+ # Public: Within usual constraints for time and memory
47
+ def within_constraints?
48
+ memory_usage <= 64.00 && real_time <= 1.00
49
+ end
50
+
51
+ # Public: Extracts the output against the input from the entire output
52
+ # which also inclues the time and memory information.
53
+ def output
54
+ @output.split("\n")[0..-16].join("\n").strip
55
+ end
56
+
57
+ private
58
+ def raw_memory_usage
59
+ @output.match(/(\d+)\s+maximum/)[1].to_f
60
+ end
61
+
62
+ def bytes_to_mb(bytes)
63
+ bytes / (2 << 20)
64
+ end
65
+
66
+ def time(type)
67
+ @output.match(/(\d+\.\d+)\s+#{type}/)[1].to_f
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,69 @@
1
+ module Testrus
2
+ class Tester
3
+ attr_reader :options
4
+
5
+ # Internal: Defines the relationship between input sources and their
6
+ # corresponding class names.
7
+ SOURCES = {
8
+ :file => Testrus::Input::File
9
+ }
10
+
11
+ # Internal: Defines the formatters to allow specifying a custom formatter in
12
+ # the options.
13
+ FORMATTERS = {
14
+ :default => Formatter::Default
15
+ }
16
+
17
+ # Public: Initializes a tester object. The tester is responsible for
18
+ # coordinating the input from the input source and the runner, and passing
19
+ # the final results to the formatter.
20
+ #
21
+ # options - The Hash containing the options for the Tester:
22
+ # :source - The Symbol marking the input source, valid options
23
+ # are defined in the class constant Tester::SOURCES.
24
+ # :command - The String specifying the command to run program that
25
+ # the the input will be given to via STDIN.
26
+ #
27
+ def initialize(options)
28
+ @options = default_options.merge(options)
29
+ end
30
+
31
+ # Public: Maps the human source to the class that is responsible for the
32
+ # given source.
33
+ #
34
+ # Returns a corresponding Class constant.
35
+ def source
36
+ @source ||= SOURCES[@options[:source]].new
37
+ end
38
+
39
+ # Public: Returns the instance of the runner which is responsible for
40
+ # running the program against the input.
41
+ def runner
42
+ @runner ||= Testrus::Runner.new(options[:command])
43
+ end
44
+
45
+ # Public: Returns the formatter class.
46
+ def formatter
47
+ FORMATTERS[@options[:formatter]]
48
+ end
49
+
50
+ # Public: Runs the input from the source against the runner. Return the
51
+ # results to the formatter.
52
+ def run
53
+ source.tests.each do |test|
54
+ formatter.new(runner.run(test)).report
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ # Internal: Defines the default options that are overriden by the options
61
+ # passed to initialize.
62
+ def default_options
63
+ {
64
+ :formatter => :default,
65
+ :source => :file
66
+ }
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,57 @@
1
+ require 'colored'
2
+
3
+ module Testrus
4
+ class Tester
5
+ module Formatter
6
+ class Default
7
+ attr_reader :run
8
+
9
+ # Public: The formatter is responsible for reporting the run data to the
10
+ # user. New formatters can easily be added here. The layout of this
11
+ # formatter should be used for guidance on how to create new formatters.
12
+ # Also see the documentation for Run and the sources to find what
13
+ # information is available to the formatter.
14
+ #
15
+ # The formatter does not return anything useful, it is simply used to
16
+ # report to the user. The default formatter simply reports to STDOUT.
17
+ #
18
+ #
19
+ # run - The Run containing the run data (memory usage, output, cpu time,
20
+ # etc.)
21
+ def initialize(run)
22
+ @run = run
23
+ end
24
+
25
+ # Public: Creates the actual report.
26
+ def report
27
+ run.passed? && run.within_constraints? ? report_success : report_failure
28
+ end
29
+
30
+ private
31
+ # Internal: Prints the header in the appropriate color.
32
+ def header(color)
33
+ puts "---> Test #{run.test.name} (#{run.real_time}s, #{run.memory_usage})".send(color)
34
+ end
35
+
36
+ # Internal: Test passed.
37
+ def report_success
38
+ header :green
39
+ end
40
+
41
+ # Internal: Test failed.
42
+ def report_failure
43
+ header :red
44
+
45
+ puts "Input".yellow
46
+ puts "#{run.test.input}\n\n"
47
+
48
+ puts "Expected".yellow
49
+ puts "#{run.test.output}\n\n"
50
+
51
+ puts "Output".yellow
52
+ puts "#{run.output}"
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,3 @@
1
+ module Testrus
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,21 @@
1
+ hello world
2
+ you are fine
3
+
4
+
5
+
6
+
7
+ 0.18 real 0.02 user 0.11 sys
8
+ 552960 maximum resident set size
9
+ 0 average shared memory size
10
+ 0 average unshared data size
11
+ 0 average unshared stack size
12
+ 159 page reclaims
13
+ 0 page faults
14
+ 0 swaps
15
+ 0 block input operations
16
+ 0 block output operations
17
+ 0 messages sent
18
+ 0 messages received
19
+ 0 signals received
20
+ 0 voluntary context switches
21
+ 1 involuntary context switches
@@ -0,0 +1,67 @@
1
+ require 'test_helper'
2
+ require 'testrus/input/file'
3
+ require 'testrus/input'
4
+
5
+ class InputFileTest < Test::Unit::TestCase
6
+ def root_path
7
+ File.expand_path(File.dirname(__FILE__) + "/../..")
8
+ end
9
+
10
+ def setup
11
+ @input_file = Testrus::Input::File.new(pwd: root_path)
12
+ end
13
+
14
+ def test_empty_pwd_context_defaults_to_pwd
15
+ @input_file = Testrus::Input::File.new(pwd: "")
16
+ mock(@input_file).default_pwd { '/home/testrus/project' }
17
+
18
+ assert_equal "/home/testrus/project", @input_file.pwd
19
+ end
20
+
21
+ def test_nil_pwd_context_defaults_to_pwd
22
+ @input_file = Testrus::Input::File.new(pwd: nil)
23
+ mock(@input_file).default_pwd { '/home/testrus/project' }
24
+
25
+ assert_equal "/home/testrus/project", @input_file.pwd
26
+ end
27
+
28
+ def test_fetch_and_associate_simple_file_tests
29
+ File.open("#{root_path}/input.1", "w") { |f| f.write "3 1 2 3" }
30
+ File.open("#{root_path}/output.1", "w") { |f| f.write "6" }
31
+
32
+ parsed_input = @input_file.input
33
+
34
+ assert_equal "3 1 2 3", parsed_input.first.input
35
+ assert_equal "6", parsed_input.first.output
36
+ assert_equal "1", parsed_input.first.name
37
+ end
38
+
39
+ def test_fetch_and_associate_in_out_format_file_tests
40
+ File.open("#{root_path}/input.in.1", "w") { |f| f.write "3 1 2 3" }
41
+ File.open("#{root_path}/output.in.1", "w") { |f| f.write "6" }
42
+
43
+ parsed_input = @input_file.input
44
+
45
+ assert_equal "3 1 2 3", parsed_input.first.input
46
+ assert_equal "6", parsed_input.first.output
47
+ assert_equal "1", parsed_input.first.name
48
+ end
49
+
50
+ def test_fetch_and_ssociate_multiple_simple_file_tests
51
+ File.open("#{root_path}/input.1", "w") { |f| f.write "3 1 2 3" }
52
+ File.open("#{root_path}/output.1", "w") { |f| f.write "6" }
53
+
54
+ File.open("#{root_path}/input.2", "w") { |f| f.write "2 1 2" }
55
+ File.open("#{root_path}/output.2", "w") { |f| f.write "3" }
56
+
57
+ parsed_input = @input_file.input
58
+
59
+ assert_equal "3 1 2 3", parsed_input.first.input
60
+ assert_equal "6", parsed_input.first.output
61
+ assert_equal "1", parsed_input.first.name
62
+
63
+ assert_equal "2 1 2", parsed_input[1].input
64
+ assert_equal "3", parsed_input[1].output
65
+ assert_equal "2", parsed_input[1].name
66
+ end
67
+ end
@@ -0,0 +1,39 @@
1
+ require 'test_helper'
2
+ require 'testrus/input'
3
+
4
+ class TestInput < Test::Unit::TestCase
5
+ def setup
6
+ @input = Testrus::Input.new(input: "3 1 2 3", output: "6", name: "1")
7
+ end
8
+
9
+ def test_input
10
+ assert_equal "3 1 2 3", @input.input
11
+ end
12
+
13
+ def test_output
14
+ assert_equal "6", @input.output
15
+ end
16
+
17
+ def test_options
18
+ assert_equal({input: "3 1 2 3", output: "6", name: "1"}, @input.options)
19
+ end
20
+
21
+ def test_stripped_input
22
+ @input.options[:input] = "\n\n3 1 2 3\n\r\n"
23
+ assert_equal "3 1 2 3", @input.input
24
+ end
25
+
26
+ def test_stripped_output
27
+ @input.options[:output] = "\n\n6\n\r\n"
28
+ assert_equal "6", @input.output
29
+ end
30
+
31
+ def test_name
32
+ assert_equal "1", @input.name
33
+ end
34
+
35
+ def test_stripped_name
36
+ @input.options[:name] = "\n\r1\r\n"
37
+ assert_equal "1", @input.name
38
+ end
39
+ end
data/test/program.rb ADDED
@@ -0,0 +1 @@
1
+ puts $stdin.gets
@@ -0,0 +1,5 @@
1
+ require 'test_helper'
2
+
3
+ class RunnerFormatterDefaultTest < Test::Unit::TestCase
4
+
5
+ end
@@ -0,0 +1,62 @@
1
+ require 'test_helper'
2
+
3
+ class RunnerRunTest < Test::Unit::TestCase
4
+ def setup
5
+ @output = fixture("time_run.txt")
6
+ @test = Testrus::Input.new(input: "world", output: "hello world\nyou are fine", name: "1")
7
+
8
+ @run = Testrus::Runner::Run.new(@output, @test)
9
+ end
10
+
11
+ def test_extract_memory_usage
12
+ assert_equal 0.263671875, @run.memory_usage, 0.01
13
+ end
14
+
15
+ def test_extract_real_time
16
+ assert_equal 0.18, @run.real_time
17
+ end
18
+
19
+ def test_extract_user_time
20
+ assert_equal 0.02, @run.user_time
21
+ end
22
+
23
+ def test_extract_sys_time
24
+ assert_equal 0.11, @run.sys_time
25
+ end
26
+
27
+ def test_extract_output
28
+ assert_equal "hello world\nyou are fine", @run.output
29
+ end
30
+
31
+ def test_passed
32
+ assert @run.passed?, "Run should pass"
33
+ end
34
+
35
+ def test_not_passed
36
+ @test = Testrus::Input.new(input: "world", output: "hello world\nyou are not fine", name: "1")
37
+ @run = Testrus::Runner::Run.new(@output, @test)
38
+
39
+ assert !@run.passed?, "Run should not pass"
40
+ end
41
+
42
+ def test_within_constraints
43
+ stub(@run).real_time { 0.84 }
44
+ stub(@run).memory_usage { 37.00 }
45
+
46
+ assert @run.within_constraints?
47
+ end
48
+
49
+ def test_not_within_time_constraints
50
+ stub(@run).real_time { 1.84 }
51
+ stub(@run).memory_usage { 37.00 }
52
+
53
+ assert !@run.within_constraints?
54
+ end
55
+
56
+ def test_not_within_memory_constraints
57
+ stub(@run).real_time { 0.84 }
58
+ stub(@run).memory_usage { 84.00 }
59
+
60
+ assert !@run.within_constraints?
61
+ end
62
+ end
@@ -0,0 +1,17 @@
1
+ require 'test_helper'
2
+
3
+ class RunnerTest < Test::Unit::TestCase
4
+ def setup
5
+ @path = File.expand_path(File.join(File.dirname(__FILE__), "/program.rb"))
6
+ @runner = Testrus::Runner.new("ruby #{@path}")
7
+ end
8
+
9
+ def test_receives_readable_command
10
+ assert_equal "ruby #{@path}", @runner.command
11
+ end
12
+
13
+ def test_runs_test_with_given_input
14
+ input = Testrus::Input.new input: "6", output: "6", name: "1"
15
+ assert_instance_of Testrus::Runner::Run, @runner.run(input)
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'test-unit'
3
+ require 'rr'
4
+ require 'pry'
5
+
6
+ $: << File.expand_path(File.dirname(__FILE__) + "../lib")
7
+
8
+ require 'testrus'
9
+
10
+ class Test::Unit::TestCase
11
+ include RR::Adapters::TestUnit
12
+
13
+ def test_path
14
+ File.expand_path(File.dirname(__FILE__))
15
+ end
16
+
17
+ def fixture(name)
18
+ File.read "#{test_path}/fixtures/#{name}"
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ require 'test_helper'
2
+ require 'testrus/input'
3
+ require 'testrus/input/file'
4
+ require 'testrus/tester'
5
+
6
+ class TesterTest < Test::Unit::TestCase
7
+ def setup
8
+ @tester = Testrus::Tester.new(:source => :file, :command => "ruby test.rb")
9
+ end
10
+
11
+ def test_set_correct_input_source
12
+ assert_instance_of Testrus::Input::File, @tester.source
13
+ end
14
+
15
+ def test_set_correct_runner
16
+ assert_instance_of Testrus::Runner, @tester.runner
17
+ assert_equal "ruby test.rb", @tester.runner.command
18
+ end
19
+
20
+ def test_default_formatter
21
+ assert_equal :default, @tester.options[:formatter]
22
+ end
23
+
24
+ def test_default_source
25
+ assert_equal :file, @tester.options[:source]
26
+ end
27
+
28
+ def test_return_formatter_class
29
+ assert_equal Testrus::Tester::Formatter::Default, @tester.formatter
30
+ end
31
+
32
+ def test_override_default_options
33
+ @tester = Testrus::Tester.new(:source => :doom)
34
+
35
+ assert_equal :doom, @tester.options[:source]
36
+ end
37
+ end
data/testrus.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'testrus/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "testrus"
8
+ gem.version = Testrus::VERSION
9
+ gem.authors = ["Simon H. Eskildsen"]
10
+ gem.email = ["sirup@sirupsen.com"]
11
+ gem.description = %q{Friendly walrus aiding participators in informatics competitions to test their programs.}
12
+ gem.summary = %q{Testing for informatics competitions.}
13
+ gem.homepage = ""
14
+
15
+ gem.add_dependency("colored", "1.2")
16
+
17
+ gem.add_development_dependency("test-unit", "2.5.2")
18
+ gem.add_development_dependency("fakefs", "0.4.1")
19
+ gem.add_development_dependency("pry", "0.9.10")
20
+ gem.add_development_dependency("rr", "1.0.4")
21
+ gem.add_development_dependency("test-unit", "2.5.3")
22
+ gem.add_development_dependency("rake", "10.0.2")
23
+
24
+ gem.files = `git ls-files`.split($/)
25
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
26
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
27
+ gem.require_paths = ["lib"]
28
+ end
metadata ADDED
@@ -0,0 +1,192 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: testrus
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Simon H. Eskildsen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: colored
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - '='
20
+ - !ruby/object:Gem::Version
21
+ version: '1.2'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - '='
28
+ - !ruby/object:Gem::Version
29
+ version: '1.2'
30
+ - !ruby/object:Gem::Dependency
31
+ name: test-unit
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - '='
36
+ - !ruby/object:Gem::Version
37
+ version: 2.5.2
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - '='
44
+ - !ruby/object:Gem::Version
45
+ version: 2.5.2
46
+ - !ruby/object:Gem::Dependency
47
+ name: fakefs
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - '='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.4.1
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.4.1
62
+ - !ruby/object:Gem::Dependency
63
+ name: pry
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - '='
68
+ - !ruby/object:Gem::Version
69
+ version: 0.9.10
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - '='
76
+ - !ruby/object:Gem::Version
77
+ version: 0.9.10
78
+ - !ruby/object:Gem::Dependency
79
+ name: rr
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - '='
84
+ - !ruby/object:Gem::Version
85
+ version: 1.0.4
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - '='
92
+ - !ruby/object:Gem::Version
93
+ version: 1.0.4
94
+ - !ruby/object:Gem::Dependency
95
+ name: test-unit
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - '='
100
+ - !ruby/object:Gem::Version
101
+ version: 2.5.3
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - '='
108
+ - !ruby/object:Gem::Version
109
+ version: 2.5.3
110
+ - !ruby/object:Gem::Dependency
111
+ name: rake
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - '='
116
+ - !ruby/object:Gem::Version
117
+ version: 10.0.2
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - '='
124
+ - !ruby/object:Gem::Version
125
+ version: 10.0.2
126
+ description: Friendly walrus aiding participators in informatics competitions to test
127
+ their programs.
128
+ email:
129
+ - sirup@sirupsen.com
130
+ executables:
131
+ - testrus
132
+ extensions: []
133
+ extra_rdoc_files: []
134
+ files:
135
+ - .gitignore
136
+ - Gemfile
137
+ - LICENSE.txt
138
+ - README.md
139
+ - Rakefile
140
+ - bin/testrus
141
+ - lib/testrus.rb
142
+ - lib/testrus/input.rb
143
+ - lib/testrus/input/file.rb
144
+ - lib/testrus/runner.rb
145
+ - lib/testrus/runner/run.rb
146
+ - lib/testrus/tester.rb
147
+ - lib/testrus/tester/formatter/default.rb
148
+ - lib/testrus/version.rb
149
+ - test/fixtures/time_run.txt
150
+ - test/input/file_test.rb
151
+ - test/input_test.rb
152
+ - test/program.rb
153
+ - test/runner/formatter/default.rb
154
+ - test/runner/run_test.rb
155
+ - test/runner_test.rb
156
+ - test/test_helper.rb
157
+ - test/tester_test.rb
158
+ - testrus.gemspec
159
+ homepage: ''
160
+ licenses: []
161
+ post_install_message:
162
+ rdoc_options: []
163
+ require_paths:
164
+ - lib
165
+ required_ruby_version: !ruby/object:Gem::Requirement
166
+ none: false
167
+ requirements:
168
+ - - ! '>='
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ required_rubygems_version: !ruby/object:Gem::Requirement
172
+ none: false
173
+ requirements:
174
+ - - ! '>='
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
177
+ requirements: []
178
+ rubyforge_project:
179
+ rubygems_version: 1.8.23
180
+ signing_key:
181
+ specification_version: 3
182
+ summary: Testing for informatics competitions.
183
+ test_files:
184
+ - test/fixtures/time_run.txt
185
+ - test/input/file_test.rb
186
+ - test/input_test.rb
187
+ - test/program.rb
188
+ - test/runner/formatter/default.rb
189
+ - test/runner/run_test.rb
190
+ - test/runner_test.rb
191
+ - test/test_helper.rb
192
+ - test/tester_test.rb