greenpepper-ruby 0.0.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 (120) hide show
  1. data/bin/greenpepperize +71 -0
  2. data/bin/greenpepperrails +33 -0
  3. data/bin/greenpepperruby +15 -0
  4. data/data/greenpepper.rake +37 -0
  5. data/data/helper.rb +32 -0
  6. data/data/tags +6 -0
  7. data/lib/greenpepper/argumentparser.rb +161 -0
  8. data/lib/greenpepper/common/loadpath.rb +7 -0
  9. data/lib/greenpepper/context/htmlcontext.rb +26 -0
  10. data/lib/greenpepper/converter.rb +347 -0
  11. data/lib/greenpepper/core.rb +152 -0
  12. data/lib/greenpepper/example/collectionexample.rb +305 -0
  13. data/lib/greenpepper/example/dowithexample.rb +192 -0
  14. data/lib/greenpepper/example/exampleheader.rb +41 -0
  15. data/lib/greenpepper/example/examplewithfixture.rb +73 -0
  16. data/lib/greenpepper/example/executionresults.rb +160 -0
  17. data/lib/greenpepper/example/fieldaccessor.rb +36 -0
  18. data/lib/greenpepper/example/freetextexample.rb +51 -0
  19. data/lib/greenpepper/example/importexample.rb +39 -0
  20. data/lib/greenpepper/example/nameresolver.rb +69 -0
  21. data/lib/greenpepper/example/ruleforexample.rb +117 -0
  22. data/lib/greenpepper/example/setupexample.rb +79 -0
  23. data/lib/greenpepper/example/silentexample.rb +14 -0
  24. data/lib/greenpepper/example/unknownexample.rb +17 -0
  25. data/lib/greenpepper/exception/greenpepperexception.rb +57 -0
  26. data/lib/greenpepper/executionunit.rb +39 -0
  27. data/lib/greenpepper/factory/collectionexamplefactory.rb +59 -0
  28. data/lib/greenpepper/factory/dowithexamplefactory.rb +71 -0
  29. data/lib/greenpepper/factory/examplefactory.rb +14 -0
  30. data/lib/greenpepper/factory/freetextexamplefactory.rb +29 -0
  31. data/lib/greenpepper/factory/htmlexamplefactory.rb +49 -0
  32. data/lib/greenpepper/factory/importexamplefactory.rb +27 -0
  33. data/lib/greenpepper/factory/ruleforexamplefactory.rb +46 -0
  34. data/lib/greenpepper/factory/setupexamplefactory.rb +31 -0
  35. data/lib/greenpepper/factory/silentexamplefactory.rb +21 -0
  36. data/lib/greenpepper/factory/unknownexamplefactory.rb +16 -0
  37. data/lib/greenpepper/freetext.rb +164 -0
  38. data/lib/greenpepper/grammar/array.treetop +51 -0
  39. data/lib/greenpepper/grammar/arrayparser.rb +14 -0
  40. data/lib/greenpepper/greenpepperconfig.rb +19 -0
  41. data/lib/greenpepper/greenpeppertask.rb +60 -0
  42. data/lib/greenpepper/logger.rb +45 -0
  43. data/lib/greenpepper/parser/freetextparser.rb +96 -0
  44. data/lib/greenpepper/parser/htmlparser.rb +70 -0
  45. data/lib/greenpepper/parser/scenario.rb +25 -0
  46. data/lib/greenpepper/parser/table.rb +37 -0
  47. data/lib/greenpepper/parser/wikiparser.rb +26 -0
  48. data/lib/greenpepper/pass/freetextpass.rb +24 -0
  49. data/lib/greenpepper/pass/greenpepperpass.rb +92 -0
  50. data/lib/greenpepper/pass/tablepass.rb +38 -0
  51. data/lib/greenpepper/railsargumentparser.rb +46 -0
  52. data/lib/greenpepper/redpeppertask.rb +89 -0
  53. data/lib/greenpepper/repository/atlassianrepository.rb +100 -0
  54. data/lib/greenpepper/writer/consolewriter.rb +21 -0
  55. data/lib/greenpepper/writer/freetextresult.rb +233 -0
  56. data/lib/greenpepper/writer/freetextwriter.rb +44 -0
  57. data/lib/greenpepper/writer/html.rb +14 -0
  58. data/lib/greenpepper/writer/htmldocwriter.rb +82 -0
  59. data/lib/greenpepper/writer/htmlresult.rb +192 -0
  60. data/lib/greenpepper/writer/htmlwriter.rb +112 -0
  61. data/lib/greenpepper/writer/output.rb +26 -0
  62. data/lib/greenpepper/writer/result.rb +35 -0
  63. data/lib/greenpepper/writer/xmlwriter.rb +32 -0
  64. data/test/coreseedstest.rb +39 -0
  65. data/test/greenpepper/argumentparsertest.rb +162 -0
  66. data/test/greenpepper/common/loadpathtest.rb +24 -0
  67. data/test/greenpepper/common/stattest.rb +186 -0
  68. data/test/greenpepper/convertertest.rb +371 -0
  69. data/test/greenpepper/coretest.rb +159 -0
  70. data/test/greenpepper/example/collectionexampletest.rb +484 -0
  71. data/test/greenpepper/example/dowithexampletest.rb +148 -0
  72. data/test/greenpepper/example/exampletest.rb +28 -0
  73. data/test/greenpepper/example/freetextexampletest.rb +151 -0
  74. data/test/greenpepper/example/importexampletest.rb +79 -0
  75. data/test/greenpepper/example/nameresolvertest.rb +56 -0
  76. data/test/greenpepper/example/ruleforexampletest.rb +225 -0
  77. data/test/greenpepper/example/setupexampletest.rb +140 -0
  78. data/test/greenpepper/example/silentexampletest.rb +17 -0
  79. data/test/greenpepper/example/unknownexampletest.rb +17 -0
  80. data/test/greenpepper/factory/collectionexamplefactorytest.rb +51 -0
  81. data/test/greenpepper/factory/dowithexamplefactorytest.rb +48 -0
  82. data/test/greenpepper/factory/examplefactorytest.rb +88 -0
  83. data/test/greenpepper/factory/freetextexamplefactorytest.rb +54 -0
  84. data/test/greenpepper/factory/importexamplefactorytest.rb +40 -0
  85. data/test/greenpepper/factory/ruleforexamplefactorytest.rb +55 -0
  86. data/test/greenpepper/factory/setupexamplefactorytest.rb +29 -0
  87. data/test/greenpepper/factory/silentexamplefactorytest.rb +38 -0
  88. data/test/greenpepper/freetexttest.rb +222 -0
  89. data/test/greenpepper/grammar/arrayparsertest.rb +45 -0
  90. data/test/greenpepper/loggertest.rb +26 -0
  91. data/test/greenpepper/parser/freetextparsertest.rb +124 -0
  92. data/test/greenpepper/parser/htmlparsertest.rb +77 -0
  93. data/test/greenpepper/parser/wikiparsertest.rb +21 -0
  94. data/test/greenpepper/pass/freetextpasstest.rb +54 -0
  95. data/test/greenpepper/pass/greenpepperpasstest.rb +47 -0
  96. data/test/greenpepper/pass/tablepasstest.rb +23 -0
  97. data/test/greenpepper/repository/atlassionrepositorytest.rb +85 -0
  98. data/test/greenpepper/writer/freetextwritertest.rb +301 -0
  99. data/test/greenpepper/writer/htmlcollectionwritertest.rb +145 -0
  100. data/test/greenpepper/writer/htmldowithwritertest.rb +87 -0
  101. data/test/greenpepper/writer/htmlruleforwritertest.rb +147 -0
  102. data/test/greenpepper/writer/htmlsetupwritertest.rb +107 -0
  103. data/test/greenpepper/writer/htmlstatresulttest.rb +118 -0
  104. data/test/greenpepper/writer/htmlwriterpositiontest.rb +53 -0
  105. data/test/greenpepper/writer/writertest.rb +33 -0
  106. data/test/greenpepper/writer/xmlwritertest.rb +34 -0
  107. data/test/integration/collectionexampleintegrationtest.rb +64 -0
  108. data/test/integration/errorhandlingintegrationtest.rb +68 -0
  109. data/test/integration/freetextexampleintegrationtest.rb +75 -0
  110. data/test/integration/greenpepperexecutableintegrationtest.rb +22 -0
  111. data/test/integration/importexampleintegrationtest.rb +41 -0
  112. data/test/integration/interpretationordertest.rb +48 -0
  113. data/test/integration/ruleforexampleintegrationtest.rb +102 -0
  114. data/test/integration/securityintegrationtest.rb +30 -0
  115. data/test/integration/setupexampleintegrationtest.rb +31 -0
  116. data/test/integration/silentexampleintegrationtest.rb +29 -0
  117. data/test/task/greenpeppertasktest.rb +96 -0
  118. data/test/task/redpeppertasktest.rb +120 -0
  119. data/vendor/accents.rb +85 -0
  120. metadata +234 -0
