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.
Files changed (77) hide show
  1. data/Rakefile.rb +39 -0
  2. data/lib/concordion.rb +66 -0
  3. data/lib/concordion_binder.rb +24 -0
  4. data/lib/concordion_constants.rb +13 -0
  5. data/lib/concordion_css.rb +172 -0
  6. data/lib/concordion_css_decorator.rb +52 -0
  7. data/lib/concordion_environment.rb +28 -0
  8. data/lib/concordion_instrumenter.rb +30 -0
  9. data/lib/concordion_invocation_string_builder.rb +24 -0
  10. data/lib/concordion_invoker.rb +33 -0
  11. data/lib/concordion_lookahead_handler.rb +17 -0
  12. data/lib/concordion_parse_result.rb +31 -0
  13. data/lib/concordion_parser.rb +47 -0
  14. data/lib/concordion_processor.rb +24 -0
  15. data/lib/concordion_reader.rb +18 -0
  16. data/lib/concordion_string_utility.rb +63 -0
  17. data/lib/concordion_string_writer.rb +13 -0
  18. data/lib/concordion_test_case.rb +97 -0
  19. data/lib/concordion_utility.rb +70 -0
  20. data/lib/concordion_verifier.rb +50 -0
  21. data/lib/concordion_writer.rb +43 -0
  22. data/lib/goldmaster_test_case.rb +32 -0
  23. data/lib/rcor.rb +2 -0
  24. data/nbproject/private/config.properties +0 -0
  25. data/nbproject/private/private.properties +4 -0
  26. data/nbproject/private/private.xml +10 -0
  27. data/nbproject/project.properties +11 -0
  28. data/nbproject/project.xml +16 -0
  29. data/test-lib/single_row_result.rb +9 -0
  30. data/test-lib/user.rb +8 -0
  31. data/tests/attr_assert.html +5 -0
  32. data/tests/attr_assert_test.rb +13 -0
  33. data/tests/basic_assert.html +5 -0
  34. data/tests/basic_assert_test.rb +9 -0
  35. data/tests/basic_assert_true.html +6 -0
  36. data/tests/basic_assert_true_test.rb +11 -0
  37. data/tests/basic_set.html +8 -0
  38. data/tests/basic_set_test.rb +8 -0
  39. data/tests/basic_text.html +6 -0
  40. data/tests/basic_text_test.rb +12 -0
  41. data/tests/concordion.css +2 -0
  42. data/tests/concordion_css_decorator_test.rb +28 -0
  43. data/tests/concordion_environment_test.rb +44 -0
  44. data/tests/concordion_parse_result_test.rb +33 -0
  45. data/tests/concordion_test.rb +49 -0
  46. data/tests/concordion_utility_test.rb +88 -0
  47. data/tests/concordion_verifier_test.rb +38 -0
  48. data/tests/concordion_writer_test.rb +26 -0
  49. data/tests/failing.html +5 -0
  50. data/tests/failing_test.rb +15 -0
  51. data/tests/goldmaster_failing.html +5 -0
  52. data/tests/goldmaster_failing_goldmaster.html +162 -0
  53. data/tests/goldmaster_failing_test.rb +11 -0
  54. data/tests/goldmaster_passing.html +5 -0
  55. data/tests/goldmaster_passing_goldmaster.html +162 -0
  56. data/tests/goldmaster_passing_test.rb +9 -0
  57. data/tests/goldmaster_table.html +46 -0
  58. data/tests/goldmaster_table_goldmaster.html +203 -0
  59. data/tests/goldmaster_table_test.rb +17 -0
  60. data/tests/lookahead_assert_true.html +25 -0
  61. data/tests/lookahead_assert_true_test.rb +17 -0
  62. data/tests/nested_element_lookahead.html +9 -0
  63. data/tests/nested_element_lookahead_test.rb +8 -0
  64. data/tests/processes_elements_in_sorted_order.html +12 -0
  65. data/tests/processes_elements_in_sorted_order_test.rb +13 -0
  66. data/tests/return_result.html +7 -0
  67. data/tests/return_result_test.rb +17 -0
  68. data/tests/single_row_table.html +13 -0
  69. data/tests/single_row_table_test.rb +9 -0
  70. data/tests/table.html +28 -0
  71. data/tests/table_test.rb +9 -0
  72. data/tests/test_helper.rb +9 -0
  73. data/tests/verify_rows.html +46 -0
  74. data/tests/verify_rows_scsr.html +27 -0
  75. data/tests/verify_rows_scsr_test.rb +15 -0
  76. data/tests/verify_rows_test.rb +16 -0
  77. metadata +142 -0
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+ require 'rake/testtask'
3
+ require 'rake/packagetask'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/clean'
6
+ require 'lib/concordion_environment'
7
+
8
+ CLEAN.include(ConcordionEnvironment.clean_list)
9
+
10
+ Rake::TestTask.new do |t|
11
+ t.libs << "test-lib"
12
+ t.libs << "tests"
13
+ t.test_files = FileList['tests/*_test.rb']
14
+ t.verbose = true
15
+ end
16
+
17
+ task :default => [:clean, :test]
18
+
19
+ PKG_FILES = FileList['**/*'].exclude(/_test_output\.html$/)
20
+ PKG_VERSION = '0.8.1'
21
+
22
+ spec = Gem::Specification.new do |s|
23
+ s.platform = Gem::Platform::RUBY
24
+ s.summary = "Ruby based concordion"
25
+ s.name = 'rcor'
26
+ s.version = PKG_VERSION
27
+ s.author = 'Ben Goodspeed'
28
+ s.email = 'b.goodspeed@gmail.com'
29
+ s.add_dependency('hpricot', '>= 0.6')
30
+ s.requirements << 'hpricot HTML parser'
31
+ s.require_path = 'lib'
32
+ s.autorequire = 'rake'
33
+ s.files = PKG_FILES
34
+ end
35
+
36
+ Rake::GemPackageTask.new(spec) { |pkg|
37
+ pkg.need_zip = true
38
+ pkg.need_tar = true
39
+ }
@@ -0,0 +1,66 @@
1
+ require 'concordion_utility'
2
+ require 'concordion_invocation_string_builder'
3
+ require 'concordion_lookahead_handler'
4
+ require 'concordion_verifier'
5
+ require 'concordion_invoker'
6
+ require 'concordion_binder'
7
+
8
+ class Concordion
9
+ include ConcordionUtility
10
+
11
+ @@TEXT_VAR = "#TEXT"
12
+ def self.TEXT_VAR
13
+ @@TEXT_VAR
14
+ end
15
+ attr_reader :verification_variable, :verifier, :invocation_builder
16
+
17
+ def initialize
18
+ @memory = {}
19
+ @invocation_builder = ConcordionInvocationStringBuilder.new(self)
20
+ @lookahead_handler = ConcordionLookaheadHandler.new
21
+ @verifier = ConcordionVerifier.new(self)
22
+ @invoker = ConcordionInvoker.new(self)
23
+ @binder = ConcordionBinder.new(self)
24
+ set_variable(@@TEXT_VAR, @@TEXT_VAR)
25
+ end
26
+ def set_variable(variable, value)
27
+ @memory[variable] = value
28
+ end
29
+
30
+ def get_variable(variable)
31
+ @memory[variable]
32
+ end
33
+
34
+ def build_invocation_string(conc_call, content)
35
+ @invocation_builder.build_invocation_string(conc_call,content)
36
+ end
37
+
38
+ def dereference(conc_call)
39
+ var_name = concordion_variable_name(conc_call)
40
+ var = get_variable(var_name)
41
+
42
+ if !has_property_reference?(conc_call)
43
+ return var
44
+ end
45
+
46
+ var.send(concordion_property_reference(conc_call))
47
+ end
48
+
49
+
50
+ def evaluate(cpr, test_context, processor)
51
+ @lookahead_handler.handle_lookahead(cpr, test_context, processor)
52
+
53
+ return { :result => true } if @binder.bind_if_set_command(cpr)
54
+
55
+ @verifier.update_if_verify_command(cpr)
56
+
57
+ sut_rv = @invoker.invoke_sut(cpr, test_context)
58
+ @binder.handle_assignment(cpr, sut_rv)
59
+ conc_rv = @invoker.invoke_concordion(cpr, sut_rv)
60
+
61
+ conc_rv
62
+ end
63
+
64
+
65
+
66
+ end
@@ -0,0 +1,24 @@
1
+ require 'concordion_utility'
2
+
3
+ class ConcordionBinder
4
+ include ConcordionUtility
5
+
6
+ def initialize(concordion)
7
+ @concordion = concordion
8
+ end
9
+ def bind_if_set_command(cpr)
10
+ if cpr.is_set_command?
11
+ @concordion.set_variable(cpr.system_under_test, cpr.content)
12
+ true
13
+ else
14
+ false
15
+ end
16
+ end
17
+
18
+ def handle_assignment(cpr, sut_rv)
19
+ if has_assignment?(cpr.system_under_test)
20
+ @concordion.set_variable(concordion_assignment(cpr.system_under_test), sut_rv)
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,13 @@
1
+ module ConcordionConstants
2
+
3
+ def concordion_command_attributes
4
+ ["assertequals", "set", "execute", "verifyrows", "asserttrue"].collect do
5
+ |cmd| "concordion:#{cmd}"
6
+ end
7
+ end
8
+
9
+ def supported?(tagname)
10
+ ['p', 'span', 'b', 'th', 'tr', 'div'].include?(tagname.downcase)
11
+ end
12
+
13
+ end
@@ -0,0 +1,172 @@
1
+
2
+
3
+ module ConcordionCSS
4
+ def self.css_filename
5
+ "concordion.css"
6
+ end
7
+
8
+ def self.css_string
9
+ css = <<-eoscss
10
+ * {
11
+ font-family: Arial;
12
+ }
13
+ body {
14
+ padding: 32px;
15
+ }
16
+ pre {
17
+ padding: 6px 28px 6px 28px;
18
+ background-color: #E8EEF7;
19
+ }
20
+ pre, pre *, code, kbd {
21
+ font-family: Courier New, Courier;
22
+ font-size: 10pt;
23
+ }
24
+ h1, h1 * {
25
+ font-size: 24pt;
26
+ }
27
+ p, td, th, li, .breadcrumbs {
28
+ font-size: 10pt;
29
+ }
30
+ p, li {
31
+ line-height: 140%;
32
+ }
33
+ table {
34
+ border-collapse: collapse;
35
+ empty-cells: show;
36
+ margin: 8px 0px 8px 0px;
37
+ }
38
+ th, td {
39
+ border: 1px solid black;
40
+ padding: 3px;
41
+ }
42
+ td {
43
+ background-color: white;
44
+ vertical-align: top;
45
+ }
46
+ th {
47
+ background-color: #C3D9FF;
48
+ }
49
+ li {
50
+ margin-top: 6px;
51
+ margin-bottom: 6px;
52
+ }
53
+
54
+
55
+ .example {
56
+ padding: 2px 12px 6px 12px;
57
+ border: 1px solid #C3D9FF;
58
+ margin: 6px 0px 28px 0px;
59
+ background-color: #F5F9FD;
60
+ }
61
+ .example h3 {
62
+ margin-top: 8px;
63
+ margin-bottom: 8px;
64
+ font-size: 12pt;
65
+ }
66
+
67
+ p.success {
68
+ padding: 2px;
69
+ }
70
+ .concordion_success, .concordion_success * {
71
+ background-color: #afa !important;
72
+ }
73
+ .success pre {
74
+ background-color: #bbffbb;
75
+ }
76
+ .concordion_failure, .concordion_failure * {
77
+ background-color: #ffb0b0;
78
+ padding: 1px;
79
+ }
80
+ .concordion_failure .expected {
81
+ text-decoration: line-through;
82
+ color: #bb5050;
83
+ }
84
+
85
+ ins {
86
+ text-decoration: none;
87
+ }
88
+
89
+ .exceptionMessage {
90
+ background-color: #fdd;
91
+ font-family: Courier New, Courier, Monospace;
92
+ font-size: 10pt;
93
+ display: block;
94
+ font-weight: normal;
95
+ padding: 4px;
96
+ text-decoration: none !important;
97
+ }
98
+ .stackTrace, .stackTrace * {
99
+ font-weight: normal;
100
+ }
101
+ .stackTrace {
102
+ display: none;
103
+ padding: 1px 4px 4px 4px;
104
+ background-color: #fdd;
105
+ border-top: 1px dotted black;
106
+ }
107
+ .stackTraceExceptionMessage {
108
+ display: block;
109
+ font-family: Courier New, Courier, Monospace;
110
+ font-size: 8pt;
111
+ white-space: wrap;
112
+ padding: 1px 0px 1px 0px;
113
+ }
114
+ .stackTraceEntry {
115
+ white-space: nowrap;
116
+ font-family: Courier New, Courier, Monospace;
117
+ display: block;
118
+ font-size: 8pt;
119
+ padding: 1px 0px 1px 32px;
120
+ }
121
+ .stackTraceButton {
122
+ font-size: 8pt;
123
+ margin: 2px 8px 2px 0px;
124
+ font-weight: normal;
125
+ font-family: Arial;
126
+ }
127
+
128
+ .special {
129
+ font-style: italic;
130
+ }
131
+ .missing, .missing * {
132
+ background-color: #ff9999;
133
+ }
134
+ .surplus, .surplus * {
135
+ background-color: #ff9999;
136
+ }
137
+ .footer {
138
+ text-align: right;
139
+ margin-top: 40px;
140
+ font-size: 8pt;
141
+ width: 100%;
142
+ color: #999;
143
+ }
144
+ .footer .testTime {
145
+ padding: 2px 10px 0px 0px;
146
+ }
147
+
148
+ .idea {
149
+ font-size: 9pt;
150
+ color: #888;
151
+ font-style: italic;
152
+ }
153
+ .tight li {
154
+ margin-top: 1px;
155
+ margin-bottom: 1px;
156
+ }
157
+ .commentary {
158
+ float: right;
159
+ width: 200px;
160
+ background-color: #ffffd0;
161
+ padding:8px;
162
+ border: 3px solid #eeeeb0;
163
+ margin: 10px 0px 10px 10px;
164
+ }
165
+ .commentary, .commentary * {
166
+ font-size: 8pt;
167
+ }
168
+ eoscss
169
+
170
+ css.strip
171
+ end
172
+ end
@@ -0,0 +1,52 @@
1
+ require 'concordion_css'
2
+
3
+ class ConcordionCSSDecorator
4
+ def add_concordion_css_link(root, html, type)
5
+ if html.at("head").nil?
6
+ root.search("html").prepend('<head></head>')
7
+ end
8
+ #TODO add an environment variable for this?
9
+ if type == :link
10
+ link_to_css(html)
11
+ else
12
+ inline_css(html)
13
+ end
14
+ end
15
+
16
+ def append_to_head(html, s)
17
+ html.search("head").append(s)
18
+ end
19
+ def link_to_css(html)
20
+ append_to_head(html, "<link rel='stylesheet' type='text/css' href='#{css_filename}' />")
21
+ end
22
+
23
+
24
+ def inline_css(html)
25
+ append_to_head(html, "<style type='text/css'>#{css}</style>")
26
+ end
27
+
28
+ def css
29
+ ConcordionCSS.css_string
30
+ end
31
+
32
+ def css_filename
33
+ ConcordionCSS.css_filename
34
+ end
35
+
36
+ def add_css_file_to_output_dir(writer, type)
37
+ if !writer.output_file_exists?(css_filename) && type == :link
38
+ writer.calculate_filename_and_overwrite(css, css_filename)
39
+ end
40
+ end
41
+
42
+ def decorate_tag(rv, tag)
43
+ if rv[:result]
44
+ tag[:class] = 'concordion_success'
45
+ return 0
46
+ end
47
+
48
+ tag[:class] = 'concordion_failure'
49
+ tag.inner_html += " expected but received #{rv[:actual]}"
50
+ 1
51
+ end
52
+ end
@@ -0,0 +1,28 @@
1
+
2
+ class ConcordionEnvironment
3
+ def self.output_dir_key
4
+ 'RCOR_OUTPUT_DIR'
5
+ end
6
+
7
+ def self.css_type_key
8
+ 'RCOR_CSS_TYPE'
9
+ end
10
+
11
+ def self.with_dir(str)
12
+ File.join(output_dir, str)
13
+ end
14
+ def self.clean_list
15
+ [with_dir("*_test_output.html"), with_dir("concordion.css")] #TODO is this safe to delete? what if the user overwrites this file?
16
+ end
17
+
18
+ #TODO dry this up
19
+ def self.css_type
20
+ type = ENV[css_type_key]
21
+ type.nil? ? :inline : type.to_sym
22
+ end
23
+
24
+ def self.output_dir
25
+ dir = ENV[output_dir_key]
26
+ dir.nil? ? "." : dir
27
+ end
28
+ end
@@ -0,0 +1,30 @@
1
+
2
+ class ConcordionInstrumenter
3
+ @@TH_CSS_QUERY_REGEXP = /tr:nth\(\d+\) > th:nth\((\d+)\)$/
4
+ @@TH_CSS_SINGLE_REGEXP = /tr:nth\(\d+\) > th$/
5
+
6
+ def instrument_from_headers(elem, attr, root)
7
+ header = @@TH_CSS_QUERY_REGEXP.match(elem.css_path)
8
+ if header
9
+ instrument_column(elem, attr, header.captures, @@TH_CSS_QUERY_REGEXP, root)
10
+ return true
11
+ end
12
+
13
+ single_header = @@TH_CSS_SINGLE_REGEXP.match(elem.css_path)
14
+ if single_header
15
+ instrument_column(elem, attr, 0, @@TH_CSS_SINGLE_REGEXP, root)
16
+ return true
17
+ end
18
+
19
+ false
20
+ end
21
+
22
+ def instrument_column(elem, attr, column_number, regex, root)
23
+ trimmed = elem.css_path.sub(regex, '')
24
+ td_css_query = trimmed + "tr > td:nth(#{column_number})"
25
+
26
+ value = elem.get_attribute(attr)
27
+ root.search(td_css_query).set(attr, value)
28
+ end
29
+
30
+ end
@@ -0,0 +1,24 @@
1
+ require 'concordion_utility'
2
+
3
+
4
+ class ConcordionInvocationStringBuilder
5
+ include ConcordionUtility
6
+ def initialize(concordion)
7
+ @concordion = concordion
8
+ end
9
+
10
+ def build_invocation_string(conc_call, content)
11
+ base = "self.send('#{concordion_method_name(conc_call)}'"
12
+ if has_arguments?(conc_call)
13
+ arg_vars = concordion_arguments(conc_call)
14
+ arg_values = arg_vars.collect {|var| "'#{@concordion.get_variable(var)}'" }
15
+
16
+ args = arg_values.join(", ")
17
+ base += ", " + args
18
+ end
19
+
20
+ rv = base + ")"
21
+
22
+ rv.gsub(Concordion.TEXT_VAR, content)
23
+ end
24
+ end