omnitest 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.gitmodules +0 -0
- data/.groc.json +7 -0
- data/.rspec +6 -0
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +47 -0
- data/.travis.yml +12 -0
- data/.yardopts +3 -0
- data/Gemfile +26 -0
- data/README.md +341 -0
- data/Rakefile +33 -0
- data/appveyor.yml +9 -0
- data/bin/omnidoc +5 -0
- data/bin/omnitask +5 -0
- data/bin/omnitest +5 -0
- data/bower.json +21 -0
- data/doc-src/index.md.tt +341 -0
- data/doc-src/project_sets.md.tt +31 -0
- data/doc-src/usage/crosstask.md.tt +86 -0
- data/doc-src/usage/omnitest.md.tt +87 -0
- data/features/bootstrapping.feature +25 -0
- data/features/cloning.feature +32 -0
- data/features/fixtures/configs/omnitest_sample.yaml +11 -0
- data/features/fixtures/configs/skeptic_empty.yaml +12 -0
- data/features/fixtures/configs/skeptic_hello_world.yaml +10 -0
- data/features/show.feature +38 -0
- data/features/states.feature +40 -0
- data/features/step_definitions/sdk_steps.rb +22 -0
- data/features/support/env.rb +9 -0
- data/lib/omnitest.rb +211 -0
- data/lib/omnitest/cli.rb +297 -0
- data/lib/omnitest/command.rb +103 -0
- data/lib/omnitest/command/generate.rb +29 -0
- data/lib/omnitest/command/generators/code2doc.rb +79 -0
- data/lib/omnitest/command/generators/dashboard.rb +148 -0
- data/lib/omnitest/command/generators/documentation.rb +119 -0
- data/lib/omnitest/command/list.rb +62 -0
- data/lib/omnitest/command/project_action.rb +26 -0
- data/lib/omnitest/command/scenario_action.rb +20 -0
- data/lib/omnitest/command/show.rb +148 -0
- data/lib/omnitest/command/task.rb +27 -0
- data/lib/omnitest/command/test.rb +41 -0
- data/lib/omnitest/configuration.rb +53 -0
- data/lib/omnitest/documentation_generator.rb +68 -0
- data/lib/omnitest/project.rb +100 -0
- data/lib/omnitest/project_logger.rb +273 -0
- data/lib/omnitest/project_set.rb +47 -0
- data/lib/omnitest/reporters.rb +27 -0
- data/lib/omnitest/reporters/hash_reporter.rb +32 -0
- data/lib/omnitest/reporters/json_reporter.rb +12 -0
- data/lib/omnitest/reporters/markdown_reporter.rb +26 -0
- data/lib/omnitest/reporters/yaml_reporter.rb +12 -0
- data/lib/omnitest/run_action.rb +44 -0
- data/lib/omnitest/version.rb +3 -0
- data/lib/omnitest/workflow.rb +5 -0
- data/mkdocs.yml +8 -0
- data/omnitest.gemspec +39 -0
- data/omnitest.yaml +5 -0
- data/resources/assets/angular/angular.min.js +217 -0
- data/resources/assets/angular/angular.min.js.map +8 -0
- data/resources/assets/angular/json-formatter.min.css +6 -0
- data/resources/assets/angular/json-formatter.min.js +7 -0
- data/resources/assets/angular/ng-table.map +1 -0
- data/resources/assets/angular/ng-table.min.css +3 -0
- data/resources/assets/angular/ng-table.min.js +3 -0
- data/resources/assets/angular/ui-bootstrap-tpls.min.js +10 -0
- data/resources/assets/bootstrap/bootstrap.min.css +9 -0
- data/resources/assets/fonts/glyphicons-halflings-regular.eot +0 -0
- data/resources/assets/fonts/glyphicons-halflings-regular.svg +229 -0
- data/resources/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/resources/assets/fonts/glyphicons-halflings-regular.woff +0 -0
- data/resources/assets/pygments/autumn.css +58 -0
- data/resources/assets/pygments/borland.css +46 -0
- data/resources/assets/pygments/bw.css +34 -0
- data/resources/assets/pygments/colorful.css +61 -0
- data/resources/assets/pygments/default.css +62 -0
- data/resources/assets/pygments/emacs.css +61 -0
- data/resources/assets/pygments/friendly.css +61 -0
- data/resources/assets/pygments/fruity.css +69 -0
- data/resources/assets/pygments/github.css +61 -0
- data/resources/assets/pygments/manni.css +61 -0
- data/resources/assets/pygments/monokai.css +64 -0
- data/resources/assets/pygments/murphy.css +61 -0
- data/resources/assets/pygments/native.css +69 -0
- data/resources/assets/pygments/pastie.css +60 -0
- data/resources/assets/pygments/perldoc.css +58 -0
- data/resources/assets/pygments/tango.css +69 -0
- data/resources/assets/pygments/trac.css +59 -0
- data/resources/assets/pygments/vim.css +69 -0
- data/resources/assets/pygments/vs.css +33 -0
- data/resources/assets/pygments/zenburn.css +1 -0
- data/resources/assets/style.css +56 -0
- data/resources/code_sample.tt +2 -0
- data/resources/generators/dashboard/files/dashboard.html.tt +51 -0
- data/resources/generators/dashboard/files/dashboard.js +26 -0
- data/resources/generators/dashboard/templates/_test_report.html.haml +91 -0
- data/resources/generators/todo/templates/todo.md.tt +6 -0
- data/resources/generators/todo/todo_template.rb +1 -0
- data/samples/.gitignore +2 -0
- data/samples/_markdown.md +5 -0
- data/samples/bootstrap.sh +2 -0
- data/samples/clone.sh +2 -0
- data/samples/code2doc.sh +5 -0
- data/samples/default_bootstrap.rb +7 -0
- data/samples/detect.sh +2 -0
- data/samples/exec.sh +2 -0
- data/samples/omnitest.yaml +24 -0
- data/samples/omnitest_simple.yaml +8 -0
- data/samples/scripts/bootstrap +3 -0
- data/samples/show.sh +4 -0
- data/samples/skeptic.yaml +13 -0
- data/samples/skeptic_simple.yaml +9 -0
- data/samples/test.sh +2 -0
- data/samples/tests/omnitest/validators.rb +23 -0
- data/samples/verify.sh +3 -0
- data/scripts/bootstrap.ps1 +7 -0
- data/scripts/run_script.sh +4 -0
- data/skeptic.yaml +26 -0
- data/spec/fabricators/project_fabricator.rb +19 -0
- data/spec/fabricators/scenario_fabricator.rb +6 -0
- data/spec/fabricators/test_manifest_fabricator.rb +41 -0
- data/spec/fabricators/validator_fabricator.rb +12 -0
- data/spec/fixtures/factorial.py +18 -0
- data/spec/fixtures/omnitest.yaml +11 -0
- data/spec/fixtures/skeptic.yaml +16 -0
- data/spec/fixtures/src-doc/_scenario.md.erb +1 -0
- data/spec/fixtures/src-doc/quine.md.erb +20 -0
- data/spec/omnitest/cli_spec.rb +38 -0
- data/spec/omnitest/configuration_spec.rb +25 -0
- data/spec/omnitest/documentation_generator_spec.rb +59 -0
- data/spec/omnitest/file_finder_spec.rb +21 -0
- data/spec/omnitest/project_spec.rb +65 -0
- data/spec/omnitest_spec.rb +13 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/thor_spy.rb +66 -0
- data/tests/omnitest/bootstrap_validations.rb +7 -0
- data/tests/omnitest/show_validations.rb +22 -0
- data/yard_macros.rb +25 -0
- metadata +470 -0
data/lib/omnitest/cli.rb
ADDED
@@ -0,0 +1,297 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
require 'omnitest'
|
4
|
+
require 'omnitest/command'
|
5
|
+
require 'omnitest/command/generate'
|
6
|
+
require 'omnitest/psychic/cli'
|
7
|
+
require 'omnitest/skeptic/cli'
|
8
|
+
|
9
|
+
module Omnitest
|
10
|
+
module Command
|
11
|
+
class Generate
|
12
|
+
autoload :Dashboard, 'omnitest/command/generators/dashboard'
|
13
|
+
autoload :Code2Doc, 'omnitest/command/generators/code2doc'
|
14
|
+
autoload :Documentation, 'omnitest/command/generators/documentation'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module CLI
|
19
|
+
class BaseCLI < Omnitest::Core::CLI
|
20
|
+
# The maximum number of concurrent instances that can run--which is a bit
|
21
|
+
# high
|
22
|
+
MAX_CONCURRENCY = 9999
|
23
|
+
|
24
|
+
# Constructs a new instance.
|
25
|
+
def initialize(*args)
|
26
|
+
super
|
27
|
+
$stdout.sync = true
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
# Convert a Thor Option object to a hash so we can copy options from
|
33
|
+
# other commands.
|
34
|
+
#
|
35
|
+
# @param [Thor::Option] an option object
|
36
|
+
# @return [Hash] the options as a hash
|
37
|
+
# @api private
|
38
|
+
def self.option_to_hash(option)
|
39
|
+
[
|
40
|
+
:banner, :default, :description, :enum, :name,
|
41
|
+
:required, :type, :aliases, :group, :hide, :lazy_default
|
42
|
+
].each_with_object({}) do | option_type, options_hash |
|
43
|
+
options_hash[option_type] = option.send(option_type)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Ensure the any failing commands exit non-zero.
|
48
|
+
#
|
49
|
+
# @return [true] you die always on failure
|
50
|
+
# @api private
|
51
|
+
def self.exit_on_failure?
|
52
|
+
true
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [Logger] the common logger
|
56
|
+
# @api private
|
57
|
+
def logger
|
58
|
+
Omnitest.logger
|
59
|
+
end
|
60
|
+
|
61
|
+
# Update and finalize options for logging, concurrency, and other concerns.
|
62
|
+
#
|
63
|
+
# @api private
|
64
|
+
def update_config!
|
65
|
+
Omnitest.update_config!(@options)
|
66
|
+
end
|
67
|
+
|
68
|
+
# If auto_init option is active, invoke the init generator.
|
69
|
+
#
|
70
|
+
# @api private
|
71
|
+
def ensure_initialized
|
72
|
+
end
|
73
|
+
|
74
|
+
def duration(total)
|
75
|
+
total = 0 if total.nil?
|
76
|
+
minutes = (total / 60).to_i
|
77
|
+
seconds = (total - (minutes * 60))
|
78
|
+
format('(%dm%.2fs)', minutes, seconds)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class CrosstaskCLI < BaseCLI
|
83
|
+
desc 'clone [PROJECT|REGEXP|all]', 'Fetches the projects from version control'
|
84
|
+
method_option :concurrency,
|
85
|
+
aliases: '-c',
|
86
|
+
type: :numeric,
|
87
|
+
lazy_default: MAX_CONCURRENCY,
|
88
|
+
desc: <<-DESC.gsub(/^\s+/, '').gsub(/\n/, ' ')
|
89
|
+
Run the task against all matching instances concurrently. Only N
|
90
|
+
instances will run at the same time if a number is given.
|
91
|
+
DESC
|
92
|
+
method_option :log_level,
|
93
|
+
aliases: '-l',
|
94
|
+
desc: 'Set the log level (debug, info, warn, error, fatal)'
|
95
|
+
method_option :file,
|
96
|
+
aliases: '-f',
|
97
|
+
desc: 'The Omnitest project set file',
|
98
|
+
default: 'omnitest.yaml'
|
99
|
+
def clone(*args)
|
100
|
+
update_config!
|
101
|
+
Omnitest.clone(*args)
|
102
|
+
end
|
103
|
+
|
104
|
+
desc 'workflow <name> [PROJECT|REGEXP|all]', 'Run the workflow against each project'
|
105
|
+
method_option :concurrency,
|
106
|
+
aliases: '-c',
|
107
|
+
type: :numeric,
|
108
|
+
lazy_default: MAX_CONCURRENCY,
|
109
|
+
desc: <<-DESC.gsub(/^\s+/, '').gsub(/\n/, ' ')
|
110
|
+
Run the task against all matching instances concurrently. Only N
|
111
|
+
instances will run at the same time if a number is given.
|
112
|
+
DESC
|
113
|
+
method_option :log_level,
|
114
|
+
aliases: '-l',
|
115
|
+
desc: 'Set the log level (debug, info, warn, error, fatal)'
|
116
|
+
method_option :file,
|
117
|
+
aliases: '-f',
|
118
|
+
desc: 'The Omnitest project set file',
|
119
|
+
default: 'omnitest.yaml'
|
120
|
+
method_option :travis, type: :boolean, desc: "Enable/disable delegation to travis-build, if it's available"
|
121
|
+
def workflow(name, project_regex = 'all')
|
122
|
+
abort 'A workflow name is required' if args.empty?
|
123
|
+
update_config!
|
124
|
+
Omnitest.workflow(project_regex, name)
|
125
|
+
end
|
126
|
+
|
127
|
+
Psychic::CLI.commands.each do | action, command |
|
128
|
+
next if action == 'workflow' # We've customized it a bit
|
129
|
+
|
130
|
+
enhanced_banner = "#{action} [PROJECT|REGEXP|all]"
|
131
|
+
desc enhanced_banner, command.description
|
132
|
+
long_desc command.long_description
|
133
|
+
method_option :file,
|
134
|
+
aliases: '-f',
|
135
|
+
desc: 'The Omnitest project set file',
|
136
|
+
default: 'omnitest.yaml'
|
137
|
+
method_option :travis, type: :boolean, desc: "Enable/disable delegation to travis-build, if it's available"
|
138
|
+
command.options.select do | name, option |
|
139
|
+
method_option name, option_to_hash(option)
|
140
|
+
end
|
141
|
+
define_method(action) do |*args|
|
142
|
+
update_config!
|
143
|
+
Omnitest.public_send(action, *args)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class CrossdocCLI < BaseCLI
|
149
|
+
register Command::Generate::Dashboard, 'dashboard', 'dashboard', 'Create a report dashboard'
|
150
|
+
tasks['dashboard'].options = Command::Generate::Dashboard.class_options
|
151
|
+
|
152
|
+
register Command::Generate::Code2Doc, 'code2doc', 'code2doc [PROJECT|REGEXP|all] [SCENARIO|REGEXP|all]',
|
153
|
+
'Generates documenation from sample code for one or more scenarios'
|
154
|
+
tasks['code2doc'].options = Command::Generate::Code2Doc.class_options
|
155
|
+
|
156
|
+
register Command::Generate::Documentation, 'generate', 'generate', 'Generates documentation, reports or other files from templates'
|
157
|
+
tasks['generate'].options = Command::Generate::Documentation.class_options
|
158
|
+
tasks['generate'].long_description = <<-eos
|
159
|
+
Generates documentation, reports or other files from templates. The templates may use Thor actions and Padrino helpers
|
160
|
+
in order to inject data from Omnitest test runs, code samples, or other sources.
|
161
|
+
|
162
|
+
Available templates: #{Command::Generate::Documentation.generator_names.join(', ')}
|
163
|
+
You may also run it against a directory containing a template with the --source option.
|
164
|
+
eos
|
165
|
+
end
|
166
|
+
|
167
|
+
class OmnitestCLI < CrosstaskCLI # rubocop:disable ClassLength
|
168
|
+
def self.filter_options
|
169
|
+
method_option :failed,
|
170
|
+
type: :boolean,
|
171
|
+
desc: 'Only list tests that failed / passed'
|
172
|
+
method_option :skipped,
|
173
|
+
type: :boolean,
|
174
|
+
desc: 'Only list tests that were skipped / executed'
|
175
|
+
method_option :samples,
|
176
|
+
type: :boolean,
|
177
|
+
desc: 'Only list tests that have sample code / do not have sample code'
|
178
|
+
end
|
179
|
+
|
180
|
+
Skeptic::CLI.commands.each do | action, command |
|
181
|
+
enhanced_banner = "#{action} [PROJECT|REGEXP|all] [SCENARIO|REGEXP|all]"
|
182
|
+
desc enhanced_banner, command.description
|
183
|
+
long_desc command.long_description
|
184
|
+
method_option :file,
|
185
|
+
aliases: '-f',
|
186
|
+
desc: 'The Omnitest project set file',
|
187
|
+
default: 'omnitest.yaml'
|
188
|
+
command.options.select do | name, option |
|
189
|
+
method_option name, option_to_hash(option)
|
190
|
+
end
|
191
|
+
define_method action do |*args|
|
192
|
+
update_config!
|
193
|
+
Omnitest.public_send(action, *args)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
desc 'list [PROJECT|REGEXP|all] [SCENARIO|REGEXP|all]', 'Lists one or more scenarios'
|
198
|
+
method_option :log_level,
|
199
|
+
aliases: '-l',
|
200
|
+
desc: 'Set the log level (debug, info, warn, error, fatal)'
|
201
|
+
method_option :format,
|
202
|
+
desc: 'List output format',
|
203
|
+
enum: %w(text markdown json yaml),
|
204
|
+
default: 'text'
|
205
|
+
method_option :file,
|
206
|
+
aliases: '-f',
|
207
|
+
desc: 'The Omnitest project set file',
|
208
|
+
default: 'omnitest.yaml'
|
209
|
+
method_option :skeptic,
|
210
|
+
aliases: '-s',
|
211
|
+
desc: 'The Skeptic test manifest file',
|
212
|
+
default: 'skeptic.yaml'
|
213
|
+
method_option :test_dir,
|
214
|
+
aliases: '-t',
|
215
|
+
desc: 'The Omnitest test directory',
|
216
|
+
default: 'tests/omnitest'
|
217
|
+
method_option :source,
|
218
|
+
desc: 'Display the path to source code in the list?',
|
219
|
+
type: :boolean
|
220
|
+
filter_options
|
221
|
+
def list(*args)
|
222
|
+
update_config!
|
223
|
+
perform('list', 'list', args, options)
|
224
|
+
end
|
225
|
+
|
226
|
+
desc 'show [PROJECT|REGEXP|all] [SCENARIO|REGEXP|all]', 'Show detailed status for one or more scenarios'
|
227
|
+
method_option :log_level,
|
228
|
+
aliases: '-l',
|
229
|
+
desc: 'Set the log level (debug, info, warn, error, fatal)'
|
230
|
+
method_option :format,
|
231
|
+
desc: 'List output format',
|
232
|
+
enum: %w(text markdown json yaml),
|
233
|
+
default: 'text'
|
234
|
+
method_option :file,
|
235
|
+
aliases: '-f',
|
236
|
+
desc: 'The Omnitest project set file',
|
237
|
+
default: 'omnitest.yaml'
|
238
|
+
method_option :skeptic,
|
239
|
+
aliases: '-s',
|
240
|
+
desc: 'The Skeptic test manifest file',
|
241
|
+
default: 'skeptic.yaml'
|
242
|
+
method_option :source,
|
243
|
+
desc: 'Display the source code for the sample'
|
244
|
+
method_option :test_dir,
|
245
|
+
aliases: '-t',
|
246
|
+
desc: 'The Omnitest test directory',
|
247
|
+
default: 'tests/omnitest'
|
248
|
+
filter_options
|
249
|
+
def show(*args)
|
250
|
+
update_config!
|
251
|
+
perform('show', 'show', args, options)
|
252
|
+
end
|
253
|
+
|
254
|
+
desc 'test [PROJECT|REGEXP|all] [SCENARIO|REGEXP|all]',
|
255
|
+
'Test (clone, bootstrap, exec, and verify) one or more scenarios'
|
256
|
+
long_desc <<-DESC
|
257
|
+
The scenario states are in order: cloned, bootstrapped, executed, verified.
|
258
|
+
Test changes the state of one or more scenarios executes
|
259
|
+
the actions for each state up to verify.
|
260
|
+
DESC
|
261
|
+
method_option :concurrency,
|
262
|
+
aliases: '-c',
|
263
|
+
type: :numeric,
|
264
|
+
lazy_default: MAX_CONCURRENCY,
|
265
|
+
desc: <<-DESC.gsub(/^\s+/, '').gsub(/\n/, ' ')
|
266
|
+
Run a test against all matching instances concurrently. Only N
|
267
|
+
instances will run at the same time if a number is given.
|
268
|
+
DESC
|
269
|
+
method_option :log_level,
|
270
|
+
aliases: '-l',
|
271
|
+
desc: 'Set the log level (debug, info, warn, error, fatal)'
|
272
|
+
method_option :file,
|
273
|
+
aliases: '-f',
|
274
|
+
desc: 'The Omnitest project set file',
|
275
|
+
default: 'omnitest.yaml'
|
276
|
+
method_option :skeptic,
|
277
|
+
aliases: '-s',
|
278
|
+
desc: 'The Skeptic test manifest file',
|
279
|
+
default: 'skeptic.yaml'
|
280
|
+
method_option :test_dir,
|
281
|
+
aliases: '-t',
|
282
|
+
desc: 'The Omnitest test directory',
|
283
|
+
default: 'tests/omnitest'
|
284
|
+
def test(*args)
|
285
|
+
update_config!
|
286
|
+
action_options = options.dup
|
287
|
+
perform('test', 'test', args, action_options)
|
288
|
+
end
|
289
|
+
|
290
|
+
desc 'version', "Print Omnitest's version information"
|
291
|
+
def version
|
292
|
+
puts "Omnitest version #{Omnitest::VERSION}"
|
293
|
+
end
|
294
|
+
map %w(-v --version) => :version
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'English'
|
3
|
+
|
4
|
+
module Omnitest
|
5
|
+
module Command
|
6
|
+
class Base # rubocop:disable ClassLength
|
7
|
+
include Core::DefaultLogger
|
8
|
+
include Omnitest::Core::Logging
|
9
|
+
include Omnitest::Core::FileSystem
|
10
|
+
|
11
|
+
# Contstructs a new Command object.
|
12
|
+
#
|
13
|
+
# @param cmd_args [Array] remainder of the arguments from processed ARGV
|
14
|
+
# @param cmd_options [Hash] hash of Thor options
|
15
|
+
# @param options [Hash] configuration options
|
16
|
+
# @option options [String] :action action to take, usually corresponding
|
17
|
+
# to the subcommand name (default: `nil`)
|
18
|
+
# @option options [proc] :help a callable that displays help for the
|
19
|
+
# command
|
20
|
+
# @option options [Config] :test_dir a Config object (default: `nil`)
|
21
|
+
# @option options [Loader] :loader a Loader object (default: `nil`)
|
22
|
+
# @option options [String] :shell a Thor shell object
|
23
|
+
def initialize(action, cmd_args, cmd_options, options = {})
|
24
|
+
@action = action
|
25
|
+
@args = cmd_args
|
26
|
+
@options = cmd_options
|
27
|
+
@help = options.fetch(:help, -> { 'No help provided' })
|
28
|
+
@project_set_file = options.fetch('file', nil)
|
29
|
+
@skeptic_file = options.fetch('skeptic', nil)
|
30
|
+
@loader = options.fetch(:loader, nil)
|
31
|
+
@shell = options.fetch(:shell)
|
32
|
+
@queue = Queue.new
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# @return [Array] remainder of the arguments from processed ARGV
|
38
|
+
# @api private
|
39
|
+
attr_reader :args
|
40
|
+
|
41
|
+
# @return [Hash] hash of Thor options
|
42
|
+
# @api private
|
43
|
+
attr_reader :options
|
44
|
+
|
45
|
+
# @return [proc] a callable that displays help for the command
|
46
|
+
# @api private
|
47
|
+
attr_reader :help
|
48
|
+
|
49
|
+
# @return [Thor::Shell] a Thor shell object
|
50
|
+
# @api private
|
51
|
+
attr_reader :shell
|
52
|
+
|
53
|
+
# @return [String] the action to perform
|
54
|
+
# @api private
|
55
|
+
attr_reader :action
|
56
|
+
|
57
|
+
def setup
|
58
|
+
Omnitest.setup
|
59
|
+
end
|
60
|
+
|
61
|
+
def project_set_file
|
62
|
+
@project_set_file ||= Omnitest.configuration.file
|
63
|
+
@project_set_file
|
64
|
+
end
|
65
|
+
|
66
|
+
# Emit an error message, display contextual help and then exit with a
|
67
|
+
# non-zero exit code.
|
68
|
+
#
|
69
|
+
# **Note** This method calls exit and will not return.
|
70
|
+
#
|
71
|
+
# @param msg [String] error message
|
72
|
+
# @api private
|
73
|
+
def die(msg)
|
74
|
+
logger.error "\n#{msg}\n\n"
|
75
|
+
help.call
|
76
|
+
exit 1
|
77
|
+
end
|
78
|
+
|
79
|
+
def select_projects(project_regexp = 'all', options = {})
|
80
|
+
projects = Omnitest.filter_projects(project_regexp, options)
|
81
|
+
die "No projects matching regex `#{project_regexp}', known projects: #{Omnitest.projects.map(&:name)}" if projects.empty?
|
82
|
+
projects
|
83
|
+
end
|
84
|
+
|
85
|
+
# Return an array on scenarios whos name matches the regular expression,
|
86
|
+
# the full instance name, or the `"all"` literal.
|
87
|
+
#
|
88
|
+
# @param arg [String] an instance name, a regular expression, the literal
|
89
|
+
# `"all"`, or `nil`
|
90
|
+
# @return [Array<Instance>] an array of scenarios
|
91
|
+
# @api private
|
92
|
+
def parse_subcommand(project_regexp = 'all', scenario_regexp = 'all', options = {})
|
93
|
+
scenarios = Omnitest.scenarios(project_regexp, scenario_regexp, options)
|
94
|
+
die "No scenarios for regex `#{scenario_regexp}', try running `omnitest list'" if scenarios.empty?
|
95
|
+
scenarios
|
96
|
+
rescue RegexpError => e
|
97
|
+
die 'Invalid Ruby regular expression, ' \
|
98
|
+
'you may need to single quote the argument. ' \
|
99
|
+
"Please try again or consult http://rubular.com/ (#{e.message})"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Omnitest
|
2
|
+
module Command
|
3
|
+
class Generate < Thor
|
4
|
+
namespace :generate
|
5
|
+
|
6
|
+
autoload :Dashboard, 'omnitest/command/generators/dashboard'
|
7
|
+
register Dashboard, 'dashboard', 'dashboard', 'Create a report dashboard'
|
8
|
+
tasks['dashboard'].options = Dashboard.class_options
|
9
|
+
|
10
|
+
autoload :Code2Doc, 'omnitest/command/generators/code2doc'
|
11
|
+
register Code2Doc, 'code2doc', 'code2doc [PROJECT|REGEXP|all] [SCENARIO|REGEXP|all]',
|
12
|
+
'Generates documenation from sample code for one or more scenarios'
|
13
|
+
tasks['code2doc'].options = Command::Generate::Code2Doc.class_options
|
14
|
+
|
15
|
+
autoload :Documentation, 'omnitest/command/generators/documentation'
|
16
|
+
register Documentation, 'generate', 'generate', 'Generates documentation, reports or other files from templates'
|
17
|
+
tasks['generate'].options = Documentation.class_options
|
18
|
+
tasks['generate'].long_description = <<-eos
|
19
|
+
Generates documentation, reports or other files from templates. The templates may use Thor actions and Padrino helpers
|
20
|
+
in order to inject data from Omnitest test runs, code samples, or other sources.
|
21
|
+
|
22
|
+
Available templates: #{Command::Generate::Documentation.generator_names.join(', ')}
|
23
|
+
You may also run it against a directory containing a template with the --source option.
|
24
|
+
eos
|
25
|
+
|
26
|
+
# FIXME: Help shows unwanted usage, e.g. "omnitest omnitest:command:report:code2_doc"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'omnitest/reporters'
|
3
|
+
require 'omnitest/documentation_generator'
|
4
|
+
|
5
|
+
module Omnitest
|
6
|
+
module Command
|
7
|
+
class Generate
|
8
|
+
class Code2Doc < Thor::Group
|
9
|
+
include Core::DefaultLogger
|
10
|
+
include Omnitest::Core::Logging
|
11
|
+
include Thor::Actions
|
12
|
+
include Omnitest::Core::FileSystem
|
13
|
+
include Omnitest::Core::Util::String
|
14
|
+
|
15
|
+
class_option :log_level,
|
16
|
+
aliases: '-l',
|
17
|
+
desc: 'Set the log level (debug, info, warn, error, fatal)'
|
18
|
+
class_option :file,
|
19
|
+
aliases: '-f',
|
20
|
+
desc: 'The Omnitest project set file',
|
21
|
+
default: 'omnitest.yaml'
|
22
|
+
class_option :skeptic,
|
23
|
+
aliases: '-s',
|
24
|
+
desc: 'The Skeptic test manifest file',
|
25
|
+
default: 'skeptic.yaml'
|
26
|
+
class_option :format,
|
27
|
+
aliases: '-f',
|
28
|
+
enum: %w(md rst),
|
29
|
+
default: 'md',
|
30
|
+
desc: 'Target documentation format'
|
31
|
+
class_option :target_dir,
|
32
|
+
aliases: '-d',
|
33
|
+
default: 'docs/',
|
34
|
+
desc: 'The target directory where documentation for generated documentation.'
|
35
|
+
class_option :source_files, type: :array
|
36
|
+
|
37
|
+
class_option :destination, default: 'docs/'
|
38
|
+
|
39
|
+
argument :project_regexp, default: 'all'
|
40
|
+
argument :scenario_regexp, default: 'all'
|
41
|
+
|
42
|
+
def setup
|
43
|
+
Omnitest.update_config!(options)
|
44
|
+
Omnitest.setup
|
45
|
+
@scenarios = Omnitest.scenarios(project_regexp, scenario_regexp, options)
|
46
|
+
abort "No scenarios for regex `#{scenario_regexp}', try running `omnitest list'" if @scenarios.empty?
|
47
|
+
end
|
48
|
+
|
49
|
+
def set_destination_root
|
50
|
+
self.destination_root = options[:destination]
|
51
|
+
end
|
52
|
+
|
53
|
+
def source_files
|
54
|
+
@source_files = @scenarios.map do |scenario|
|
55
|
+
[scenario.slug, scenario.absolute_source_file]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def code2doc
|
60
|
+
@source_files.each do |slug, source_file|
|
61
|
+
if source_file.nil?
|
62
|
+
warn "No code sample available for #{slug}, no documentation will be generated."
|
63
|
+
next
|
64
|
+
end
|
65
|
+
|
66
|
+
target_file_name = slug + ".#{options[:format]}"
|
67
|
+
|
68
|
+
begin
|
69
|
+
doc = Omnitest::DocumentationGenerator.new.code2doc(source_file)
|
70
|
+
create_file(target_file_name, doc)
|
71
|
+
rescue Omnitest::Psychic::Code2Doc::CommentStyles::UnknownStyleError
|
72
|
+
warn "Could not generated documentation for #{source_file}, because the language couldn't be detected."
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|