greybox 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +5 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +83 -0
- data/Rakefile +13 -0
- data/bin/greybox +9 -0
- data/example/Greyfile +5 -0
- data/example/test/file1.input +1 -0
- data/example/test/file1.output +1 -0
- data/greybox.gemspec +27 -0
- data/lib/greybox/configurable.rb +66 -0
- data/lib/greybox/configuration.rb +12 -0
- data/lib/greybox/runner.rb +48 -0
- data/lib/greybox/version.rb +3 -0
- data/lib/greybox.rb +38 -0
- data/spec/greybox_spec.rb +12 -0
- data/spec/runner_spec.rb +108 -0
- data/spec/spec_helper.rb +5 -0
- metadata +137 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6403c4bd8f174968087fb1add29ea027ffb2e502
|
4
|
+
data.tar.gz: eaf7e713f00cc65d609a5c80be3f94479da6d42a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c8ca2cc43f5b623785081aff0918db238fd10e052fe2ac23363dd97539d509afec441fc84b7ddf2c55dd04e7aaf596da0ec21c0c007f60944e0d65f2c6f103c0
|
7
|
+
data.tar.gz: 39f8f4521871ee01435b2a1a7829f8037352aaf42d56414e5f6755bcf63942f3e985d3620202dab9c3a06224680bcf8a7fdbda4fe78c031216d2db08407bf739
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Justin Jaffray
|
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,83 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/justinj/greybox.png?branch=master)](https://travis-ci.org/justinj/greybox)
|
2
|
+
[![Code Climate](https://codeclimate.com/github/justinj/greybox.png)](https://codeclimate.com/github/justinj/greybox)
|
3
|
+
|
4
|
+
# Greybox
|
5
|
+
|
6
|
+
Test a CLI program against a black box.
|
7
|
+
Intended for school projects.
|
8
|
+
|
9
|
+
Often when working on a school project, the class will provide a black box to test your programs against.
|
10
|
+
Greybox provides a simple testing harness to easily add new test cases whose expected output is automatically generated by this black box.
|
11
|
+
Since these might be slow, or even over an ssh connection, it will store the results so it only has to actually run the black box the first time.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Only Ruby 1.9.3 and 2.0.0 are supported.
|
16
|
+
|
17
|
+
$ gem install greybox
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
In your project directory, create a file called `Greyfile`.
|
22
|
+
A `Greyfile` might look like this:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
Greybox.setup do |c|
|
26
|
+
c.test_command = "./my_test_command < %"
|
27
|
+
c.blackbox_command = "./blackbox_command < %"
|
28
|
+
c.input = "test/*.input"
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
This defines a testing setup in which the command
|
33
|
+
|
34
|
+
$ ./blackbox_command < INPUT_FILE.input
|
35
|
+
|
36
|
+
is used as the reference for correctness.
|
37
|
+
`%` denotes where the input file will be placed.
|
38
|
+
|
39
|
+
$ ./my_test_command < INPUT_FILE.input
|
40
|
+
|
41
|
+
is verified to match the blackbox output every time
|
42
|
+
|
43
|
+
$ greybox
|
44
|
+
|
45
|
+
is run.
|
46
|
+
|
47
|
+
The expected results will be stored in `INPUT_FILE.output`.
|
48
|
+
This is the default behaviour but can be changed.
|
49
|
+
|
50
|
+
As a more complete example, here is a Greyfile I used for a school project:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
Greybox.setup do |c|
|
54
|
+
c.test_command = "racket wlppscan.ss < % 2>&1"
|
55
|
+
c.blackbox_command = "ssh school 'java cs241.WLPPScan' < % 2>&1"
|
56
|
+
c.input = "test/*.input"
|
57
|
+
|
58
|
+
# if the expected ERRORs, all we care about is that
|
59
|
+
# the actual ERRORs as well.
|
60
|
+
c.comparison = ->(actual, expected) do
|
61
|
+
if expected =~ /ERROR/
|
62
|
+
actual =~ /ERROR/
|
63
|
+
else
|
64
|
+
expected == actual
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
The `test_command` specifies how to run _my_ version of the program, a racket program.
|
71
|
+
`blackbox_command` specifies how to generate the expected output for a specific test case.
|
72
|
+
|
73
|
+
`comparison` specifies how the output of `test_command` should be compared to the black box output.
|
74
|
+
In this case, if part of the output contains `ERROR`, all we care about is that the actual output contains `ERROR` as well.
|
75
|
+
Otherwise, they must be equal.
|
76
|
+
|
77
|
+
## Contributing
|
78
|
+
|
79
|
+
1. Fork it
|
80
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
81
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
82
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
83
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
Rake::TestTask.new do |t|
|
5
|
+
t.libs << "test"
|
6
|
+
t.test_files = ["spec/spec_helper"] + FileList['spec/**/*_spec.rb']
|
7
|
+
end
|
8
|
+
|
9
|
+
task :gem do
|
10
|
+
sh "yes | gem uninstall greybox; true"
|
11
|
+
sh "gem build greybox.gemspec"
|
12
|
+
sh "gem install *.gem"
|
13
|
+
end
|
data/bin/greybox
ADDED
data/example/Greyfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Hello
|
@@ -0,0 +1 @@
|
|
1
|
+
Hello
|
data/greybox.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'greybox/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "greybox"
|
8
|
+
spec.version = Greybox::VERSION
|
9
|
+
spec.authors = ["Justin Jaffray"]
|
10
|
+
spec.email = ["justin.jaffray@gmail.com"]
|
11
|
+
spec.description = %q{Test against a black box.}
|
12
|
+
spec.summary = %q{Easily test school assignments or other projects where you have a reference}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "diffy"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "fakefs"
|
26
|
+
spec.add_development_dependency "mocha"
|
27
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Greybox
|
2
|
+
module Configurable
|
3
|
+
attr_accessor :properties
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
attr_accessor :defaults
|
7
|
+
attr_accessor :required_properties
|
8
|
+
def def_property(name, args = {})
|
9
|
+
setter = "#{name}=".to_sym
|
10
|
+
getter = name
|
11
|
+
(@defaults ||= {})[name] = args[:default] if args.has_key? :default
|
12
|
+
(@required_properties ||= Set.new) << name if args[:required]
|
13
|
+
|
14
|
+
# Stolen from RubyTapas episodes 27 and 28
|
15
|
+
mod = if const_defined?(:Properties, false)
|
16
|
+
const_get(:Properties)
|
17
|
+
else
|
18
|
+
const_set(:Properties, new_blank_properties_module)
|
19
|
+
end
|
20
|
+
|
21
|
+
mod.module_eval %Q{
|
22
|
+
def #{setter}(value)
|
23
|
+
@properties ||= {}
|
24
|
+
@properties[:#{name}] = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def #{getter}
|
28
|
+
get_prop(:#{name})
|
29
|
+
end
|
30
|
+
}
|
31
|
+
|
32
|
+
include mod
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def new_blank_properties_module
|
37
|
+
Module.new do
|
38
|
+
class << self
|
39
|
+
def to_s
|
40
|
+
"Properties(#{properties.join(", ")})"
|
41
|
+
end
|
42
|
+
alias_method :inspect, :to_s
|
43
|
+
|
44
|
+
def properties
|
45
|
+
instance_methods(false).reject { |m| m.to_s.end_with? "=" }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_prop(prop)
|
53
|
+
(@properties || {}).fetch(prop, self.class.defaults[prop])
|
54
|
+
end
|
55
|
+
|
56
|
+
def verify
|
57
|
+
self.class.required_properties.each do |prop|
|
58
|
+
raise "Property #{prop} is required." unless get_prop(prop)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.included(base)
|
63
|
+
base.extend(ClassMethods)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Greybox
|
2
|
+
class Configuration
|
3
|
+
include Configurable
|
4
|
+
|
5
|
+
def_property :input, required: true
|
6
|
+
def_property :test_command, required: true
|
7
|
+
def_property :expected, default: ->(input) { input.gsub(/\.input$/, ".output") }
|
8
|
+
def_property :comparison, default: ->(actual, expected) { actual == expected }
|
9
|
+
def_property :blackbox_command, required: true
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Greybox
|
2
|
+
class Runner
|
3
|
+
attr_reader :failures
|
4
|
+
attr_reader :config
|
5
|
+
|
6
|
+
def initialize(config)
|
7
|
+
@config = config
|
8
|
+
@failures = []
|
9
|
+
end
|
10
|
+
def files
|
11
|
+
Dir.glob(config.input)
|
12
|
+
end
|
13
|
+
|
14
|
+
def expected_filename(input_filename)
|
15
|
+
expected_filename = config.expected.call(input_filename)
|
16
|
+
raise "Output filename for #{input_filename} was same as input!" if expected_filename == input_filename
|
17
|
+
expected_filename
|
18
|
+
end
|
19
|
+
|
20
|
+
def expected_for(filename)
|
21
|
+
file = expected_filename(filename)
|
22
|
+
File.open(file, 'w') do |f|
|
23
|
+
f.write run_command(config.blackbox_command, filename)
|
24
|
+
end
|
25
|
+
File.read(file)
|
26
|
+
end
|
27
|
+
|
28
|
+
def run
|
29
|
+
files.each do |input_file|
|
30
|
+
expected = expected_for(input_file)
|
31
|
+
actual = run_command(config.test_command, input_file)
|
32
|
+
report_failure(input_file, expected, actual) unless config.comparison.call(actual, expected)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def run_command(command, file)
|
37
|
+
`#{insert_filename(command, file)}`
|
38
|
+
end
|
39
|
+
|
40
|
+
def insert_filename(command, filename)
|
41
|
+
command.gsub("%", filename)
|
42
|
+
end
|
43
|
+
|
44
|
+
def report_failure(filename, expected, actual)
|
45
|
+
@failures << { filename: filename, expected: expected, actual: actual }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/greybox.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require "set"
|
2
|
+
require "diffy"
|
3
|
+
require "greybox/version"
|
4
|
+
require "greybox/configurable"
|
5
|
+
require "greybox/runner"
|
6
|
+
require "greybox/configuration"
|
7
|
+
|
8
|
+
module Greybox
|
9
|
+
class << self
|
10
|
+
attr_reader :failures
|
11
|
+
attr_reader :configuration
|
12
|
+
attr_reader :runner
|
13
|
+
def setup(&blk)
|
14
|
+
config(&blk)
|
15
|
+
run
|
16
|
+
check
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
@runner = Runner.new(configuration)
|
21
|
+
runner.run
|
22
|
+
end
|
23
|
+
|
24
|
+
def check
|
25
|
+
runner.failures.each do |failure|
|
26
|
+
puts "FAILED:"
|
27
|
+
puts "filename: #{failure[:filename]}"
|
28
|
+
puts Diffy::Diff.new(failure[:expected], failure[:actual])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def config
|
33
|
+
@configuration = Configuration.new
|
34
|
+
yield configuration
|
35
|
+
configuration.verify
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/spec/runner_spec.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
module Greybox
|
2
|
+
describe Runner do
|
3
|
+
before do
|
4
|
+
FakeFS.activate!
|
5
|
+
|
6
|
+
FileUtils.touch "inputfile.input"
|
7
|
+
end
|
8
|
+
|
9
|
+
after do
|
10
|
+
FakeFS.activate!
|
11
|
+
Dir.glob("*").each { |f| FileUtils.rm f }
|
12
|
+
FakeFS.deactivate!
|
13
|
+
end
|
14
|
+
|
15
|
+
# it should be noted these are just the defaults
|
16
|
+
# for these tests to reduce duplication,
|
17
|
+
# the real-world defaults are different
|
18
|
+
def defaults
|
19
|
+
{
|
20
|
+
input: "*.input",
|
21
|
+
expected: ->(input) { "output_file" },
|
22
|
+
blackbox_command: "echo BLACKBOX_COMMAND",
|
23
|
+
comparison: ->(actual, expected) { actual == expected },
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :runner
|
28
|
+
|
29
|
+
def with_config(config = {})
|
30
|
+
@runner = Runner.new(stub(defaults.merge(config)))
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "finding files" do
|
34
|
+
it "uses the glob to find files" do
|
35
|
+
with_config
|
36
|
+
runner.files.must_equal ["inputfile.input"]
|
37
|
+
end
|
38
|
+
|
39
|
+
it "uses the 'expected' value to determine the expected name" do
|
40
|
+
with_config(expected: ->(input) {
|
41
|
+
input.gsub(/\.input$/, ".output")
|
42
|
+
})
|
43
|
+
runner.expected_filename("hello.input").must_equal "hello.output"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "complains if the output is the same as the input" do
|
47
|
+
with_config(expected: ->(input){ input })
|
48
|
+
->() { runner.expected_filename("input.input") }.must_raise RuntimeError
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "running commands" do
|
53
|
+
it "uses the provided test command" do
|
54
|
+
with_config(test_command: "echo TEST_COMMAND")
|
55
|
+
runner.expects(:`).with("echo TEST_COMMAND")
|
56
|
+
runner.expects(:`).with("echo BLACKBOX_COMMAND")
|
57
|
+
runner.run
|
58
|
+
end
|
59
|
+
|
60
|
+
it "inserts filenames for %'s" do
|
61
|
+
with_config(test_command: "echo hi %")
|
62
|
+
runner.expects(:`).with "echo hi inputfile.input"
|
63
|
+
runner.expects(:`).with "echo BLACKBOX_COMMAND"
|
64
|
+
runner.run
|
65
|
+
end
|
66
|
+
|
67
|
+
it "uses the provided blackbox command to find the expected value for cases that don't have one yet" do
|
68
|
+
with_config(test_command: "echo hi",
|
69
|
+
blackbox_command: "echo output")
|
70
|
+
runner.expects(:`).with "echo hi"
|
71
|
+
runner.expects(:`).with "echo output"
|
72
|
+
runner.run
|
73
|
+
end
|
74
|
+
|
75
|
+
it "inserts output filenames for %'s in the blackbox command" do
|
76
|
+
with_config(test_command: "echo hi",
|
77
|
+
blackbox_command: "echo output < %")
|
78
|
+
runner.expects(:`).with "echo hi"
|
79
|
+
runner.expects(:`).with "echo output < inputfile.input"
|
80
|
+
runner.run
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "asserting output" do
|
85
|
+
it "compares for equality by default" do
|
86
|
+
with_config(test_command: "echo hi",
|
87
|
+
blackbox_command: "echo hi")
|
88
|
+
runner.run
|
89
|
+
runner.failures.must_be_empty
|
90
|
+
end
|
91
|
+
|
92
|
+
it "has a failure if a test fails" do
|
93
|
+
with_config(test_command: "echo hi",
|
94
|
+
blackbox_command: "echo hello")
|
95
|
+
runner.run
|
96
|
+
runner.failures.wont_be_empty
|
97
|
+
end
|
98
|
+
|
99
|
+
it "compares by the provided comparison" do
|
100
|
+
with_config(comparison: ->(actual, expected) { actual == "hi\n" },
|
101
|
+
test_command: "echo hi",
|
102
|
+
blackbox_command: "echo hello")
|
103
|
+
runner.run
|
104
|
+
runner.failures.must_be_empty
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: greybox
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Justin Jaffray
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-10-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: diffy
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: fakefs
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mocha
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Test against a black box.
|
84
|
+
email:
|
85
|
+
- justin.jaffray@gmail.com
|
86
|
+
executables:
|
87
|
+
- greybox
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- .gitignore
|
92
|
+
- .travis.yml
|
93
|
+
- Gemfile
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- bin/greybox
|
98
|
+
- example/Greyfile
|
99
|
+
- example/test/file1.input
|
100
|
+
- example/test/file1.output
|
101
|
+
- greybox.gemspec
|
102
|
+
- lib/greybox.rb
|
103
|
+
- lib/greybox/configurable.rb
|
104
|
+
- lib/greybox/configuration.rb
|
105
|
+
- lib/greybox/runner.rb
|
106
|
+
- lib/greybox/version.rb
|
107
|
+
- spec/greybox_spec.rb
|
108
|
+
- spec/runner_spec.rb
|
109
|
+
- spec/spec_helper.rb
|
110
|
+
homepage: ''
|
111
|
+
licenses:
|
112
|
+
- MIT
|
113
|
+
metadata: {}
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 2.0.3
|
131
|
+
signing_key:
|
132
|
+
specification_version: 4
|
133
|
+
summary: Easily test school assignments or other projects where you have a reference
|
134
|
+
test_files:
|
135
|
+
- spec/greybox_spec.rb
|
136
|
+
- spec/runner_spec.rb
|
137
|
+
- spec/spec_helper.rb
|