ciat 0.4.8
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +96 -0
- data/README.rdoc +135 -0
- data/Rakefile +40 -0
- data/ciat.gemspec +53 -0
- data/lib/ciat.rb +22 -0
- data/lib/ciat/cargo.rb +55 -0
- data/lib/ciat/compilers/java.rb +54 -0
- data/lib/ciat/crate.rb +58 -0
- data/lib/ciat/differs/html_differ.rb +20 -0
- data/lib/ciat/erb_helpers.rb +83 -0
- data/lib/ciat/executors/java.rb +36 -0
- data/lib/ciat/executors/parrot.rb +51 -0
- data/lib/ciat/feedback/composite.rb +20 -0
- data/lib/ciat/feedback/feedback_counter.rb +45 -0
- data/lib/ciat/feedback/html_feedback.rb +40 -0
- data/lib/ciat/feedback/return_status.rb +23 -0
- data/lib/ciat/feedback/standard_output.rb +29 -0
- data/lib/ciat/processors/basic_processing.rb +64 -0
- data/lib/ciat/processors/compilation_interpreter.rb +18 -0
- data/lib/ciat/processors/compiler.rb +18 -0
- data/lib/ciat/processors/copy.rb +37 -0
- data/lib/ciat/processors/interpreter.rb +18 -0
- data/lib/ciat/rake_task.rb +56 -0
- data/lib/ciat/suite.rb +112 -0
- data/lib/ciat/test.rb +41 -0
- data/lib/ciat/test_element.rb +44 -0
- data/lib/ciat/traffic_light.rb +39 -0
- data/lib/ciat/version.rb +7 -0
- data/lib/data/ciat.css +40 -0
- data/lib/data/elements.yml +30 -0
- data/lib/data/prototype.js +4228 -0
- data/lib/templates/detail_row.html.erb +9 -0
- data/lib/templates/detail_row/elements.html.erb +3 -0
- data/lib/templates/elements/diff.html.erb +7 -0
- data/lib/templates/elements/plain.html.erb +8 -0
- data/lib/templates/group_header.html.erb +7 -0
- data/lib/templates/report.html.erb +38 -0
- data/lib/templates/summary_row.html.erb +12 -0
- data/lib/templates/test_numbers.html.erb +12 -0
- metadata +99 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
class CIAT::Processors::CompilationInterpreter
|
2
|
+
def element_name_hash
|
3
|
+
{
|
4
|
+
:green => [:compilation_generated, :execution_generated],
|
5
|
+
:yellow => [:compilation_generated, :execution_error],
|
6
|
+
:red => [:compilation_generated, :execution_diff],
|
7
|
+
:unset => []
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
def input_name
|
12
|
+
:compilation_generated
|
13
|
+
end
|
14
|
+
|
15
|
+
def output_name
|
16
|
+
:execution
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CIAT::Processors::Compiler
|
2
|
+
def element_name_hash
|
3
|
+
{
|
4
|
+
:green => [:source, :compilation_generated],
|
5
|
+
:yellow => [:source, :compilation_error],
|
6
|
+
:red => [:source, :compilation_diff],
|
7
|
+
:unset => []
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
def input_name
|
12
|
+
:source
|
13
|
+
end
|
14
|
+
|
15
|
+
def output_name
|
16
|
+
:compilation
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module CIAT
|
2
|
+
module Processors
|
3
|
+
# A simple processor that just simply copies the code from one file to the other
|
4
|
+
# using the Unix +cp+ command.
|
5
|
+
class Copy
|
6
|
+
attr :light, true
|
7
|
+
|
8
|
+
def initialize(original, copy)
|
9
|
+
@original = original
|
10
|
+
@copy = copy
|
11
|
+
@light = CIAT::TrafficLight.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def for_test
|
15
|
+
copy = clone
|
16
|
+
copy.light = light.clone
|
17
|
+
copy
|
18
|
+
end
|
19
|
+
|
20
|
+
def describe
|
21
|
+
"copy processor"
|
22
|
+
end
|
23
|
+
|
24
|
+
def process(crate)
|
25
|
+
if system( "cp '#{crate.element(@original).as_file}' '#{crate.element(@copy).as_file}'")
|
26
|
+
light.green!
|
27
|
+
else
|
28
|
+
light.red!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def relevant_elements(crate)
|
33
|
+
[@original, @copy].map { |e| crate.element(e) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CIAT::Processors::Interpreter
|
2
|
+
def element_name_hash
|
3
|
+
{
|
4
|
+
:green => [:source, :command_line, :execution_generated],
|
5
|
+
:yellow => [:source, :command_line, :execution_error],
|
6
|
+
:red => [:source, :command_line, :execution_diff],
|
7
|
+
:unset => []
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
def input_name
|
12
|
+
:source
|
13
|
+
end
|
14
|
+
|
15
|
+
def output_name
|
16
|
+
:execution
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# = A Rake Task for a Suite of Tests
|
2
|
+
#
|
3
|
+
# This is the class to use in your +Rakefile+. The simplest use looks like
|
4
|
+
# this:
|
5
|
+
#
|
6
|
+
# CIAT::RakeTask(:name_of_task) do |t|
|
7
|
+
# t.processors << compiler
|
8
|
+
# t.processors << executor
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# Define +compiler+ and +executor+ in the +Rakefile+ to return a compiler and
|
12
|
+
# executor, respectively. <code>:name_of_task</code> is (as I try to make
|
13
|
+
# clear by its name) the name of the rake task. If you leave out this name,
|
14
|
+
# it defaults to <code>:ciat</code>. The options on +t+ correspond directly
|
15
|
+
# to the options of CIAT::Suite. See CIAT::Suite for defaults and details.
|
16
|
+
#
|
17
|
+
# * <code>t.processors</code> is <em>required</em> and specifies the
|
18
|
+
# processors to be executed; order matters! Use <code>=</code> to assign a
|
19
|
+
# list of processors; use <code><<</code> to push processors onto the
|
20
|
+
# existing list of processors.
|
21
|
+
# * <code>t.folder</code> specifies folders to search for test files.
|
22
|
+
# * <code>t.files</code> is an array of specific files.
|
23
|
+
# * <code>t.report_filename</code> is the name of the report
|
24
|
+
# * <code>t.feedback</code> specifies a feedback mechanism
|
25
|
+
#
|
26
|
+
class CIAT::RakeTask
|
27
|
+
attr_accessor :processors
|
28
|
+
attr_accessor :files
|
29
|
+
attr_accessor :feedback
|
30
|
+
attr_accessor :folder
|
31
|
+
attr_accessor :report_filename
|
32
|
+
attr_accessor :report_title
|
33
|
+
attr_accessor :output_folder
|
34
|
+
|
35
|
+
def initialize(name = :ciat)
|
36
|
+
@name = name
|
37
|
+
@processors = []
|
38
|
+
yield self if block_given?
|
39
|
+
define
|
40
|
+
end
|
41
|
+
|
42
|
+
def define
|
43
|
+
desc "Run CIAT tests" + (@name==:test ? "" : ", #{@name}")
|
44
|
+
task @name do
|
45
|
+
suite = CIAT::Suite.new(
|
46
|
+
:processors => @processors,
|
47
|
+
:files => @files,
|
48
|
+
:feedback => @feedback,
|
49
|
+
:folder => @folder,
|
50
|
+
:report_filename => @report_filename,
|
51
|
+
:output_folder => @output_folder,
|
52
|
+
:report_title => @report_title)
|
53
|
+
suite.run
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/ciat/suite.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'ciat/feedback/composite'
|
3
|
+
require 'ciat/feedback/feedback_counter'
|
4
|
+
require 'ciat/feedback/return_status'
|
5
|
+
|
6
|
+
# = A Suite of Tests
|
7
|
+
#
|
8
|
+
# This is the top-level class for organizing CIAT tests. It can be used in a
|
9
|
+
# +Rakefile+ like so:
|
10
|
+
#
|
11
|
+
# task :ciat do
|
12
|
+
# CIAT::Suite.new(:processors => [compiler, executor]).run
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# You may find the CIAT::RakeTask a little bit easier and more familiar
|
16
|
+
# to use.
|
17
|
+
#
|
18
|
+
# == Specifying Test and Output Files and Folders
|
19
|
+
#
|
20
|
+
# By default, this suite will do the following:
|
21
|
+
# * find tests ending in <code>.ciat</code> in a folder named
|
22
|
+
# <code>ciat</code>,
|
23
|
+
# * use simple standard-output feedback,
|
24
|
+
# * put all output files into a folder named <code>temp</code>,
|
25
|
+
# * produce an HTML report in <code>temp/report.html</code>.
|
26
|
+
#
|
27
|
+
# Each of these settings can be overridden with these options:
|
28
|
+
# * <code>:processors</code> is <em>required</em> and specifies the processors
|
29
|
+
# to be executed; order matters!
|
30
|
+
# * <code>:folder</code> specifies folders to search for test files (default:
|
31
|
+
# <code>ciat/**</code>).
|
32
|
+
# * <code>:pattern</code> specifies a pattern for matching test files
|
33
|
+
# (default: <code>*.ciat</code>).
|
34
|
+
# * <code>:files</code> is an array of specific files (default: none).
|
35
|
+
# * <code>:output_folder</code> is the output folder (default: +temp+)
|
36
|
+
# * <code>:report_filename</code> is the name of the report (default:
|
37
|
+
# <code>report.html</code> in the output folder)
|
38
|
+
# * <code>:feedback</code> specifies a feedback mechanism (default: a
|
39
|
+
# CIAT::Feedback::StandardOutput).
|
40
|
+
#
|
41
|
+
# <code>:folder</code> and <code>:pattern</code> can be used together;
|
42
|
+
# <code>:files</code> overrides both <code>:folder</code> and
|
43
|
+
# <code>:pattern</code>.
|
44
|
+
#
|
45
|
+
# == Processors
|
46
|
+
#
|
47
|
+
# You can create your own processors. Each processor needs to specify which
|
48
|
+
# test elements it wants or will accept, which files it wants checked, and how
|
49
|
+
# it should be executed. See CIAT::Compilers::Java and
|
50
|
+
# CIAT::Executors::Parrot (to learn how to use them and how to write others).
|
51
|
+
#
|
52
|
+
# == Test File
|
53
|
+
#
|
54
|
+
# See the README for details on the format of a test file.
|
55
|
+
#
|
56
|
+
class CIAT::Suite
|
57
|
+
attr_reader :cargo
|
58
|
+
attr_reader :results
|
59
|
+
attr_reader :processors
|
60
|
+
attr_reader :report_title
|
61
|
+
|
62
|
+
# Constructs a suite of CIAT tests. See the instructions above for possible
|
63
|
+
# values for the +options+.
|
64
|
+
def initialize(options = {})
|
65
|
+
@processors = options[:processors]
|
66
|
+
@cargo = options[:cargo] || CIAT::Cargo.new(options)
|
67
|
+
@report_title = "CIAT Report"
|
68
|
+
if options[:report_title]
|
69
|
+
@report_title = @report_title + ": " + options[:report_title]
|
70
|
+
end
|
71
|
+
@feedback = options[:feedback] || default_feedback
|
72
|
+
@feedback = CIAT::Feedback::Composite.new(
|
73
|
+
@feedback, CIAT::Feedback::ReturnStatus.new
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns the number of tests in the suite.
|
78
|
+
def size
|
79
|
+
cargo.size
|
80
|
+
end
|
81
|
+
|
82
|
+
# Runs all of the tests in the suite, and returns the results. The results
|
83
|
+
# are also available through #results.
|
84
|
+
def run
|
85
|
+
@feedback.pre_tests(self)
|
86
|
+
@results = cargo.crates.
|
87
|
+
map { |crate| create_test(crate) }.
|
88
|
+
map { |test| test.run }
|
89
|
+
@feedback.post_tests(self)
|
90
|
+
@results
|
91
|
+
end
|
92
|
+
|
93
|
+
def create_test(crate)
|
94
|
+
CIAT::Test.new(crate.test_file,
|
95
|
+
crate.process_test_file,
|
96
|
+
:processors => test_processors,
|
97
|
+
:feedback => @feedback)
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_processors #:nodoc:
|
101
|
+
@processors.map { |processor| processor.for_test }
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
def default_feedback
|
106
|
+
counter = CIAT::Feedback::FeedbackCounter.new
|
107
|
+
CIAT::Feedback::Composite.new(counter,
|
108
|
+
CIAT::Feedback::StandardOutput.new(counter),
|
109
|
+
CIAT::Feedback::HtmlFeedback.new(counter)
|
110
|
+
)
|
111
|
+
end
|
112
|
+
end
|
data/lib/ciat/test.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
class CIAT::Test
|
4
|
+
attr_reader :filename
|
5
|
+
attr_reader :processors
|
6
|
+
attr_reader :elements
|
7
|
+
|
8
|
+
def initialize(filename, elements, options={}) #:nodoc:
|
9
|
+
@filename = filename
|
10
|
+
@elements = elements
|
11
|
+
@processors = options[:processors]
|
12
|
+
@feedback = options[:feedback]
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
run_processors
|
17
|
+
report_lights
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def run_processors #:nodoc:
|
22
|
+
processors.each do |processor|
|
23
|
+
processor.process(self)
|
24
|
+
break unless processor.light.green?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def report_lights #:nodoc:
|
29
|
+
processors.each do |processor|
|
30
|
+
@feedback.processor_result(processor)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def element(*names)
|
35
|
+
elements[names.compact.join("_").to_sym]
|
36
|
+
end
|
37
|
+
|
38
|
+
def element?(*names)
|
39
|
+
elements.has_key?(names.compact.join("_").to_sym)
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
class CIAT::TestElement
|
4
|
+
attr_reader :name
|
5
|
+
attr_reader :filename
|
6
|
+
|
7
|
+
def initialize(name, filename, content)
|
8
|
+
@name = name
|
9
|
+
@filename = filename
|
10
|
+
@content = content
|
11
|
+
end
|
12
|
+
|
13
|
+
def template
|
14
|
+
if yaml_entry.nil?
|
15
|
+
raise "Need entry for #{name.to_s} in data/elements.yml"
|
16
|
+
end
|
17
|
+
File.join("elements", yaml_entry["template"])
|
18
|
+
end
|
19
|
+
|
20
|
+
def describe
|
21
|
+
yaml_entry["description"]
|
22
|
+
end
|
23
|
+
|
24
|
+
def yaml_entry
|
25
|
+
metadata[name.to_s]
|
26
|
+
end
|
27
|
+
|
28
|
+
def content
|
29
|
+
@content ||= CIAT::Cargo.read_file(@filename)
|
30
|
+
end
|
31
|
+
|
32
|
+
def as_file
|
33
|
+
if @content
|
34
|
+
CIAT::Cargo.write_file(@filename, @content)
|
35
|
+
end
|
36
|
+
@filename
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def metadata
|
42
|
+
@@metadata ||= YAML.load_file(File.join(File.dirname(__FILE__), "..", "data", "elements.yml"))
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class CIAT::TrafficLight
|
2
|
+
attr_reader :setting
|
3
|
+
|
4
|
+
def initialize(setting = :unset) #:nodoc:
|
5
|
+
@setting = setting
|
6
|
+
end
|
7
|
+
|
8
|
+
def unset?
|
9
|
+
@setting == :unset
|
10
|
+
end
|
11
|
+
|
12
|
+
def green?
|
13
|
+
@setting == :green
|
14
|
+
end
|
15
|
+
|
16
|
+
def green! #:nodoc:
|
17
|
+
@setting = :green unless yellow?
|
18
|
+
end
|
19
|
+
|
20
|
+
def yellow?
|
21
|
+
@setting == :yellow
|
22
|
+
end
|
23
|
+
|
24
|
+
def yellow! #:nodoc:
|
25
|
+
@setting = :yellow
|
26
|
+
end
|
27
|
+
|
28
|
+
def red?
|
29
|
+
@setting == :red
|
30
|
+
end
|
31
|
+
|
32
|
+
def red! #:nodoc:
|
33
|
+
@setting = :red unless yellow?
|
34
|
+
end
|
35
|
+
|
36
|
+
def color
|
37
|
+
@setting.to_s
|
38
|
+
end
|
39
|
+
end
|
data/lib/ciat/version.rb
ADDED
data/lib/data/ciat.css
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
/* color scheme from FitNesse */
|
2
|
+
.red {
|
3
|
+
background-color: #FFAAAA;
|
4
|
+
}
|
5
|
+
.green {
|
6
|
+
background-color: #AAFFAA;
|
7
|
+
}
|
8
|
+
.yellow {
|
9
|
+
background-color: #FFFFAA;
|
10
|
+
}
|
11
|
+
.unset {
|
12
|
+
background-color: #CCCCCC;
|
13
|
+
}
|
14
|
+
|
15
|
+
.code {
|
16
|
+
background-color: #AAAAFF;
|
17
|
+
}
|
18
|
+
|
19
|
+
.compilation_error .code {
|
20
|
+
background-color: #FFFFAA;
|
21
|
+
}
|
22
|
+
|
23
|
+
|
24
|
+
.results {
|
25
|
+
clear: both;
|
26
|
+
}
|
27
|
+
|
28
|
+
.details .diff td {
|
29
|
+
padding-top: 0;
|
30
|
+
padding-bottom: 0;
|
31
|
+
}
|
32
|
+
|
33
|
+
.details pre {
|
34
|
+
padding: 0.5em;
|
35
|
+
margin: 0;
|
36
|
+
}
|
37
|
+
|
38
|
+
.details h4, .details h3 {
|
39
|
+
margin: 0;
|
40
|
+
}
|