@@ -0,0 +1,24 @@
1
+ =begin
2
+ Author: Simon Mathieu (simon.math@gmail.com)
3
+ Pascal Ouellet (pas.ouellet@gmail.com)
4
+ Date: October 5, 2009
5
+ =end
6
+
7
+ module GreenPepper
8
+
9
+ require 'greenpepper/factory/freetextexamplefactory'
10
+ require 'greenpepper/parser/freetextparser'
11
+ require 'greenpepper/writer/freetextwriter'
12
+
13
+ require 'greenpepper/pass/greenpepperpass'
14
+
15
+ class FreeTextPass < GreenPepperPass
16
+ def initialize()
17
+ parser = FreeTextParser.new
18
+ factory = FreeTextExampleFactory.new
19
+ writer = FreeTextWriter.new
20
+ super(parser, factory, writer)
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,92 @@
1
+ =begin
2
+ Author: Pascal Ouellet (pas.ouellet@gmail.com)
3
+ Date: October 27, 2009
4
+ =end
5
+
6
+
7
+
8
+ module GreenPepper
9
+ class GreenPepperPass
10
+
11
+ @@passes = []
12
+ attr_accessor :writer
13
+ # TODO Malformed do with table test
14
+ def initialize(parser, factory, writer)
15
+ @parser = parser
16
+ @factory = factory
17
+ @writer = writer
18
+ # Force LibXML to keep the line number when parsing
19
+ LibXML::XML::default_line_numbers = true
20
+ end
21
+
22
+ def extract_data document, filename
23
+ # Extract the content of the document
24
+ execution_units = @parser.extract_content document, filename
25
+
26
+ # Build examples from the content
27
+ i = 0
28
+ new_execution_units = []
29
+ while i < execution_units.size
30
+ content = execution_units[i].content
31
+ context = execution_units[i].context
32
+
33
+ current_unit = i
34
+ @factory.push_content content
35
+ i += 1
36
+ while @factory.need_more_content?
37
+
38
+ if i >= execution_units.size
39
+ raise GreenPepperMalformedTableError.new(
40
+ "Can't parse document, one of the table is not formated correctly.")
41
+ end
42
+
43
+ content = @factory.push_content execution_units[i].content
44
+ context.nb_table +=1
45
+ i += 1
46
+ end
47
+ example = @factory.build_example
48
+ execution_units[current_unit].example = example
49
+ new_execution_units << execution_units[current_unit]
50
+ end
51
+ new_execution_units
52
+ end
53
+
54
+ def write document, execution_units, writer_options
55
+ if execution_units.size > 0
56
+ document = @writer.write document, execution_units, writer_options
57
+ end
58
+ document
59
+ end
60
+
61
+ def self.interpret(document, filename = 'UNKNOWN', writer_options = {})
62
+ ex_units = []
63
+ @@passes.each{|pass| ex_units += pass.extract_data(document, filename)}
64
+
65
+ ex_units.sort!{|first, second|first.context.index <=> second.context.index}
66
+ # Execute examples
67
+ ex_units.each{ |ex_unit|
68
+ ex_unit.execute
69
+ }
70
+
71
+ # Don't write unless we have to
72
+ pass_it = 0
73
+ @@passes.each{|pass|
74
+ temp_units = []
75
+ ex_units.each{|unit|
76
+ if pass.writer.support? unit
77
+ temp_units << unit
78
+ end
79
+ }
80
+
81
+ document = pass.write(document, temp_units, writer_options)
82
+ }
83
+ [ex_units, document]
84
+ end
85
+
86
+ def self.passes=(passes)
87
+ @@passes = passes
88
+ end
89
+ end
90
+
91
+ end
92
+
@@ -0,0 +1,38 @@
1
+ =begin
2
+ Author: Simon Mathieu (simon.math@gmail.com)
3
+ Pascal Ouellet (pas.ouellet@gmail.com)
4
+ Date: October 5, 2009
5
+ =end
6
+ module GreenPepper
7
+
8
+ require 'greenpepper/parser/htmlparser'
9
+ require 'greenpepper/factory/examplefactory'
10
+ require 'greenpepper/writer/htmlwriter'
11
+ require 'greenpepper/factory/htmlexamplefactory'
12
+ require 'greenpepper/factory/ruleforexamplefactory'
13
+ require 'greenpepper/factory/importexamplefactory'
14
+ require 'greenpepper/factory/setupexamplefactory'
15
+ require 'greenpepper/factory/dowithexamplefactory'
16
+ require 'greenpepper/factory/collectionexamplefactory'
17
+ require 'greenpepper/factory/silentexamplefactory'
18
+
19
+ require 'greenpepper/pass/greenpepperpass'
20
+
21
+ class TablePass < GreenPepperPass
22
+ def initialize()
23
+ parser = HtmlParser.new
24
+ factory = HtmlExampleFactory.new([ImportExampleFactory.new,
25
+ RuleForExampleFactory.new,
26
+ SetupExampleFactory.new,
27
+ DoWithExampleFactory.new,
28
+ ListOfExampleFactory.new,
29
+ SetOfExampleFactory.new,
30
+ SubsetOfExampleFactory.new,
31
+ SupersetOfExampleFactory.new,
32
+ SilentExampleFactory.new
33
+ ])
34
+ writer = HtmlWriter.new
35
+ super(parser, factory, writer)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,46 @@
1
+ =begin
2
+ author : S�bastien Boisclair (sebastien.boisclair2@usherbrooke.ca)
3
+ date: November 26, 2009
4
+ =end
5
+ module RailsArgumentParser
6
+
7
+ def self.extract_args
8
+ args = {}
9
+
10
+ env = extract_single_arg("--env")
11
+ args[:env] = env
12
+
13
+ path = extract_single_arg("--rails")
14
+ args[:rails] = path
15
+ args
16
+ end
17
+
18
+ def self.extract_single_arg(argument)
19
+ ind = ARGV.index(argument)
20
+ result = nil
21
+ if ind != nil
22
+ if ind + 1 >= ARGV.length
23
+ puts "Wrong number of arguments.\n"
24
+ puts argument + " needs a linked argument."
25
+ ARGV.delete_at(ind)
26
+ else
27
+ result = ARGV[ind+1]
28
+ ARGV.delete_at(ind+1)
29
+ ARGV.delete_at(ind)
30
+ end
31
+ end
32
+ result
33
+ end
34
+
35
+ def self.usage
36
+ index = ARGV.index('--help')
37
+ if ARGV.length == 0 || index != nil
38
+ puts "Usage: ruby greenpepperrails input_document output_document [option]"
39
+ puts "--rails path to the rails application"
40
+ puts "--env name of the environment of rails application"
41
+ puts "all the options that can be used with greenpepper.rb can be used " +
42
+ "with greenpepperrails\n\n"
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'libxml'
5
+ require 'rake'
6
+ require 'rake/tasklib'
7
+ require 'net/http'
8
+ require 'cgi'
9
+ require 'greenpepper/greenpepperconfig'
10
+
11
+ module GreenPepper
12
+ class RedPepperTask < Rake::TaskLib
13
+ attr_accessor :server, :path, :spec_id, :spec_name
14
+
15
+ def initialize(name, http = Net::HTTP)
16
+ @name = name
17
+ @http_client = http
18
+ @path = 'greenpepper/specifications'
19
+
20
+ yield self if block_given?
21
+ load_config
22
+ define
23
+ end
24
+
25
+ private
26
+ # Create the tasks defined by this task lib.
27
+ def define
28
+ task @name do
29
+ if @spec_id.nil? && @spec_name.nil?
30
+ download_all_specs
31
+ else
32
+ if @spec_name
33
+ url = get_url_for_name @spec_name
34
+ name = @spec_name
35
+ elsif @spec_id
36
+ url = get_url_for_id @spec_id
37
+ name = @spec_id.to_s
38
+ end
39
+ page = get_page(url)
40
+ name = parse_for_name(page)
41
+
42
+ write_page page, name
43
+ end
44
+ end
45
+ end
46
+
47
+ def download_all_specs
48
+ all_ids_string = @http_client.get URI.parse("#{@server}/specifications/all")
49
+ all_ids_string.split("\n").each do |id|
50
+ url = get_url_for_id(id)
51
+ page = get_page(url)
52
+ name = parse_for_name page
53
+ write_page page, name
54
+ end
55
+ end
56
+
57
+ def get_url_for_id id
58
+ "#{@server}/specifications/spec/#{id}"
59
+ end
60
+
61
+ def get_url_for_name name
62
+ "#{@server}/specifications/spec/name/#{CGI::escape name}"
63
+ end
64
+
65
+ def get_page url
66
+ @http_client.get URI.parse(url)
67
+ end
68
+
69
+ def write_page(page, name)
70
+ filepath = File.join @path, name + '.html'
71
+ FileUtils.mkdir_p @path if !File.directory?(@path)
72
+ File.open(filepath, 'w') { |f| f.write page }
73
+ end
74
+
75
+ def parse_for_name page
76
+ page_parse = (LibXML::XML::HTMLParser.string page).parse
77
+ name = ""
78
+ page_parse.find("//title").each {|t| name = t.content}
79
+ name.strip
80
+ end
81
+
82
+
83
+ def load_config
84
+ config = GreenPepperConfig.instance
85
+ GreenPepperConfig.maybe_set self, "@server", config
86
+ GreenPepperConfig.maybe_set self, "@path", config
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,100 @@
1
+ =begin
2
+ author: Éloise Dubé (eloise.dube@gmail.com)
3
+ date: March 29, 2009
4
+ =end
5
+ module GreenPepper
6
+
7
+ require 'cgi'
8
+ require 'xmlrpc/client'
9
+ require 'greenpepper/exception/greenpepperexception'
10
+
11
+ class AtlassianRepository
12
+
13
+ def initialize(uri, server = nil)
14
+ uri = AtlassianURI.new(uri) if uri.is_a?(String)
15
+ @uri = uri
16
+ server = Confluence::Server.new(@uri.url, @uri.handler) unless server
17
+ @repo = server
18
+ end
19
+
20
+ def load_document(filename)
21
+ filename = CGI::unescape(filename)
22
+
23
+ parse_input_filename filename
24
+ return @repo.getRenderedSpecification(@uri.username, @uri.password,
25
+ [@uri.space, @input_filename, false, true])
26
+ end
27
+
28
+ def parse_input_filename(filename)
29
+ # format of filename : FILENAME?ATTRIBUTES
30
+ @file_attributes = Hash.new
31
+
32
+ filename_parts = filename.split "?"
33
+ @input_filename = filename_parts[0]
34
+ if filename_parts.size > 1
35
+ attribute_parts = filename_parts[1].split "="
36
+ @file_attributes[attribute_parts[0]] = attribute_parts[1]
37
+ end
38
+ end
39
+ end
40
+
41
+ class AtlassianURI
42
+ attr_reader :uri, :url, :handler, :space, :username, :password
43
+ def initialize(uri)
44
+ @uri = uri
45
+ uri_parts = @uri.split ";"
46
+ if uri_parts.size < 2
47
+ raise GreenPepperRepositoryError.new("Bad format of URI. " + uri)
48
+ end
49
+
50
+ success = /(.*)\?handler=(.*)&(.*)#(.*)/ === uri_parts[1]
51
+ if success == false
52
+ raise GreenPepperRepositoryError.new(
53
+ "Can't parse confluence URL")
54
+ end
55
+ @url = $1
56
+ @handler = $2
57
+ @space = $4
58
+ attribute_parts = $3.split "="
59
+
60
+ @username = ""
61
+ @password = ""
62
+
63
+ if uri_parts.size > 2
64
+ @username = uri_parts[2]
65
+ @password = uri_parts[3]
66
+ end
67
+ end
68
+ end
69
+
70
+ # A useful helper for running Confluence XML-RPC from Ruby.
71
+ # Also takes care of re-logging in if your login times out.
72
+ #
73
+ # Source code :
74
+ # http://confluence.atlassian.com/display/CONFEXT/Confluence4r
75
+ module Confluence
76
+ class ServerFactory
77
+ def create_server(server_url)
78
+ XMLRPC::Client.new2 server_url
79
+ end
80
+ end
81
+ class Server
82
+ def initialize(server_url, handler, factory = ServerFactory.new)
83
+ unless server_url[-11..-1] == "/rpc/xmlrpc"
84
+ server_url += "/rpc/xmlrpc"
85
+ end
86
+ server = factory.create_server server_url
87
+ @conf = server.proxy handler
88
+ end
89
+
90
+ def method_missing(method_name, *args)
91
+ begin
92
+ @conf.send(method_name, *(args))
93
+ rescue XMLRPC::FaultException => e
94
+ raise e.faultString
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ end #module GreenPepper
@@ -0,0 +1,21 @@
1
+ =begin
2
+ author: Martin Provencher (martin.provencher@usherbrooke.ca)
3
+ date: March 18, 2009
4
+ =end
5
+ module GreenPepper
6
+
7
+ require 'greenpepper/example/ruleforexample'
8
+
9
+ class ConsoleWriter
10
+ def initialize results
11
+ @results = results
12
+ end
13
+
14
+ def output
15
+ results = HtmlTableExecutionResults.get_all_results(@results)
16
+ total = results.successes + results.failures + results.ignored + results.errors
17
+ "#{total} tests: #{results.successes} right, #{results.failures}" +
18
+ " wrong, #{results.ignored} ignored, #{results.errors} exception(s)"
19
+ end
20
+ end
21
+ end #module GreenPepper
@@ -0,0 +1,233 @@
1
+ =begin
2
+ author: Simon Mathieu (simon.math@gmail.com)
3
+ date: October 3, 2009
4
+ =end
5
+ module GreenPepper
6
+
7
+ require 'greenpepper/writer/html'
8
+ require 'greenpepper/writer/result'
9
+ require 'greenpepper/converter'
10
+ require 'cgi'
11
+
12
+ module KeywordFormat
13
+ def indent(text)
14
+ "<div class=\"greenpepper-freetext-indent\">#{text}</div>"
15
+ end
16
+
17
+ def indent2(text)
18
+ "<div class=\"greenpepper-freetext-indent2\">#{text}</div>"
19
+ end
20
+
21
+ def newline(text)
22
+ "<div class=\"greenpepper-freetext\">#{text}</div>"
23
+ end
24
+
25
+ def highlight(color, text)
26
+ "<font style=\"background-color: #{color};\">#{text}</font>"
27
+ end
28
+
29
+ def yellow_highlight(text)
30
+ highlight(Html::YELLOW, text)
31
+ end
32
+
33
+ def green_highlight(text)
34
+ highlight(Html::GREEN, text)
35
+ end
36
+
37
+ def red_highlight(text)
38
+ highlight(Html::RED, text)
39
+ end
40
+
41
+ def grey_highlight(text)
42
+ highlight(Html::GREY, text)
43
+ end
44
+
45
+ def error(error)
46
+ res = indent yellow_highlight("#{error.class}: " +
47
+ "#{CGI::escapeHTML error.to_s}")
48
+ if error.backtrace
49
+ res += '<hr/>'
50
+ error.backtrace.each { |step|
51
+ res << indent2(yellow_highlight(CGI::escapeHTML(step)))
52
+ }
53
+ end
54
+ res
55
+ end
56
+ end
57
+
58
+ class GivenSuccess < ExampleResult
59
+ def write(action)
60
+ action
61
+ end
62
+
63
+ def success?
64
+ true
65
+ end
66
+ end
67
+
68
+ class WhenSuccess < ExampleResult
69
+ def write(action)
70
+ action
71
+ end
72
+
73
+ def success?
74
+ true
75
+ end
76
+ end
77
+
78
+ class ThenResults < ExampleResult
79
+ include KeywordFormat
80
+ attr_accessor :expectations
81
+
82
+ def initialize(regex, expectations)
83
+ @regex, @expectations = regex, expectations
84
+ end
85
+
86
+ def write(action)
87
+ expected_lines = []
88
+ match_data = @regex.match action
89
+ i = match_data.size - 1
90
+ while i > 0
91
+ start_index = match_data.offset(i)[0]
92
+ end_index = match_data.offset(i)[1]
93
+
94
+ # Type conversion of expected and received value
95
+ converter = TypeConverter.instance
96
+ expected = converter.format_object(match_data[i],
97
+ @expectations[i-1].expected)
98
+ received = converter.format_object(match_data[i],
99
+ @expectations[i-1].received)
100
+
101
+ # Highlight match
102
+ action = action[0...start_index] +
103
+ then_highlight(expected,
104
+ @expectations[i-1].check_result) +
105
+ action[end_index..-1]
106
+
107
+ # Write expected lines for failures
108
+ unless @expectations[i-1].check_result
109
+ expected_lines << indent(
110
+ red_highlight("Expected value was #{expected}, " +
111
+ "but #{received} was received"))
112
+ end
113
+ i -= 1
114
+ end
115
+
116
+ expected_lines.reverse.each do |line|
117
+ action += line
118
+ end
119
+
120
+ action
121
+ end
122
+
123
+ def then_highlight(string, result)
124
+ result ? green_highlight(string) : red_highlight(string)
125
+ end
126
+
127
+ def update_stats(results)
128
+ @expectations[0..-1].each do |exp|
129
+ exp.check_result ? results.add_success : results.add_failure
130
+ end
131
+ end
132
+ end
133
+
134
+ class AskSuccess < ExampleResult
135
+ include KeywordFormat
136
+ attr_accessor :answer
137
+
138
+ def initialize(answer)
139
+ @answer = answer
140
+ end
141
+
142
+ def write(action)
143
+ action + indent("Answer: " + grey_highlight(@answer))
144
+ end
145
+
146
+ def success?
147
+ true
148
+ end
149
+ end
150
+
151
+ class CheckSuccess < ExampleResult
152
+ include KeywordFormat
153
+
154
+ def write(action)
155
+ green_highlight action
156
+ end
157
+
158
+ def update_stats(results)
159
+ results.add_success
160
+ end
161
+
162
+ def success?
163
+ true
164
+ end
165
+ end
166
+
167
+ class HeaderSuccess < ExampleResult
168
+ def initialize(fixture_name)
169
+ @fixture_name = fixture_name
170
+ end
171
+
172
+ def write(action)
173
+ "Scenario: #{@fixture_name}"
174
+ end
175
+
176
+ def success?
177
+ true
178
+ end
179
+ end
180
+
181
+ class KeywordError < ExampleResult
182
+ include KeywordFormat
183
+ def update_stats(results)
184
+ results.add_error
185
+ end
186
+
187
+ def error?
188
+ true
189
+ end
190
+ end
191
+
192
+ class ActionError < KeywordError
193
+ attr_reader :exception
194
+
195
+ def initialize(exception)
196
+ @exception = exception
197
+ end
198
+
199
+ def write(action)
200
+ newline(yellow_highlight(action)) +
201
+ error(@exception)
202
+ end
203
+ end
204
+
205
+ class HeaderError < KeywordError
206
+ def initialize(fixture_name, error)
207
+ @fixture_name = fixture_name
208
+ @error = error
209
+ end
210
+
211
+ def write(action)
212
+ "Scenario: " + yellow_highlight(@fixture_name) +
213
+ indent(error(@error))
214
+ end
215
+ end
216
+
217
+ class CheckFailure < ExampleResult
218
+ include KeywordFormat
219
+
220
+ def write(action)
221
+ red_highlight action
222
+ end
223
+
224
+ def update_stats(results)
225
+ results.add_failure
226
+ end
227
+
228
+ def failure?
229
+ true
230
+ end
231
+ end
232
+
233
+ end