rcor 0.8.1
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/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
|