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.
Files changed (40) hide show
  1. data/History.txt +96 -0
  2. data/README.rdoc +135 -0
  3. data/Rakefile +40 -0
  4. data/ciat.gemspec +53 -0
  5. data/lib/ciat.rb +22 -0
  6. data/lib/ciat/cargo.rb +55 -0
  7. data/lib/ciat/compilers/java.rb +54 -0
  8. data/lib/ciat/crate.rb +58 -0
  9. data/lib/ciat/differs/html_differ.rb +20 -0
  10. data/lib/ciat/erb_helpers.rb +83 -0
  11. data/lib/ciat/executors/java.rb +36 -0
  12. data/lib/ciat/executors/parrot.rb +51 -0
  13. data/lib/ciat/feedback/composite.rb +20 -0
  14. data/lib/ciat/feedback/feedback_counter.rb +45 -0
  15. data/lib/ciat/feedback/html_feedback.rb +40 -0
  16. data/lib/ciat/feedback/return_status.rb +23 -0
  17. data/lib/ciat/feedback/standard_output.rb +29 -0
  18. data/lib/ciat/processors/basic_processing.rb +64 -0
  19. data/lib/ciat/processors/compilation_interpreter.rb +18 -0
  20. data/lib/ciat/processors/compiler.rb +18 -0
  21. data/lib/ciat/processors/copy.rb +37 -0
  22. data/lib/ciat/processors/interpreter.rb +18 -0
  23. data/lib/ciat/rake_task.rb +56 -0
  24. data/lib/ciat/suite.rb +112 -0
  25. data/lib/ciat/test.rb +41 -0
  26. data/lib/ciat/test_element.rb +44 -0
  27. data/lib/ciat/traffic_light.rb +39 -0
  28. data/lib/ciat/version.rb +7 -0
  29. data/lib/data/ciat.css +40 -0
  30. data/lib/data/elements.yml +30 -0
  31. data/lib/data/prototype.js +4228 -0
  32. data/lib/templates/detail_row.html.erb +9 -0
  33. data/lib/templates/detail_row/elements.html.erb +3 -0
  34. data/lib/templates/elements/diff.html.erb +7 -0
  35. data/lib/templates/elements/plain.html.erb +8 -0
  36. data/lib/templates/group_header.html.erb +7 -0
  37. data/lib/templates/report.html.erb +38 -0
  38. data/lib/templates/summary_row.html.erb +12 -0
  39. data/lib/templates/test_numbers.html.erb +12 -0
  40. 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>&lt;&lt;</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
@@ -0,0 +1,7 @@
1
+ module CIAT::VERSION #:nodoc:
2
+ MAJOR = 0
3
+ MINOR = 3
4
+ TINY = 0
5
+
6
+ STRING = [MAJOR, MINOR, TINY].join('.')
7
+ end
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
+ }