ciat 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|