greenpepper-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,71 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Greenpepperize the folder by deploying rake tasks
4
+ require 'fileutils'
5
+
6
+ module GreenPepper
7
+ module Deploy
8
+ FOLDERS = ["greenpepper/specifications", "greenpepper/results",
9
+ "greenpepper/fixtures", "lib/tasks"]
10
+
11
+ def self.deploy
12
+ no_argument_error if ARGV.size != 1
13
+ deploy_path = File.expand_path ARGV[0]
14
+ inexistant_path_error if !File.exists? deploy_path
15
+ return if !confirm? deploy_path
16
+
17
+ gem_data_dir = File.join(File.dirname(__FILE__), '..', 'data')
18
+
19
+ # Create folders
20
+ FOLDERS.each{ |folder| FileUtils.mkdir_p File.join(deploy_path, folder)}
21
+
22
+ # Deploy files
23
+ FileUtils.cp File.join(gem_data_dir, 'greenpepper.rake'),
24
+ File.join(deploy_path, 'lib/tasks')
25
+ FileUtils.cp File.join(gem_data_dir, 'helper.rb'),
26
+ File.join(deploy_path, 'greenpepper')
27
+
28
+ print_info
29
+ end
30
+
31
+ private
32
+ def self.confirm? path
33
+ puts "Do you want to deploy GreenPepper to \"#{path}\"? [y/n]"
34
+ begin
35
+ answer = STDIN.gets.chomp
36
+ end while answer != "y" && answer != "n"
37
+ answer == "y" ? true : false
38
+ end
39
+
40
+ def self.no_argument_error
41
+ puts "Invalid argument specified."
42
+ print_usage
43
+ exit 1
44
+ end
45
+
46
+ def self.inexistant_path_error
47
+ puts "Inexistant path specified."
48
+ print_usage
49
+ exit 1
50
+ end
51
+
52
+ def self.print_usage
53
+ puts "usage: greenpepperize PATH"
54
+ end
55
+
56
+ def self.print_info
57
+ puts "The directory has been greenpeperized.\n\n" +
58
+ "The following rake tasks are now available: \n" +
59
+ " gp:all [name=\"spec\"] - Download and run one or all" +
60
+ " specifications\n" +
61
+ " gp:download [name=\"spec\"] - Download one or all specifications" +
62
+ " from RedPepper server\n" +
63
+ " gp:run [name=\"spec\"] - Execute one or all specifications" +
64
+ " from greenpepper/specification\n\n" +
65
+ "The greenpepper/helper.rb file can be used to configure the tasks.\n"
66
+ end
67
+ end
68
+ end
69
+
70
+ GreenPepper::Deploy.deploy
71
+ exit 0
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ =begin
3
+ author : S�bastien Boisclair (sebastien.boisclair2@usherbrooke.ca)
4
+ date: November 26, 2009
5
+ =end
6
+
7
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "../lib")
8
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "../bin")
9
+
10
+ require 'rubygems'
11
+ require 'greenpepper/railsargumentparser'
12
+ require 'greenpepper/freetext'
13
+ args = RailsArgumentParser.extract_args
14
+
15
+ if !args[:env]
16
+ RAILS_ENV = "test"
17
+ else
18
+ RAILS_ENV = args[:env]
19
+ end
20
+
21
+ if args[:rails]
22
+ require File.join(args[:rails], 'config/environment.rb')
23
+ requires = Dir.glob File.join(args[:rails], "greenpepper", "fixtures",
24
+ "*.rb")
25
+ requires.each { |req| require req }
26
+ end
27
+
28
+ index = ARGV.index('--help')
29
+ if ARGV.length == 0 || index != nil
30
+ RailsArgumentParser.usage
31
+ end
32
+
33
+ load 'greenpepperruby'
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ =begin
3
+ author : Martin Provencher (martin.provencher@usherbrooke.ca)
4
+ date: March 11, 2009
5
+ =end
6
+
7
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "../lib")
8
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "../../common")
9
+
10
+ require 'greenpepper/core.rb'
11
+
12
+ core = GreenPepper::GreenPepperCore.new
13
+ ret = core.run ARGV
14
+
15
+ exit(ret) if ret.is_a? Fixnum
@@ -0,0 +1,37 @@
1
+ # Tasks to download and execute GreenPepper specifications against the Rails
2
+ # application. Tasks configuration file is located in greenpepper/helper.rb
3
+ require 'greenpepper/greenpeppertask'
4
+ require 'greenpepper/redpeppertask'
5
+
6
+ # Load the configuration file
7
+ load 'greenpepper/helper.rb'
8
+
9
+ # Global GreenPepper namespace
10
+ namespace :gp do
11
+
12
+ # Download and run all specifications
13
+ task :all do
14
+ Rake::Task["gp:download"].execute
15
+ Rake::Task["gp:run"].execute
16
+ end
17
+
18
+ # Download all the specifications hosted by the RedPepper server defined
19
+ # in the config file
20
+ GreenPepper::RedPepperTask.new(:download) do |t|
21
+ # Get the spec name, if any
22
+ t.spec_name = ENV['name']
23
+ end
24
+
25
+ # Execute all specifications in greenpepper/specifications
26
+ GreenPepper::GreenPepperTask.new(:run) do |t|
27
+ # Require Rails environment
28
+ require "config/environment"
29
+
30
+ # Require fixtures in greenpepper/fixtures
31
+ requires = Dir.glob File.join("greenpepper", "fixtures", "*.rb")
32
+ requires.each { |req| require req }
33
+
34
+ # Get the spec name, if any
35
+ t.spec_name = ENV['name'] + '.html'
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ # GreenPepper rake tasks configuration file. Change this file to customize
2
+ # the behavior of the gp:all, gp:download and gp:run tasks.
3
+ require 'greenpepper/greenpepperconfig'
4
+
5
+ # Include the freetext DSL.
6
+ require 'greenpepper/freetext'
7
+
8
+ GreenPepper::GreenPepperConfig.configure do |config|
9
+
10
+ ### RedPepper ###
11
+ #################
12
+ # Defines the RedPepper server URL from which to fetch the specifications
13
+ config.server = "http://greenpepper.kicks-ass.org/server"
14
+
15
+ # The directory to save the downloaded specifications to.
16
+ # Default : "greenpepper/specifications"
17
+ #config.path = "path/specifications"
18
+
19
+ ### Specification ###
20
+ #####################
21
+ # The directory from which to execute the specifications
22
+ # Default : "greenpepper/specifications"
23
+ #config.spec_dir = "/my/spec/dir"
24
+
25
+ # The execution result directory.
26
+ # Defaut : "greenpepper/results"
27
+ #config.result_dir = "path/results"
28
+
29
+ # The path of the GreenPepper core. If not specified, it searches for it in
30
+ # the ruby loadpath.
31
+ #config.greenpepper_path = "/my/core/path"
32
+ end
@@ -0,0 +1,6 @@
1
+ !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
2
+ !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
3
+ !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
4
+ !_TAG_PROGRAM_NAME Exuberant Ctags //
5
+ !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
6
+ !_TAG_PROGRAM_VERSION 5.7 //
@@ -0,0 +1,161 @@
1
+ =begin
2
+ author: Martin Provencher (martin.provencher@usherbrooke.ca)
3
+ date: March 24, 2008
4
+ =end
5
+ module GreenPepper
6
+
7
+ class ArgumentParser
8
+
9
+ attr_reader :execution_context, :writer_context
10
+
11
+ def initialize(args)
12
+ @execution_context = {:html_results_output => true,
13
+ :xml_output => false,
14
+ :console_output => "",
15
+ :repository => nil,
16
+ :load_path => Array.new,
17
+ :input_document => nil,
18
+ :output_document => nil}
19
+
20
+ @writer_context = {:no_exception_stack => false}
21
+
22
+ if args.empty?
23
+ @execution_context[:console_output] = ArgumentParser.usage
24
+ else
25
+ @parsed = parse_args args
26
+ end
27
+ end
28
+
29
+ def parse_args(argv)
30
+ argv = [argv] unless argv.is_a? Array
31
+ args = argv.dup
32
+ arg_regex = /^\s*-.+\s*/
33
+ return false if args.size < 1
34
+
35
+ while arg = args.shift
36
+ if arg =~ arg_regex
37
+ case arg
38
+ when "--no-html-results" #Not in doc
39
+ @execution_context[:html_results_output] = false
40
+ when "--no-exception-stack"
41
+ @writer_context[:no_exception_stack] = true
42
+ when "--help"
43
+ @execution_context[:console_output] = ArgumentParser.usage
44
+ return
45
+ when "--version"
46
+ @execution_context[:console_output] =
47
+ "#{$APP_NAME} version : #{$VERSION}"
48
+ return
49
+ when "--xml"
50
+ @execution_context[:xml_output] = true
51
+ @execution_context[:output_document] = args.shift unless
52
+ args[0] =~ arg_regex || args.size == 0
53
+ #Output to the specified output. If no specified output,
54
+ #outputting to INPUTFILENAME_output.xml
55
+ when "-r"
56
+ if args[0] =~ arg_regex || args.size == 0
57
+ @execution_context[:console_output] = ArgumentParser.usage
58
+ return
59
+ else
60
+ @execution_context[:repository] = args.shift
61
+ end
62
+ when "--loadpath"
63
+ if args[0] =~ arg_regex || args.size == 0
64
+ @execution_context[:console_output] = ArgumentParser.usage
65
+ return
66
+ else
67
+ while !(args[0] =~ arg_regex || args.size == 0)
68
+ @execution_context[:load_path] << args.shift
69
+ end
70
+ end
71
+
72
+ else
73
+ @execution_context[:console_output] =
74
+ "#{arg.to_s} option is not recognize\n#{ArgumentParser.usage}"
75
+ return
76
+ end
77
+ else
78
+ if @execution_context[:input_document].nil?
79
+ @execution_context[:input_document] = arg
80
+ elsif @execution_context[:output_document].nil?
81
+ @execution_context[:output_document] = arg
82
+ end
83
+ end
84
+ end
85
+
86
+ if (@execution_context[:input_document].nil?)
87
+ @execution_context[:console_output] = ArgumentParser.usage
88
+ return
89
+ else
90
+ if(@execution_context[:output_document].nil?)
91
+ extension_name = File.extname @execution_context[:input_document]
92
+ base_name = File.basename @execution_context[:input_document]
93
+ base_name.gsub!(extension_name, "")
94
+ extension_name = '.xml' if @execution_context[:xml_output]
95
+
96
+ @execution_context[:output_document] =
97
+ "#{base_name}_output#{extension_name}"
98
+ end
99
+ end
100
+ end
101
+
102
+ def self.usage
103
+ str = "Usage: ruby greenpepper.rb input_document "
104
+ str += "[ouput_document] [options]\n\n"
105
+ str += "--help Display the help.\n"
106
+ str += "--version Output version information.\n"
107
+ str += "-r CLASS;ARGS The url of the repository of the" +
108
+ str += " specifications.\n"
109
+ str += "--no-html-results This option will not print result in output.\n"
110
+ str += "--xml [output_document] Generate XML report (default is plain text)."
111
+ str += " If output_document is specified, the xml report will outputed"
112
+ str += " in the specified file.\n"
113
+ str += "--no-exception-stack Disable outputting of exception stack when"
114
+ str += " execution exception are raised.\n"
115
+ str += "--load_path path1 [pathX] List of path to include for execution."
116
+ str
117
+ end
118
+
119
+ =begin
120
+ This doc came from greenpeppersoftware.com ... this will be needed to fill self.usage
121
+
122
+ Usage: greenpepper [options] input [ouput]
123
+ Run the input specification and produce a report in output file or in directory specified by -o
124
+
125
+ Options:
126
+ Ignore :-l, --locale LANG Set application language (en, fr, ...)
127
+ #-f, --sud CLASS;ARGS Use CLASS as the system under development and instantiate it with ARGS
128
+ #-o DIRECTORY Produce reports in DIRECTORY (defaults to current directory)
129
+ #-r CLASS;ARGS Use CLASS as the document repository and instantiate it with ARGS (defaults to com.greenpepper.repository.FileSystemRepository)
130
+ #-s, --suite Run a suite rather than a single test (output must refer to a directory)
131
+ -t SECTIONS Filter input specification to only execute SECTIONS (comma separated list of sections)
132
+ -a ARGS Semicolon seperated list of assemblies fullName
133
+
134
+ Ignore : --selector CLASS Use CLASS as the interpreter selector (defaults to com.greenpepper.document.GreenPepperInterpreterSelector)
135
+ # --lazy Set greenpepper in lazy mode for document execution
136
+ # --xml Generate XML report (defaults to plain)
137
+ # --help Display this help and exit
138
+ # --version Output version information and exit
139
+ Don't implement for now : --debug Enable debug mode
140
+ # --stop Stop the execution of the specification on the first failure
141
+
142
+ When no option is given, GreenPepper defaults to the following rules:
143
+
144
+ * Input is a single specification, not a suite
145
+ * If output is not specified, reports are produced in the current directory
146
+ * Report is in plain format
147
+ * The operating system locale is used
148
+ Not in story * The input specification is not filtered
149
+ * The specification file must be located on the file system
150
+ * Fixtures are created using the default built-in mechanism
151
+ * Tables use GreenPepper formalism
152
+ * Lazy mode is disabled
153
+ * Debug mode is disabled
154
+ * Will not stop the execution on first failure
155
+
156
+ Any of the rules above can be overridden using command line switches.
157
+
158
+ =end
159
+ end
160
+
161
+ end #module GreenPepper
@@ -0,0 +1,7 @@
1
+ module LoadPath
2
+ def self.load(paths)
3
+ paths.reverse.each{ |path|
4
+ $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
5
+ }
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ =begin
2
+ author: Martin Provencher (mprovencher86@gmail.com)
3
+ date: September 3, 2009
4
+ =end
5
+
6
+ module GreenPepper
7
+
8
+ class ExampleContext
9
+ attr_accessor :index
10
+
11
+ def initialize(index = 0)
12
+ @index = index
13
+ end
14
+ end
15
+
16
+ class HtmlContext < ExampleContext
17
+ attr_accessor :nb_table, :first_table_index
18
+
19
+ def initialize(index = 0, first_table_index = 0, nb_table = 1)
20
+ super(index)
21
+ @first_table_index = first_table_index
22
+ @nb_table = nb_table
23
+ end
24
+ end
25
+
26
+ end #module GreenPepper
@@ -0,0 +1,347 @@
1
+ =begin
2
+ authors: Simon Mathieu (simon.math@gmail.com)
3
+ Sebastien Boisclair (sebboisclair@gmail.com)
4
+ date: March 3, 2009
5
+ =end
6
+ module GreenPepper
7
+
8
+ require 'singleton'
9
+ require 'date'
10
+ require 'greenpepper/grammar/arrayparser'
11
+
12
+ class TypeConverter
13
+ include Singleton
14
+
15
+ def initialize
16
+ @converters = []
17
+ end
18
+
19
+ def convert_string(string)
20
+ @converters.each { |type|
21
+ if type.can_parse? string
22
+ return type.convert.call(string)
23
+ end
24
+ }
25
+ string
26
+ end
27
+
28
+ def format_object(expected_string_format, object)
29
+ @converters.each { |type|
30
+ if type.can_parse? expected_string_format
31
+ return type.format.call(object, expected_string_format)
32
+ end
33
+ }
34
+ object.to_s
35
+ end
36
+
37
+ #Encapsulate all the type conversion logic for fixtures
38
+ def auto_convert_string(fixture, name, string)
39
+ parse_f = conversion_func name
40
+ if fixture.respond_to?(parse_f)
41
+ if string.is_a? Array
42
+ return fixture.send(parse_f, *string)
43
+ else
44
+ return fixture.send(parse_f, string)
45
+ end
46
+ else
47
+ if string.is_a? Array
48
+ return string.collect{|s| convert_string s}
49
+ else
50
+ return convert_string(string)
51
+ end
52
+ end
53
+ end
54
+
55
+ def auto_convert_object(fixture, name, expected_format, object)
56
+ format_f = format_func name
57
+ if fixture.respond_to?(format_f)
58
+ return fixture.send(format_f, object)
59
+ else
60
+ return format_object(expected_format, object)
61
+ end
62
+ end
63
+
64
+ def add_conversion_type(type)
65
+ @converters << type
66
+ end
67
+
68
+ private
69
+ def conversion_func(name)
70
+ ("parse_" + NameResolver.format_column_name(name)).to_sym
71
+ end
72
+
73
+ def format_func(name)
74
+ ("format_" + NameResolver.format_column_name(name)).to_sym
75
+ end
76
+ end
77
+
78
+ class TypeBase
79
+ def TypeBase.inherited(subclass)
80
+ TypeConverter.instance.add_conversion_type subclass
81
+ end
82
+
83
+ def self.can_parse?(str)
84
+ regex === str
85
+ end
86
+
87
+ def self.format
88
+ Proc.new{|object,expected_format| object.to_s}
89
+ end
90
+
91
+ end
92
+
93
+ class ErrorType < TypeBase
94
+
95
+ def self.regex
96
+ /^[\s]*error[\s]*$/i
97
+ end
98
+
99
+ def self.convert
100
+ Proc.new{|s| Exception.new}
101
+ end
102
+
103
+ def self.format
104
+ Proc.new{|object, expected_format|
105
+ if object.is_a? Exception
106
+ expected_format
107
+ else
108
+ object.to_s
109
+ end
110
+ }
111
+ end
112
+ end
113
+
114
+ class IntType < TypeBase
115
+
116
+ def self.regex
117
+ /^\s*-?[0-9]+\s*$/
118
+ end
119
+
120
+ def self.convert
121
+ Proc.new{|s| s.to_i}
122
+ end
123
+ end
124
+
125
+
126
+ class FloatType < TypeBase
127
+
128
+ def self.regex
129
+ /^\s*-?[0-9]*\.[0-9]+\s*$/
130
+ end
131
+
132
+ def self.convert
133
+ Proc.new{|s| s.to_f}
134
+ end
135
+
136
+ def self.format
137
+ Proc.new{ |b, expected_format|
138
+ if expected_format.match /^.[0-9]+$/
139
+ b.to_s[1..-1]
140
+ else
141
+ b.to_s
142
+ end
143
+ }
144
+ end
145
+ end
146
+
147
+ class BoolType < TypeBase
148
+ def self.regex
149
+ /^\s*(true|false|yes|no)\s*$/i
150
+ end
151
+
152
+ def self.convert
153
+ Proc.new{ |s|
154
+ (/true|yes/i =~ s) != nil
155
+ }
156
+ end
157
+
158
+ def self.format
159
+ Proc.new{ |b,expected_format|
160
+ yes = "yes"
161
+ no = "no"
162
+
163
+ case expected_format
164
+ when /^True|False$/
165
+ b.to_s.capitalize
166
+ when /^yes|no$/
167
+ b ? yes : no
168
+ when /^Yes|No$/
169
+ b ? yes.capitalize : no.capitalize
170
+ else
171
+ b.to_s
172
+ end
173
+ }
174
+ end
175
+ end
176
+
177
+ class BlankStringType < TypeBase
178
+ def self.regex
179
+ /^\s*blank\s*$/i
180
+ end
181
+
182
+ def self.convert
183
+ Proc.new{ |s|
184
+ ""
185
+ }
186
+ end
187
+
188
+ def self.format
189
+ Proc.new{ |s,expected_format|
190
+ expected_format
191
+ }
192
+ end
193
+ end
194
+
195
+ class NilType < TypeBase
196
+ def self.regex
197
+ /^\s*(nil|null|none|nothing|\s*)\s*$/i
198
+ end
199
+
200
+ def self.convert
201
+ Proc.new{ |s|
202
+ nil
203
+ }
204
+ end
205
+
206
+ def self.format
207
+ Proc.new{ |n,expected_format|
208
+ #The server return some weird unicode char when a cell is
209
+ #empty and since ruby 1.8 doesn't like unicode in regex, we
210
+ #have to do this ugly path here.
211
+ if /^\s*$/ === expected_format || expected_format[0] == 194
212
+ n.to_s
213
+ else
214
+ expected_format
215
+ end
216
+ }
217
+ end
218
+ end
219
+
220
+ class IsoDate < TypeBase
221
+ def self.regex
222
+ /^\s*(\d{4})\D?(0[1-9]|1[0-2])\D?([12]\d|0[1-9]|3[01])(\D?([01]\d|2[0-3])\D?([0-5]\d)\D?([0-5]\d)?\D?(\d{3})?([zZ]|([\+-])([01]\d|2[0-3])\D?([0-5]\d)?)?)?\s*$/
223
+ end
224
+
225
+ def self.convert
226
+ Proc.new{ |s|
227
+ begin
228
+ DateTime.parse(s)
229
+ rescue ArgumentError => exception
230
+ raise(GreenPepperTypeError.new,"Can't parse date #{s}")
231
+ end
232
+ }
233
+ end
234
+
235
+ def self.format
236
+ Proc.new{ |d,expected_format|
237
+ date_base_slash = d.year.to_s.rjust(4,"0") + "-" +
238
+ d.month.to_s.rjust(2,"0") + "-" + d.day.to_s.rjust(2,"0")
239
+ date_base_frontslash = d.year.to_s.rjust(4,"0") + "/" +
240
+ d.month.to_s.rjust(2,"0") + "/" + d.day.to_s.rjust(2,"0")
241
+ date_hour_min = d.hour.to_s.rjust(2,"0") + ":" +
242
+ d.min.to_s.rjust(2,"0")
243
+ date_extension = "Z"
244
+
245
+ case expected_format
246
+ when /^(\d+)\-(\d+)\-(\d+)\w(\d+):(\d+)\w$/
247
+ date_base_slash + "T" + date_hour_min + date_extension
248
+ when /^(\d+)\-(\d+)\-(\d+)\s(\d+):(\d+)$/
249
+ date_base_slash + " " + date_hour_min
250
+ when /^(\d+)\-(\d+)\-(\d+)\s(\d+):(\d+)\w$/
251
+ date_base_slash + " " + date_hour_min + date_extension
252
+ when /^(\d+)\-(\d+)\-(\d+)$/
253
+ date_base_slash
254
+ when /^(\d+)\/(\d+)\/(\d+)\w(\d+):(\d+)\w$/
255
+ date_base_frontslash + "T" + date_hour_min + date_extension
256
+ when /^(\d+)\/(\d+)\/(\d+)\s(\d+):(\d+)$/
257
+ date_base_frontslash + " " + date_hour_min
258
+ when /^(\d+)\/(\d+)\/(\d+)\s(\d+):(\d+)\w$/
259
+ date_base_frontslash + " " + date_hour_min + date_extension
260
+ when /^(\d+)\/(\d+)\/(\d+)$/
261
+ date_base_frontslash
262
+ else
263
+ d.to_s
264
+ end
265
+ }
266
+ end
267
+ end
268
+
269
+ class ExplicitStringType < TypeBase
270
+ def self.regex
271
+ /^\s*["'].*["']\s*$/
272
+ end
273
+
274
+ def self.convert
275
+ Proc.new{ |s| s[1..-2] }
276
+ end
277
+
278
+ def self.format
279
+ Proc.new{ |str,expected_format|
280
+ if (expected_format.index("'") == 0)
281
+ "'" + str.to_s + "'"
282
+ else
283
+ "\"" + str.to_s + "\""
284
+ end
285
+ }
286
+ end
287
+ end
288
+
289
+ class EmptyArrayType < TypeBase
290
+ def self.regex
291
+ /^\s*empty\s*$/i
292
+ end
293
+
294
+ def self.convert
295
+ Proc.new{ |s| [] }
296
+ end
297
+
298
+ def self.format
299
+ Proc.new{ |a,expected_format|
300
+ expected_format
301
+ }
302
+ end
303
+ end
304
+
305
+ class ArrayType < TypeBase
306
+ def self.regex
307
+ /^\s*(\[([^,]*,?)*\])|(([^,]+,)+[^,]+,?)\s*$/
308
+ end
309
+
310
+ def self.convert
311
+ Proc.new{ |s|
312
+ data = ArrayGrammarModule.parse(s)
313
+
314
+ data.collect{ |x|
315
+ TypeConverter.instance.convert_string x
316
+ }
317
+ }
318
+ end
319
+
320
+ def self.format
321
+ Proc.new{ |a,expected_format|
322
+ if a != nil
323
+ expected = ArrayGrammarModule.parse(expected_format)
324
+
325
+ a.each_index{|i|
326
+ a[i] = TypeConverter.instance.format_object expected[i],
327
+ a[i]
328
+ }
329
+
330
+ case expected_format
331
+ when /^\[([^,]*,)*\]$/
332
+ "[" + a.join(",") + ",]"
333
+ when /^\[([^,]*,?)*\]$/
334
+ "[" + a.join(",") + "]"
335
+ when /^([^,]+,)+[^,]+,$/
336
+ a.join(",") + ","
337
+ else
338
+ a.join(",")
339
+ end
340
+ else
341
+ ""
342
+ end
343
+ }
344
+ end
345
+ end
346
+
347
+ end #module GreenPepper