ciat 0.4.8

Sign up to get free protection for your applications and to get access to all the features.
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
+ }