polytrix 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop-todo.yml +14 -5
- data/Gemfile +2 -1
- data/README.md +139 -177
- data/Rakefile +5 -12
- data/bin/polytrix +0 -1
- data/features/bootstrapping.feature +0 -3
- data/features/cloning.feature +0 -3
- data/features/show.feature +38 -0
- data/features/states.feature +12 -13
- data/features/step_definitions/sdk_steps.rb +0 -4
- data/lib/polytrix/challenge.rb +135 -53
- data/lib/polytrix/challenge_result.rb +0 -2
- data/lib/polytrix/challenge_runner.rb +28 -18
- data/lib/polytrix/cli.rb +53 -69
- data/lib/polytrix/color.rb +2 -2
- data/lib/polytrix/command/action.rb +4 -3
- data/lib/polytrix/command/list.rb +39 -28
- data/lib/polytrix/command/report.rb +9 -86
- data/lib/polytrix/command/reports/code2doc.rb +72 -0
- data/lib/polytrix/command/reports/dashboard.rb +125 -0
- data/lib/polytrix/command/show.rb +148 -0
- data/lib/polytrix/command.rb +37 -104
- data/lib/polytrix/configuration.rb +14 -18
- data/lib/polytrix/{core/hashie.rb → dash.rb} +4 -3
- data/lib/polytrix/documentation/code_segmenter.rb +8 -8
- data/lib/polytrix/documentation/comment_styles.rb +1 -1
- data/lib/polytrix/documentation/helpers/code_helper.rb +9 -0
- data/lib/polytrix/documentation_generator.rb +11 -14
- data/lib/polytrix/error.rb +104 -97
- data/lib/polytrix/executor.rb +33 -0
- data/lib/polytrix/{runners → executors}/buff_shellout_executor.rb +1 -1
- data/lib/polytrix/executors/linux_challenge_executor.rb +29 -0
- data/lib/polytrix/executors/mixlib_shellout_executor.rb +55 -0
- data/lib/polytrix/{runners/windows_challenge_runner.rb → executors/windows_challenge_executor.rb} +4 -11
- data/lib/polytrix/{core/implementor.rb → implementor.rb} +10 -6
- data/lib/polytrix/manifest.rb +2 -31
- data/lib/polytrix/{reports → reporters}/hash_reporter.rb +6 -2
- data/lib/polytrix/{reports → reporters}/json_reporter.rb +2 -2
- data/lib/polytrix/{reports → reporters}/markdown_reporter.rb +7 -2
- data/lib/polytrix/{reports → reporters}/yaml_reporter.rb +2 -2
- data/lib/polytrix/reporters.rb +27 -0
- data/lib/polytrix/result.rb +6 -5
- data/lib/polytrix/spies/file_system_spy.rb +15 -0
- data/lib/polytrix/spies.rb +61 -0
- data/lib/polytrix/state_file.rb +1 -20
- data/lib/polytrix/util.rb +157 -62
- data/lib/polytrix/validation.rb +41 -2
- data/lib/polytrix/validator.rb +9 -4
- data/lib/polytrix/version.rb +1 -1
- data/lib/polytrix.rb +110 -105
- data/polytrix.gemspec +7 -2
- data/polytrix.yml +16 -13
- 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 +41 -0
- data/resources/templates/dashboard/files/dashboard.html.tt +82 -0
- data/resources/templates/dashboard/templates/_test_report.html.tt +87 -0
- data/samples/bootstrap.sh +2 -0
- data/samples/clone.sh +2 -0
- data/samples/code2doc.sh +4 -0
- data/samples/docs/samples/code2doc/java/katas-hello_world-java.md +17 -0
- data/samples/docs/samples/code2doc/java/katas-quine-java.md +35 -0
- data/samples/docs/samples/code2doc/python/katas-hello_world-python.md +5 -0
- data/samples/docs/samples/code2doc/python/katas-quine-python.md +6 -0
- data/samples/docs/samples/code2doc/ruby/katas-hello_world-ruby.md +11 -0
- data/samples/exec.sh +2 -0
- data/samples/polytrix.rb +2 -2
- data/samples/polytrix.yml +5 -2
- data/samples/show.sh +4 -0
- data/samples/test.sh +2 -0
- data/samples/tests/polytrix/validators.rb +2 -2
- data/samples/verify.sh +3 -0
- data/scripts/wrapper +4 -7
- data/spec/fabricators/challenge_fabricator.rb +2 -9
- data/spec/fabricators/implementor_fabricator.rb +0 -8
- data/spec/fabricators/manifest_fabricator.rb +2 -9
- data/spec/fabricators/validator_fabricator.rb +2 -4
- data/spec/polytrix/challenge_runner_spec.rb +20 -0
- data/spec/polytrix/documentation/helpers/code_helper_spec.rb +7 -7
- data/spec/polytrix/file_finder_spec.rb +5 -5
- data/spec/polytrix/manifest_spec.rb +0 -21
- data/spec/polytrix/result_spec.rb +14 -14
- data/spec/polytrix/validator_registry_spec.rb +4 -4
- data/spec/polytrix/validator_spec.rb +9 -9
- data/spec/polytrix_spec.rb +1 -25
- data/spec/spec_helper.rb +8 -1
- metadata +130 -38
- data/features/execution.feature +0 -53
- data/features/fixtures/spec/polytrix_spec.rb +0 -7
- data/lib/polytrix/cli/report.rb +0 -84
- data/lib/polytrix/command/rundoc.rb +0 -27
- data/lib/polytrix/core/file_system_helper.rb +0 -75
- data/lib/polytrix/core/manifest_section.rb +0 -4
- data/lib/polytrix/core/string_helpers.rb +0 -15
- data/lib/polytrix/documentation/view_helper.rb +0 -21
- data/lib/polytrix/rspec/documentation_formatter.rb +0 -66
- data/lib/polytrix/rspec/yaml_report.rb +0 -51
- data/lib/polytrix/rspec.rb +0 -56
- data/lib/polytrix/runners/executor.rb +0 -34
- data/lib/polytrix/runners/linux_challenge_runner.rb +0 -23
- data/lib/polytrix/runners/middleware/change_directory.rb +0 -20
- data/lib/polytrix/runners/middleware/feature_executor.rb +0 -24
- data/lib/polytrix/runners/middleware/setup_env_vars.rb +0 -42
- data/lib/polytrix/runners/mixlib_shellout_executor.rb +0 -83
- data/lib/polytrix/validations.rb +0 -23
- data/samples/scripts/wrapper +0 -7
- data/spec/polytrix/middleware/feature_executor_spec.rb +0 -48
- data/spec/polytrix/validations_spec.rb +0 -16
@@ -1,52 +1,63 @@
|
|
1
|
+
require 'polytrix/reporters'
|
1
2
|
module Polytrix
|
2
3
|
module Command
|
3
4
|
class List < Polytrix::Command::Base
|
4
|
-
|
5
|
-
# Logging.mdc['command'] = 'list'
|
5
|
+
include Polytrix::Reporters
|
6
6
|
|
7
|
+
def call
|
7
8
|
setup
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
colorize('Suite', :green), colorize('Scenario', :green),
|
13
|
-
colorize('Implementor', :green), colorize('Status', :green)
|
14
|
-
]
|
15
|
-
]
|
9
|
+
@reporter = Polytrix::Reporters.reporter(options[:format], shell)
|
10
|
+
tests = parse_subcommand(args.pop)
|
11
|
+
|
12
|
+
table = [header_row]
|
16
13
|
table += tests.map do | challenge |
|
17
|
-
|
18
|
-
color_pad(challenge.suite),
|
19
|
-
color_pad(challenge.name),
|
20
|
-
color_pad(challenge.implementor.name),
|
21
|
-
format_last_action(challenge)
|
22
|
-
]
|
14
|
+
row(challenge)
|
23
15
|
end
|
24
|
-
|
16
|
+
print_table(table)
|
25
17
|
end
|
26
18
|
|
27
19
|
private
|
28
20
|
|
21
|
+
def header_row
|
22
|
+
row = []
|
23
|
+
row << colorize('Test ID', :green)
|
24
|
+
row << colorize('Suite', :green)
|
25
|
+
row << colorize('Scenario', :green)
|
26
|
+
row << colorize('Implementor', :green)
|
27
|
+
row << colorize('Status', :green)
|
28
|
+
row << colorize('Source', :green) if options[:source]
|
29
|
+
row
|
30
|
+
end
|
31
|
+
|
32
|
+
def row(challenge)
|
33
|
+
row = []
|
34
|
+
row << color_pad(challenge.slug)
|
35
|
+
row << color_pad(challenge.suite)
|
36
|
+
row << color_pad(challenge.name)
|
37
|
+
row << color_pad(challenge.implementor.name)
|
38
|
+
row << format_status(challenge)
|
39
|
+
if options[:source]
|
40
|
+
source_file = challenge.absolute_source_file ? relativize(challenge.absolute_source_file, Dir.pwd) : colorize('<No code sample>', :red)
|
41
|
+
row << source_file
|
42
|
+
end
|
43
|
+
row
|
44
|
+
end
|
45
|
+
|
29
46
|
def print_table(*args)
|
30
|
-
|
47
|
+
@reporter.print_table(*args)
|
31
48
|
end
|
32
49
|
|
33
50
|
def colorize(string, *args)
|
34
|
-
|
51
|
+
return string unless @reporter.respond_to? :set_color
|
52
|
+
@reporter.set_color(string, *args)
|
35
53
|
end
|
36
54
|
|
37
55
|
def color_pad(string)
|
38
56
|
string + colorize('', :white)
|
39
57
|
end
|
40
58
|
|
41
|
-
def
|
42
|
-
|
43
|
-
when 'clone' then colorize('Cloned', :cyan)
|
44
|
-
when 'bootstrap' then colorize('Bootstrapped', :magenta)
|
45
|
-
when 'exec' then colorize('Executed', :blue)
|
46
|
-
when 'verify' then colorize("Verified (x#{challenge.validations.count})", :yellow)
|
47
|
-
when nil then colorize('<Not Found>', :red)
|
48
|
-
else colorize("<Unknown (#{challenge.last_action})>", :white)
|
49
|
-
end
|
59
|
+
def format_status(challenge)
|
60
|
+
colorize(challenge.status_description, challenge.status_color)
|
50
61
|
end
|
51
62
|
end
|
52
63
|
end
|
@@ -1,94 +1,17 @@
|
|
1
1
|
module Polytrix
|
2
|
-
module Reports
|
3
|
-
# autoload :TextReporter, 'polytrix/cli/reports/text_reporter'
|
4
|
-
autoload :MarkdownReporter, 'polytrix/cli/reports/markdown_reporter'
|
5
|
-
# autoload :HTMLReporter, 'polytrix/cli/reports/html_reporter'
|
6
|
-
autoload :JSONReporter, 'polytrix/cli/reports/json_reporter'
|
7
|
-
autoload :YAMLReporter, 'polytrix/cli/reports/yaml_reporter'
|
8
|
-
end
|
9
2
|
module Command
|
10
|
-
class Report <
|
11
|
-
|
12
|
-
fail StandardError, 'Report command not yet implemented - work in progress'
|
13
|
-
# setup
|
14
|
-
# @tests = parse_subcommand(args.first)
|
15
|
-
# tests_by_implementor = @tests.group_by(&:implementor)
|
16
|
-
|
17
|
-
# table = [
|
18
|
-
# [
|
19
|
-
# colorize('SDK', :green), colorize('Passed', :green),
|
20
|
-
# colorize('Failed', :red), colorize('Pending', :yellow),
|
21
|
-
# colorize('Skipped', :cyan)
|
22
|
-
# ]
|
23
|
-
# ]
|
24
|
-
# load_results.each do |sdk, sdk_summary|
|
25
|
-
# table << [sdk, sdk_summary[:passed], sdk_summary[:failed], sdk_summary[:pending], sdk_summary[:skipped]]
|
26
|
-
# end
|
27
|
-
# shell.print_table table
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def count(results, state)
|
33
|
-
results.count do |r|
|
34
|
-
result.last_action.to_s == state.to_s
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def load_results
|
39
|
-
result_stats = Hash.new do |hash, sdk|
|
40
|
-
hash[sdk] = { passed: 0, failed: 0, pending: 0, skipped: 0 }
|
41
|
-
end
|
42
|
-
Polytrix.manifest.suites.reduce(result_stats) do |hash, (suite_name, suite)|
|
43
|
-
suite.samples.each do |sample, suite_results|
|
44
|
-
Polytrix.implementors.map(&:name).each do |sdk|
|
45
|
-
result = Result.new(suite_results[sdk])
|
46
|
-
result.validations << Validation.new(validated_by: 'polytrix', result: 'skipped')
|
47
|
-
hash[sdk][result.status.to_sym] += 1
|
48
|
-
end
|
49
|
-
end
|
50
|
-
hash
|
51
|
-
end
|
52
|
-
result_stats
|
53
|
-
end
|
54
|
-
|
55
|
-
def reporter
|
56
|
-
@reporter ||= case options[:format]
|
57
|
-
when 'text'
|
58
|
-
self
|
59
|
-
when 'markdown'
|
60
|
-
Polytrix::CLI::Reports::MarkdownReporter.new
|
61
|
-
when 'json'
|
62
|
-
Polytrix::CLI::Reports::JSONReporter.new
|
63
|
-
when 'yaml'
|
64
|
-
Polytrix::CLI::Reports::YAMLReporter.new
|
65
|
-
else
|
66
|
-
fail "Unknown report format #{options[:format]}"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def print_table(*args)
|
71
|
-
shell.print_table(*args)
|
72
|
-
end
|
3
|
+
class Report < Thor
|
4
|
+
namespace :report
|
73
5
|
|
74
|
-
|
75
|
-
|
76
|
-
|
6
|
+
autoload :Dashboard, 'polytrix/command/reports/dashboard'
|
7
|
+
register Dashboard, 'dashboard', 'dashboard', 'Create a report dashboard'
|
8
|
+
tasks['dashboard'].options = Dashboard.class_options
|
77
9
|
|
78
|
-
|
79
|
-
|
80
|
-
|
10
|
+
autoload :Code2Doc, 'polytrix/command/reports/code2doc'
|
11
|
+
register Code2Doc, 'code2doc', 'code2doc [INSTANCE|REGEXP|all]', 'Generates documenation from sample code for one or more scenarios'
|
12
|
+
tasks['code2doc'].options = Code2Doc.class_options
|
81
13
|
|
82
|
-
|
83
|
-
case challenge.last_action
|
84
|
-
when 'clone' then colorize('Cloned', :cyan)
|
85
|
-
when 'bootstrap' then colorize('Bootstrapped', :magenta)
|
86
|
-
when 'exec' then colorize('Executed', :blue)
|
87
|
-
when 'verify' then colorize("Verified (Level #{challenge.verification_level})", :yellow)
|
88
|
-
when nil then colorize('<Not Found>', :red)
|
89
|
-
else colorize("<Unknown (#{challenge.last_action})>", :white)
|
90
|
-
end
|
91
|
-
end
|
14
|
+
# FIXME: Help shows unwanted usage, e.g. "polytrix polytrix:command:report:code2_doc"
|
92
15
|
end
|
93
16
|
end
|
94
17
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'polytrix/reporters'
|
3
|
+
|
4
|
+
module Polytrix
|
5
|
+
module Command
|
6
|
+
class Report
|
7
|
+
class Code2Doc < Thor::Group
|
8
|
+
include Polytrix::DefaultLogger
|
9
|
+
include Polytrix::Logging
|
10
|
+
include Thor::Actions
|
11
|
+
include Polytrix::Util::FileSystem
|
12
|
+
|
13
|
+
class_option :log_level,
|
14
|
+
aliases: '-l',
|
15
|
+
desc: 'Set the log level (debug, info, warn, error, fatal)'
|
16
|
+
class_option :manifest,
|
17
|
+
aliases: '-m',
|
18
|
+
desc: 'The Polytrix test manifest file location',
|
19
|
+
default: 'polytrix.yml'
|
20
|
+
class_option :solo,
|
21
|
+
desc: 'Enable solo mode - Polytrix will auto-configure a single implementor and its scenarios'
|
22
|
+
# , default: 'polytrix.yml'
|
23
|
+
class_option :solo_glob,
|
24
|
+
desc: 'The globbing pattern to find code samples in solo mode'
|
25
|
+
class_option :format,
|
26
|
+
aliases: '-f',
|
27
|
+
enum: %w(md rst),
|
28
|
+
default: 'md',
|
29
|
+
desc: 'Target documentation format'
|
30
|
+
class_option :target_dir,
|
31
|
+
aliases: '-d',
|
32
|
+
default: 'docs/',
|
33
|
+
desc: 'The target directory where documentation for generated documentation.'
|
34
|
+
|
35
|
+
class_option :destination, default: 'docs/'
|
36
|
+
|
37
|
+
def setup
|
38
|
+
# HACK: Need to make Command setup/parse_subcommand easily re-usable in Thor::Group actions
|
39
|
+
command_options = {
|
40
|
+
shell: shell
|
41
|
+
}.merge(options)
|
42
|
+
command = Polytrix::Command::Base.new(args, options, command_options)
|
43
|
+
command.send(:setup)
|
44
|
+
@scenarios = command.send(:parse_subcommand, args.pop)
|
45
|
+
end
|
46
|
+
|
47
|
+
def set_destination_root
|
48
|
+
self.destination_root = options[:destination]
|
49
|
+
end
|
50
|
+
|
51
|
+
def code2doc
|
52
|
+
@scenarios.each do | scenario |
|
53
|
+
source_file = scenario.source_file
|
54
|
+
if source_file.nil?
|
55
|
+
warn "No code sample available for #{scenario.slug}, no documentation will be generated."
|
56
|
+
next
|
57
|
+
end
|
58
|
+
|
59
|
+
target_file_name = scenario.slug + ".#{options[:format]}"
|
60
|
+
|
61
|
+
begin
|
62
|
+
doc = Polytrix::DocumentationGenerator.new.code2doc(scenario.absolute_source_file)
|
63
|
+
create_file(target_file_name, doc)
|
64
|
+
rescue Polytrix::Documentation::CommentStyles::UnknownStyleError
|
65
|
+
warn "Could not generated documentation for #{source_file}, because the language couldn't be detected."
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'polytrix/reporters'
|
3
|
+
|
4
|
+
module Polytrix
|
5
|
+
module Command
|
6
|
+
class Report
|
7
|
+
class Dashboard < Thor::Group
|
8
|
+
include Thor::Actions
|
9
|
+
include Polytrix::Util::FileSystem
|
10
|
+
module Helpers
|
11
|
+
include Polytrix::Util::String
|
12
|
+
include Padrino::Helpers::TagHelpers
|
13
|
+
include Padrino::Helpers::OutputHelpers
|
14
|
+
include Padrino::Helpers::AssetTagHelpers
|
15
|
+
|
16
|
+
def implementors
|
17
|
+
Polytrix.implementors.map do |implementor|
|
18
|
+
slugify(implementor.name)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def results
|
23
|
+
manifest = Polytrix.manifest
|
24
|
+
rows = []
|
25
|
+
grouped_challenges = manifest.challenges.values.group_by { |challenge| [challenge.suite, challenge.name] }
|
26
|
+
grouped_challenges.each do |(suite, name), challenges|
|
27
|
+
row = {
|
28
|
+
slug_prefix: slugify(suite, name),
|
29
|
+
suite: suite,
|
30
|
+
scenario: name
|
31
|
+
}
|
32
|
+
Polytrix.implementors.each do |implementor|
|
33
|
+
challenge = challenges.find { |c| c.implementor == implementor }
|
34
|
+
row[slugify(implementor.name)] = challenge.status_description
|
35
|
+
end
|
36
|
+
rows << row
|
37
|
+
end
|
38
|
+
rows
|
39
|
+
end
|
40
|
+
|
41
|
+
def as_json(table)
|
42
|
+
JSON.dump(table)
|
43
|
+
end
|
44
|
+
|
45
|
+
def status(status, msg = nil, _color = :cyan)
|
46
|
+
"<strong>#{status}</strong> <em>#{msg}</em>"
|
47
|
+
end
|
48
|
+
|
49
|
+
def bootstrap_color(color)
|
50
|
+
bootstrap_classes = {
|
51
|
+
green: 'success',
|
52
|
+
cyan: 'primary',
|
53
|
+
red: 'danger',
|
54
|
+
yellow: 'warning'
|
55
|
+
}
|
56
|
+
bootstrap_classes.key?(color) ? bootstrap_classes[color] : color
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
include Helpers
|
61
|
+
|
62
|
+
class_option :destination, default: 'reports/'
|
63
|
+
class_option :code_style, default: 'github'
|
64
|
+
|
65
|
+
def self.source_root
|
66
|
+
Polytrix::Reporters::TEMPLATE_DIR
|
67
|
+
end
|
68
|
+
|
69
|
+
def report_name
|
70
|
+
@report_name ||= self.class.name.downcase.split('::').last
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_framework_to_source_root
|
74
|
+
source_paths.map do | path |
|
75
|
+
path << "/#{report_name}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def set_destination_root
|
80
|
+
self.destination_root = options[:destination]
|
81
|
+
end
|
82
|
+
|
83
|
+
# def load_helpers
|
84
|
+
# framework_root = source_paths.first
|
85
|
+
# Dir["#{report_name}/helpers/**/*.rb"].each do |helper|
|
86
|
+
# load helper
|
87
|
+
# end
|
88
|
+
# end
|
89
|
+
|
90
|
+
def setup
|
91
|
+
Polytrix.manifest.build_challenges
|
92
|
+
test_dir = 'tests/polytrix' # @test_dir.nil? ? nil : File.expand_path(@test_dir)
|
93
|
+
return nil unless test_dir && File.directory?(test_dir)
|
94
|
+
|
95
|
+
$LOAD_PATH.unshift test_dir
|
96
|
+
Dir["#{test_dir}/**/*.rb"].each do | file_to_require |
|
97
|
+
require relativize(file_to_require, test_dir).to_s.gsub('.rb', '')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def copy_assets
|
102
|
+
directory Polytrix::Reporters::ASSETS_DIR, 'assets'
|
103
|
+
end
|
104
|
+
|
105
|
+
def copy_base_structure
|
106
|
+
directory 'files', '.'
|
107
|
+
end
|
108
|
+
|
109
|
+
def create_test_reports
|
110
|
+
Polytrix.manifest.challenges.values.each do |challenge|
|
111
|
+
@challenge = challenge
|
112
|
+
template 'templates/_test_report.html.tt', "details/#{challenge.slug}.html"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def create_spy_reports
|
117
|
+
reports = Polytrix::Spies.reports[:dashboard]
|
118
|
+
reports.each do | report_class |
|
119
|
+
invoke report_class, args, options
|
120
|
+
end if reports
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'polytrix/reporters'
|
2
|
+
|
3
|
+
module Polytrix
|
4
|
+
module Command
|
5
|
+
class Show < Polytrix::Command::Base
|
6
|
+
include Polytrix::Reporters
|
7
|
+
include Polytrix::Util::String
|
8
|
+
include Polytrix::Util::FileSystem
|
9
|
+
|
10
|
+
def initialize(cmd_args, cmd_options, options = {})
|
11
|
+
@indent_level = 0
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
setup
|
17
|
+
@reporter = Polytrix::Reporters.reporter(options[:format], shell)
|
18
|
+
challenges = parse_subcommand(args.pop)
|
19
|
+
|
20
|
+
challenges.each do | challenge |
|
21
|
+
status_color = challenge.status_color.to_sym
|
22
|
+
status(challenge.slug, colorize(challenge.status_description, status_color), status_color)
|
23
|
+
indent do
|
24
|
+
status('Test suite', challenge.suite)
|
25
|
+
status('Test scenario', challenge.name)
|
26
|
+
status('Implementor', challenge.implementor.name)
|
27
|
+
source_file = challenge.absolute_source_file ? relativize(challenge.absolute_source_file, Dir.pwd) : colorize('<No code sample>', :red)
|
28
|
+
status('Source', source_file)
|
29
|
+
display_source(challenge)
|
30
|
+
display_execution_result(challenge)
|
31
|
+
display_validations(challenge)
|
32
|
+
display_spy_data(challenge)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def reformat(string)
|
40
|
+
return if string.nil? || string.empty?
|
41
|
+
|
42
|
+
indent do
|
43
|
+
string.gsub(/^/, indent)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def indent
|
48
|
+
if block_given?
|
49
|
+
@indent_level += 2
|
50
|
+
result = yield
|
51
|
+
@indent_level -= 2
|
52
|
+
result
|
53
|
+
else
|
54
|
+
' ' * @indent_level
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def display_source(test)
|
59
|
+
return if !options[:source] || !test.source?
|
60
|
+
|
61
|
+
shell.say test.highlighted_code
|
62
|
+
end
|
63
|
+
|
64
|
+
def display_execution_result(test)
|
65
|
+
return if test.result.nil? || test.result.execution_result.nil?
|
66
|
+
|
67
|
+
execution_result = test.result.execution_result
|
68
|
+
status 'Execution result'
|
69
|
+
indent do
|
70
|
+
status('Exit Status', execution_result.exitstatus)
|
71
|
+
status 'Stdout'
|
72
|
+
say reformat(execution_result.stdout)
|
73
|
+
status 'Stderr'
|
74
|
+
say reformat(execution_result.stderr)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def display_validations(test)
|
79
|
+
return if test.validations.nil?
|
80
|
+
|
81
|
+
status 'Validations'
|
82
|
+
indent do
|
83
|
+
test.validations.each do | name, validation |
|
84
|
+
status(name, indicator(validation))
|
85
|
+
indent do
|
86
|
+
status 'Error message', validation.error if validation.error
|
87
|
+
unless !options[:source] || !validation.error_source?
|
88
|
+
status 'Validator source'
|
89
|
+
say highlight(validation.error_source, language: 'ruby')
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def display_spy_data(test)
|
97
|
+
return if test.spy_data.nil?
|
98
|
+
|
99
|
+
status 'Data from spies'
|
100
|
+
indent do
|
101
|
+
test.spy_data.each do |_spy, data|
|
102
|
+
indent do
|
103
|
+
data.each_pair do |k, v|
|
104
|
+
status(k, v)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def say(msg)
|
112
|
+
shell.say msg if msg
|
113
|
+
end
|
114
|
+
|
115
|
+
def status(status, msg = nil, color = :cyan, colwidth = 50)
|
116
|
+
msg = yield if block_given?
|
117
|
+
shell.say(indent)
|
118
|
+
status = shell.set_color("#{status}:", color, true)
|
119
|
+
# The built-in say_status is right-aligned, we want left-aligned
|
120
|
+
shell.say format("%-#{colwidth}s %s", status, msg).rstrip
|
121
|
+
end
|
122
|
+
|
123
|
+
def print_table(*args)
|
124
|
+
@reporter.print_table(*args)
|
125
|
+
end
|
126
|
+
|
127
|
+
def colorize(string, *args)
|
128
|
+
return string unless @reporter.respond_to? :set_color
|
129
|
+
@reporter.set_color(string, *args)
|
130
|
+
end
|
131
|
+
|
132
|
+
def color_pad(string)
|
133
|
+
string + colorize('', :white)
|
134
|
+
end
|
135
|
+
|
136
|
+
def indicator(validation)
|
137
|
+
case validation.result
|
138
|
+
when :passed
|
139
|
+
colorize('✓ Passed', :green)
|
140
|
+
when :failed
|
141
|
+
colorize('x Failed', :red)
|
142
|
+
else
|
143
|
+
colorize(validation.result, :yellow)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|