rcor 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile.rb +39 -0
- data/lib/concordion.rb +66 -0
- data/lib/concordion_binder.rb +24 -0
- data/lib/concordion_constants.rb +13 -0
- data/lib/concordion_css.rb +172 -0
- data/lib/concordion_css_decorator.rb +52 -0
- data/lib/concordion_environment.rb +28 -0
- data/lib/concordion_instrumenter.rb +30 -0
- data/lib/concordion_invocation_string_builder.rb +24 -0
- data/lib/concordion_invoker.rb +33 -0
- data/lib/concordion_lookahead_handler.rb +17 -0
- data/lib/concordion_parse_result.rb +31 -0
- data/lib/concordion_parser.rb +47 -0
- data/lib/concordion_processor.rb +24 -0
- data/lib/concordion_reader.rb +18 -0
- data/lib/concordion_string_utility.rb +63 -0
- data/lib/concordion_string_writer.rb +13 -0
- data/lib/concordion_test_case.rb +97 -0
- data/lib/concordion_utility.rb +70 -0
- data/lib/concordion_verifier.rb +50 -0
- data/lib/concordion_writer.rb +43 -0
- data/lib/goldmaster_test_case.rb +32 -0
- data/lib/rcor.rb +2 -0
- data/nbproject/private/config.properties +0 -0
- data/nbproject/private/private.properties +4 -0
- data/nbproject/private/private.xml +10 -0
- data/nbproject/project.properties +11 -0
- data/nbproject/project.xml +16 -0
- data/test-lib/single_row_result.rb +9 -0
- data/test-lib/user.rb +8 -0
- data/tests/attr_assert.html +5 -0
- data/tests/attr_assert_test.rb +13 -0
- data/tests/basic_assert.html +5 -0
- data/tests/basic_assert_test.rb +9 -0
- data/tests/basic_assert_true.html +6 -0
- data/tests/basic_assert_true_test.rb +11 -0
- data/tests/basic_set.html +8 -0
- data/tests/basic_set_test.rb +8 -0
- data/tests/basic_text.html +6 -0
- data/tests/basic_text_test.rb +12 -0
- data/tests/concordion.css +2 -0
- data/tests/concordion_css_decorator_test.rb +28 -0
- data/tests/concordion_environment_test.rb +44 -0
- data/tests/concordion_parse_result_test.rb +33 -0
- data/tests/concordion_test.rb +49 -0
- data/tests/concordion_utility_test.rb +88 -0
- data/tests/concordion_verifier_test.rb +38 -0
- data/tests/concordion_writer_test.rb +26 -0
- data/tests/failing.html +5 -0
- data/tests/failing_test.rb +15 -0
- data/tests/goldmaster_failing.html +5 -0
- data/tests/goldmaster_failing_goldmaster.html +162 -0
- data/tests/goldmaster_failing_test.rb +11 -0
- data/tests/goldmaster_passing.html +5 -0
- data/tests/goldmaster_passing_goldmaster.html +162 -0
- data/tests/goldmaster_passing_test.rb +9 -0
- data/tests/goldmaster_table.html +46 -0
- data/tests/goldmaster_table_goldmaster.html +203 -0
- data/tests/goldmaster_table_test.rb +17 -0
- data/tests/lookahead_assert_true.html +25 -0
- data/tests/lookahead_assert_true_test.rb +17 -0
- data/tests/nested_element_lookahead.html +9 -0
- data/tests/nested_element_lookahead_test.rb +8 -0
- data/tests/processes_elements_in_sorted_order.html +12 -0
- data/tests/processes_elements_in_sorted_order_test.rb +13 -0
- data/tests/return_result.html +7 -0
- data/tests/return_result_test.rb +17 -0
- data/tests/single_row_table.html +13 -0
- data/tests/single_row_table_test.rb +9 -0
- data/tests/table.html +28 -0
- data/tests/table_test.rb +9 -0
- data/tests/test_helper.rb +9 -0
- data/tests/verify_rows.html +46 -0
- data/tests/verify_rows_scsr.html +27 -0
- data/tests/verify_rows_scsr_test.rb +15 -0
- data/tests/verify_rows_test.rb +16 -0
- metadata +142 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
class ConcordionInvoker
|
2
|
+
def initialize(conc)
|
3
|
+
@concordion = conc
|
4
|
+
@builder = conc.invocation_builder
|
5
|
+
end
|
6
|
+
|
7
|
+
def invoke_sut(cpr, test_context)
|
8
|
+
sut_rv = nil
|
9
|
+
if cpr.needs_dereference?
|
10
|
+
sut_rv = @concordion.dereference(cpr.system_under_test)
|
11
|
+
else
|
12
|
+
invocation_str = @builder.build_invocation_string(cpr.system_under_test, cpr.content)
|
13
|
+
sut_rv = test_context.instance_eval invocation_str
|
14
|
+
end
|
15
|
+
|
16
|
+
sut_rv
|
17
|
+
end
|
18
|
+
def invoke_concordion(cpr, sut_rv)
|
19
|
+
commands[cpr.concordion_command].call(sut_rv, cpr.content)
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def commands
|
24
|
+
cmds = {}
|
25
|
+
cmds["assertequals"] = Proc.new { |a, b| { :result => a == b, :actual => a, :expected => b } }
|
26
|
+
cmds["execute"] = Proc.new { |a,b| {:result => true, :actual => a, :expected => b } }
|
27
|
+
cmds["verifyrows"] = Proc.new { |a,b| { :result => true, :actual => a, :expected => b } }
|
28
|
+
cmds["asserttrue"] = Proc.new { |a, b| { :result => a, :actual => a, :expected => true } }
|
29
|
+
cmds
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
class ConcordionLookaheadHandler
|
3
|
+
|
4
|
+
|
5
|
+
def is_element_setter?(elem)
|
6
|
+
!elem.get_attribute('concordion:set').nil?
|
7
|
+
end
|
8
|
+
|
9
|
+
def handle_lookahead(cpr, test_context, processor)
|
10
|
+
cpr.tag.search("/*[@]").each {|child|
|
11
|
+
if is_element_setter?(child)
|
12
|
+
processor.process(child, test_context)
|
13
|
+
end
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class ConcordionParseResult
|
2
|
+
include ConcordionUtility
|
3
|
+
attr_accessor :concordion_command, :system_under_test, :content, :tag
|
4
|
+
def initialize(cmd, sut, content, tag)
|
5
|
+
@concordion_command = cmd
|
6
|
+
@system_under_test = sut
|
7
|
+
@content = content
|
8
|
+
@tag = tag
|
9
|
+
end
|
10
|
+
def to_s
|
11
|
+
"CPR: #{@concordion_command}, #{@system_under_test}, #{@content}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def is_set_command?
|
15
|
+
"set" == @concordion_command
|
16
|
+
end
|
17
|
+
def is_verify_command?
|
18
|
+
"verifyrows" == @concordion_command
|
19
|
+
end
|
20
|
+
def is_execute_command?
|
21
|
+
"execute" == @concordion_command
|
22
|
+
end
|
23
|
+
|
24
|
+
def assignment
|
25
|
+
concordion_assignment(@system_under_test)
|
26
|
+
end
|
27
|
+
|
28
|
+
def needs_dereference?
|
29
|
+
@system_under_test =~ /^#/ && @system_under_test.index("=").nil?
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require 'hpricot'
|
4
|
+
require 'concordion_instrumenter'
|
5
|
+
|
6
|
+
class ConcordionParser
|
7
|
+
@@ALL_ATTRIBUTED_ELEMENTS = "/html/body//*[@*]"
|
8
|
+
|
9
|
+
include ConcordionUtility
|
10
|
+
|
11
|
+
attr_accessor :root, :body, :html
|
12
|
+
|
13
|
+
def initialize(reader, concordion)
|
14
|
+
@reader = reader
|
15
|
+
@concordion = concordion
|
16
|
+
@verifier = concordion.verifier
|
17
|
+
@instrumenter = ConcordionInstrumenter.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse(filename)
|
21
|
+
@root = Hpricot.parse(@reader.read(filename))
|
22
|
+
@body = @root.at("body")
|
23
|
+
@html = @root.at("html")
|
24
|
+
end
|
25
|
+
def each_concordion_element(&block)
|
26
|
+
@root.search(@@ALL_ATTRIBUTED_ELEMENTS).each {|elem|
|
27
|
+
yield elem
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
def each_eligible_concordion_element(&block)
|
34
|
+
each_concordion_element do |elem|
|
35
|
+
if concordion_cmd_attr_exists?(elem)
|
36
|
+
attr = concordion_cmd_attr_for(elem)
|
37
|
+
@verifier.update_row(elem)
|
38
|
+
if !@instrumenter.instrument_from_headers(elem, attr, @root)
|
39
|
+
yield elem
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'concordion_utility'
|
2
|
+
|
3
|
+
class ConcordionProcessor
|
4
|
+
include ConcordionUtility
|
5
|
+
|
6
|
+
def initialize(concordion, decorator)
|
7
|
+
@concordion = concordion
|
8
|
+
@decorator = decorator
|
9
|
+
end
|
10
|
+
|
11
|
+
def process(tag, test_context)
|
12
|
+
attr = concordion_cmd_attr_for(tag)
|
13
|
+
instrumented_value = tag.get_attribute(attr)
|
14
|
+
rv = @concordion.evaluate(create_parse_result(tag, attr, instrumented_value), test_context, self)
|
15
|
+
@decorator.decorate_tag(rv, tag)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_parse_result(tag, attr, value)
|
19
|
+
ConcordionParseResult.new(instrumentation(attr), value, tag.inner_text, tag)
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
class ConcordionReader
|
3
|
+
def read(filename)
|
4
|
+
IO.read(find_on_load_path(filename))
|
5
|
+
end
|
6
|
+
|
7
|
+
def find_on_load_path(filename)
|
8
|
+
return filename if File.exists?(filename)
|
9
|
+
|
10
|
+
$LOAD_PATH.each {|path|
|
11
|
+
candidate = "#{path}/#{filename}"
|
12
|
+
return candidate if File.exists?(candidate)
|
13
|
+
}
|
14
|
+
|
15
|
+
raise "Could not find #{filename} on the system load path!"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
module SnakeCaseUtility
|
3
|
+
|
4
|
+
def snake_case(str)
|
5
|
+
s = str.gsub( /([A-Z])/, '_\1')
|
6
|
+
if s.index("_") == 0
|
7
|
+
s = s.slice(1, s.length)
|
8
|
+
end
|
9
|
+
|
10
|
+
s.downcase
|
11
|
+
end
|
12
|
+
|
13
|
+
def snake_cased_test_name(str)
|
14
|
+
s = snake_case(str)
|
15
|
+
s = s.gsub(/_test$/, '')
|
16
|
+
"#{s}.html"
|
17
|
+
end
|
18
|
+
|
19
|
+
def snake_cased_goldmaster_name(str)
|
20
|
+
snake_cased_test_name(str).gsub(".html", "_goldmaster.html")
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
module PluralToSingularUtility
|
26
|
+
|
27
|
+
def singular(str)
|
28
|
+
str.sub(/s$/, "")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module ConcordionStringUtility
|
33
|
+
include SnakeCaseUtility
|
34
|
+
include PluralToSingularUtility
|
35
|
+
|
36
|
+
def has_arguments?(name)
|
37
|
+
name !~ /\(\)$/
|
38
|
+
end
|
39
|
+
|
40
|
+
def concordion_assignment(name)
|
41
|
+
name.split("=")[0].strip
|
42
|
+
end
|
43
|
+
|
44
|
+
def has_assignment?(name)
|
45
|
+
name =~ /=/
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def concordion_method_name(name)
|
50
|
+
if name =~ /\(/
|
51
|
+
base = name.split("(")[0].strip
|
52
|
+
else
|
53
|
+
base = name.strip
|
54
|
+
end
|
55
|
+
|
56
|
+
if !has_assignment?(base)
|
57
|
+
return base
|
58
|
+
end
|
59
|
+
|
60
|
+
base.split("=")[1].strip
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'concordion_utility'
|
2
|
+
require 'concordion_reader'
|
3
|
+
require 'concordion_parser'
|
4
|
+
require 'concordion_processor'
|
5
|
+
require 'concordion_parse_result'
|
6
|
+
require 'concordion_test_case'
|
7
|
+
require 'concordion_writer'
|
8
|
+
require 'concordion_environment'
|
9
|
+
require 'concordion'
|
10
|
+
require 'concordion_css_decorator'
|
11
|
+
require 'test/unit'
|
12
|
+
|
13
|
+
class ConcordionTestCase < Test::Unit::TestCase
|
14
|
+
|
15
|
+
@@EXPECTED_FAILURE_COUNT = 0
|
16
|
+
|
17
|
+
include ConcordionUtility
|
18
|
+
|
19
|
+
def self.inherited(subclass)
|
20
|
+
subclass.class_eval do
|
21
|
+
define_method :test_spec do
|
22
|
+
filename = snake_cased_test_name(subclass.to_s)
|
23
|
+
parse_spec(filename)
|
24
|
+
run_spec(filename)
|
25
|
+
report_spec(filename)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
subclass
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.default_config
|
32
|
+
concordion = Concordion.new
|
33
|
+
parser = ConcordionParser.new(ConcordionReader.new, concordion)
|
34
|
+
decorator = ConcordionCSSDecorator.new
|
35
|
+
processor = ConcordionProcessor.new(concordion, decorator)
|
36
|
+
{ :expected_failure_count => @@EXPECTED_FAILURE_COUNT,
|
37
|
+
:parser => parser,
|
38
|
+
:writer => ConcordionWriter.new(ConcordionEnvironment.output_dir),
|
39
|
+
:concordion => concordion,
|
40
|
+
:decorator => decorator,
|
41
|
+
:processor => processor,
|
42
|
+
:write_goldmaster => false,
|
43
|
+
:css_type => ConcordionEnvironment.css_type
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize(arg, conf = ConcordionTestCase.default_config)
|
48
|
+
super(arg)
|
49
|
+
config = ConcordionTestCase.default_config.merge(conf)
|
50
|
+
@parser = config[:parser]
|
51
|
+
@writer = config[:writer]
|
52
|
+
@concordion = config[:concordion]
|
53
|
+
@decorator = config[:decorator]
|
54
|
+
@expected_failure_count = config[:expected_failure_count]
|
55
|
+
@processor = config[:processor]
|
56
|
+
@css_type = config[:css_type]
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_something_trivial_to_shut_runit_up
|
60
|
+
assert true
|
61
|
+
trivial
|
62
|
+
end
|
63
|
+
|
64
|
+
def trivial
|
65
|
+
@trivial = true
|
66
|
+
end
|
67
|
+
def is_trivial?
|
68
|
+
@trivial
|
69
|
+
end
|
70
|
+
|
71
|
+
def parse_spec(filename)
|
72
|
+
@parser.parse(filename)
|
73
|
+
assert_concordion_document
|
74
|
+
@decorator.add_concordion_css_link(@parser.root, @parser.html, @css_type)
|
75
|
+
end
|
76
|
+
|
77
|
+
def run_spec(filename)
|
78
|
+
@failures = 0
|
79
|
+
@parser.each_eligible_concordion_element do |elem|
|
80
|
+
@failures += @processor.process(elem, self)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def report_spec(filename)
|
85
|
+
@decorator.add_css_file_to_output_dir(@writer, @css_type)
|
86
|
+
outfilename = @writer.calculate_filename_and_overwrite(@parser.root, filename)
|
87
|
+
assert_no_failures(@failures, outfilename)
|
88
|
+
end
|
89
|
+
|
90
|
+
def assert_no_failures(failures, outfilename)
|
91
|
+
assert_equal @expected_failure_count, failures, "Wrote output to #{outfilename}"
|
92
|
+
end
|
93
|
+
|
94
|
+
def assert_concordion_document
|
95
|
+
assert_equal "http://www.concordion.org/2007/concordion", @parser.html.get_attribute("xmlns:concordion")
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
|
2
|
+
require 'concordion_constants'
|
3
|
+
require 'concordion_string_utility'
|
4
|
+
|
5
|
+
module ConcordionConvenience
|
6
|
+
def methods_for(clazz)
|
7
|
+
(clazz.methods - Object.methods).sort
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module ConcordionUtility
|
12
|
+
include ConcordionConstants
|
13
|
+
include ConcordionStringUtility
|
14
|
+
include ConcordionConvenience
|
15
|
+
|
16
|
+
|
17
|
+
def instrumentation(attr)
|
18
|
+
attr.split(":")[1]
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def supported_and_instrumented?(key)
|
23
|
+
supported?(key) and instrumented?(key)
|
24
|
+
end
|
25
|
+
|
26
|
+
def concordion_arguments(name)
|
27
|
+
return [] unless has_arguments?(name)
|
28
|
+
name_no_end_paren = name.gsub(")", '')
|
29
|
+
arg_string = name_no_end_paren.split("(")[1]
|
30
|
+
|
31
|
+
arg_string.split(",").collect { |arg| arg.strip }
|
32
|
+
end
|
33
|
+
def concordion_variable_name(conc_call)
|
34
|
+
if has_property_reference?(conc_call)
|
35
|
+
return conc_call.split(".")[0].strip
|
36
|
+
end
|
37
|
+
|
38
|
+
conc_call.strip
|
39
|
+
end
|
40
|
+
|
41
|
+
def has_property_reference?(conc_call)
|
42
|
+
conc_call =~ /\./
|
43
|
+
end
|
44
|
+
|
45
|
+
def concordion_property_reference(conc_call)
|
46
|
+
if !has_property_reference?(conc_call)
|
47
|
+
return conc_call
|
48
|
+
end
|
49
|
+
idx = conc_call.index(".")
|
50
|
+
conc_call.slice(idx + 1, conc_call.length - idx).strip
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
def concordion_cmd_attr_exists?(elem)
|
56
|
+
!concordion_cmd_attr_for(elem).nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
def concordion_cmd_attr_for(elem)
|
60
|
+
concordion_command_attributes.each {|attr|
|
61
|
+
instrumented_value = elem.get_attribute(attr)
|
62
|
+
if !instrumented_value.nil?
|
63
|
+
return attr
|
64
|
+
end
|
65
|
+
}
|
66
|
+
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'concordion_utility'
|
2
|
+
|
3
|
+
class ConcordionVerifier
|
4
|
+
include ConcordionUtility
|
5
|
+
|
6
|
+
@@ROW_REGEXP = /tr:nth\((\d+)\)/
|
7
|
+
attr_accessor :verification_variable
|
8
|
+
def initialize(concordion)
|
9
|
+
@concordion = concordion
|
10
|
+
@verification_variable = nil
|
11
|
+
@last_row = -1
|
12
|
+
end
|
13
|
+
|
14
|
+
def update_if_verify_command(cpr)
|
15
|
+
if cpr.is_verify_command?
|
16
|
+
@verification_variable = cpr.assignment
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def update_verifier(idx)
|
21
|
+
return if verification_variable.nil?
|
22
|
+
arr = @concordion.get_variable(verification_variable)
|
23
|
+
index = idx < 1 ? 0 : idx - 1
|
24
|
+
|
25
|
+
value = arr[index]
|
26
|
+
@concordion.set_variable(singular(verification_variable), value)
|
27
|
+
end
|
28
|
+
|
29
|
+
def verification_variable=(value)
|
30
|
+
@verification_variable = value
|
31
|
+
|
32
|
+
unless @verification_variable.nil?
|
33
|
+
update_verifier(0)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
def update_row(elem)
|
37
|
+
on_row = @@ROW_REGEXP.match(elem.css_path)
|
38
|
+
if on_row
|
39
|
+
current_row = on_row.captures[0]
|
40
|
+
if current_row != @last_row
|
41
|
+
update_verifier(current_row.to_i)
|
42
|
+
@last_row = current_row
|
43
|
+
end
|
44
|
+
else
|
45
|
+
@last_row = -1
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|