polytrix 0.1.0 → 0.1.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.
- checksums.yaml +4 -4
- data/features/states.feature +1 -1
- data/lib/polytrix/challenge.rb +18 -14
- data/lib/polytrix/challenge_runner.rb +2 -2
- data/lib/polytrix/cli/report.rb +8 -8
- data/lib/polytrix/cli.rb +28 -3
- data/lib/polytrix/command/list.rb +1 -1
- data/lib/polytrix/command/report.rb +94 -0
- data/lib/polytrix/command.rb +2 -1
- data/lib/polytrix/configuration.rb +1 -1
- data/lib/polytrix/core/file_system_helper.rb +5 -2
- data/lib/polytrix/documentation_generator.rb +1 -1
- data/lib/polytrix/manifest.rb +2 -0
- data/lib/polytrix/reports/hash_reporter.rb +28 -0
- data/lib/polytrix/reports/json_reporter.rb +12 -0
- data/lib/polytrix/reports/markdown_reporter.rb +21 -0
- data/lib/polytrix/reports/yaml_reporter.rb +12 -0
- data/lib/polytrix/rspec.rb +1 -1
- data/lib/polytrix/runners/executor.rb +2 -0
- data/lib/polytrix/runners/linux_challenge_runner.rb +3 -2
- data/lib/polytrix/runners/middleware/setup_env_vars.rb +11 -9
- data/lib/polytrix/state_file.rb +1 -1
- data/lib/polytrix/validator.rb +7 -2
- data/lib/polytrix/validator_registry.rb +2 -5
- data/lib/polytrix/version.rb +1 -1
- data/lib/polytrix.rb +3 -6
- data/polytrix.gemspec +1 -1
- data/samples/polytrix.rb +3 -7
- data/samples/tests/polytrix/validators.rb +15 -0
- data/spec/fabricators/validator_fabricator.rb +3 -1
- data/spec/polytrix/validator_registry_spec.rb +2 -1
- data/spec/polytrix/validator_spec.rb +4 -4
- data/spec/polytrix_spec.rb +1 -1
- metadata +10 -9
- data/lib/polytrix/cli/add.rb +0 -67
- data/lib/polytrix/cli/reports/hash_reporter.rb +0 -30
- data/lib/polytrix/cli/reports/json_reporter.rb +0 -14
- data/lib/polytrix/cli/reports/markdown_reporter.rb +0 -23
- data/lib/polytrix/cli/reports/yaml_reporter.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7ffce1e75b5eb183162405a377b984462fc0bc9
|
4
|
+
data.tar.gz: 747e6c4a45538f02101cb551c2e8e766efd0fbfe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13df8aff0ebe16f43ad0ea00d7e77e463c2675a316a9d660c3955475ff631fb9e030f619bfe6c11ac0fb0c5844a57e366654b5c77ad32c1abb136fc66088e2a8
|
7
|
+
data.tar.gz: ac2e37d38cd6b2823d05c88199f0fc03ab55887628f9020472ca6d3bfff9bf8a2c034bb56e06f2d58b065b140efdca980fe80baa60c1316fcde1bbdf5fd88dad
|
data/features/states.feature
CHANGED
@@ -34,7 +34,7 @@ Feature: States
|
|
34
34
|
Then the output should contain:
|
35
35
|
"""
|
36
36
|
Suite Scenario Implementor Status
|
37
|
-
Katas hello world ruby Verified (
|
37
|
+
Katas hello world ruby Verified (x1)
|
38
38
|
Katas hello world java <Not Found>
|
39
39
|
Katas hello world python Executed
|
40
40
|
"""
|
data/lib/polytrix/challenge.rb
CHANGED
@@ -89,14 +89,12 @@ module Polytrix
|
|
89
89
|
end
|
90
90
|
|
91
91
|
display_file = relativize(absolute_source_file, Dir.pwd)
|
92
|
-
banner "Generating documentation from #{display_file}"
|
92
|
+
banner "Generating documentation for #{slug} from #{display_file}"
|
93
93
|
target_dir = Polytrix.configuration.documentation_dir
|
94
94
|
format = Polytrix.configuration.documentation_format
|
95
|
-
# language = options[:lang]
|
96
|
-
language = '.rb'
|
97
95
|
target_file_name = File.basename(source_file, File.extname(source_file)) + ".#{format}"
|
98
96
|
target_file = File.join(target_dir, target_file_name)
|
99
|
-
doc = Polytrix::DocumentationGenerator.new.code2doc(absolute_source_file
|
97
|
+
doc = Polytrix::DocumentationGenerator.new.code2doc(absolute_source_file)
|
100
98
|
FileUtils.mkdir_p File.dirname(target_file)
|
101
99
|
File.write(target_file, doc)
|
102
100
|
info "Documentated saved to #{target_file}"
|
@@ -106,19 +104,21 @@ module Polytrix
|
|
106
104
|
|
107
105
|
def destroy_action
|
108
106
|
perform_action(:destroy, 'Destroying') do
|
109
|
-
|
110
|
-
|
107
|
+
@state_file.destroy
|
108
|
+
@state_file = nil
|
109
|
+
@validations = nil
|
110
|
+
@state = {}
|
111
111
|
end
|
112
|
-
@state_file.destroy
|
113
|
-
@state_file = nil
|
114
112
|
end
|
115
113
|
|
116
114
|
def verify_action
|
117
115
|
perform_action(:verify, 'Verifying') do
|
118
116
|
validators = Polytrix::ValidatorRegistry.validators_for self
|
119
117
|
validators.each do |validator|
|
120
|
-
validator.validate
|
118
|
+
validator.validate(self)
|
119
|
+
validations << validator.description
|
121
120
|
end
|
121
|
+
@state['validations'] = validations
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
@@ -133,12 +133,12 @@ module Polytrix
|
|
133
133
|
end
|
134
134
|
|
135
135
|
def action(what, &block)
|
136
|
-
state = state_file.read
|
136
|
+
@state = state_file.read
|
137
137
|
elapsed = Benchmark.measure do
|
138
|
-
# synchronize_or_call(what, state, &block)
|
139
|
-
block.call(state)
|
138
|
+
# synchronize_or_call(what, @state, &block)
|
139
|
+
block.call(@state)
|
140
140
|
end
|
141
|
-
state['last_action'] = what.to_s
|
141
|
+
@state['last_action'] = what.to_s
|
142
142
|
elapsed
|
143
143
|
rescue Polytrix::FeatureNotImplementedError => e
|
144
144
|
raise e
|
@@ -152,7 +152,7 @@ module Polytrix
|
|
152
152
|
fail ActionFailed,
|
153
153
|
"Failed to complete ##{what} action: [#{e.message}]", e.backtrace
|
154
154
|
ensure
|
155
|
-
state_file.write(state)
|
155
|
+
state_file.write(@state) unless what == :destroy
|
156
156
|
end
|
157
157
|
|
158
158
|
# Returns the last successfully completed action state of the instance.
|
@@ -162,6 +162,10 @@ module Polytrix
|
|
162
162
|
state_file.read['last_action']
|
163
163
|
end
|
164
164
|
|
165
|
+
def validations
|
166
|
+
@validations ||= (state_file.read['validations'] || [])
|
167
|
+
end
|
168
|
+
|
165
169
|
def transition_to(desired)
|
166
170
|
transition_result = nil
|
167
171
|
begin
|
@@ -11,6 +11,8 @@ module Polytrix
|
|
11
11
|
include Polytrix::Core::FileSystemHelper
|
12
12
|
include Polytrix::Runners::Executor
|
13
13
|
|
14
|
+
attr_accessor :env
|
15
|
+
|
14
16
|
def self.create_runner
|
15
17
|
case RbConfig::CONFIG['host_os']
|
16
18
|
when /mswin(\d+)|mingw/i
|
@@ -30,8 +32,6 @@ module Polytrix
|
|
30
32
|
end
|
31
33
|
|
32
34
|
def run_challenge(challenge)
|
33
|
-
# Logging.mdc['implementor'] = "\033[35m#{challenge.implementor.name}\033[0m"
|
34
|
-
# Logging.mdc['scenario'] = "\033[32m#{challenge.name}\033[0m"
|
35
35
|
middleware.call(challenge)
|
36
36
|
challenge.result
|
37
37
|
end
|
data/lib/polytrix/cli/report.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
module Polytrix
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
+
module Command
|
10
10
|
class Report < Polytrix::CLI::Base
|
11
11
|
# class_options = super.class_options
|
12
12
|
class_option :format, desc: 'Output format for the report', default: 'text', enum: %w(text markdown json yaml)
|
data/lib/polytrix/cli.rb
CHANGED
@@ -45,7 +45,6 @@ module Polytrix
|
|
45
45
|
def initialize(*args)
|
46
46
|
super
|
47
47
|
$stdout.sync = true
|
48
|
-
# Polytrix.logger = Polytrix.default_file_logger
|
49
48
|
end
|
50
49
|
|
51
50
|
desc 'list [INSTANCE|REGEXP|all]', 'Lists one or more scenarios'
|
@@ -74,6 +73,32 @@ module Polytrix
|
|
74
73
|
perform('list', 'list', args, options)
|
75
74
|
end
|
76
75
|
|
76
|
+
desc 'report [INSTANCE|REGEXP|all]', 'Summary report for one or more scenarios'
|
77
|
+
method_option :bare,
|
78
|
+
aliases: '-b',
|
79
|
+
type: :boolean,
|
80
|
+
desc: 'List the name of each scenario only, one per line'
|
81
|
+
method_option :log_level,
|
82
|
+
aliases: '-l',
|
83
|
+
desc: 'Set the log level (debug, info, warn, error, fatal)'
|
84
|
+
method_option :manifest,
|
85
|
+
aliases: '-m',
|
86
|
+
desc: 'The Polytrix test manifest file location',
|
87
|
+
default: 'polytrix.yml'
|
88
|
+
method_option :test_dir,
|
89
|
+
aliases: '-t',
|
90
|
+
desc: 'The Polytrix test directory',
|
91
|
+
default: 'tests/polytrix'
|
92
|
+
method_option :solo,
|
93
|
+
desc: 'Enable solo mode - Polytrix will auto-configure a single implementor and its scenarios'
|
94
|
+
# , default: 'polytrix.yml'
|
95
|
+
method_option :solo_glob,
|
96
|
+
desc: 'The globbing pattern to find code samples in solo mode'
|
97
|
+
def report(*args)
|
98
|
+
update_config!
|
99
|
+
perform('report', 'report', args, options)
|
100
|
+
end
|
101
|
+
|
77
102
|
{
|
78
103
|
clone: "Change scenario state to cloned. " \
|
79
104
|
"Clone the code sample from git",
|
@@ -202,7 +227,7 @@ module Polytrix
|
|
202
227
|
end
|
203
228
|
map %w[-v --version] => :version
|
204
229
|
|
205
|
-
# register Polytrix::
|
230
|
+
# register Polytrix::CLI::Report, "init",
|
206
231
|
# "init", "Adds some configuration to your cookbook so Polytrix can rock"
|
207
232
|
# long_desc <<-D, :for => "init"
|
208
233
|
# Init will add Test Polytrix support to an existing project for
|
@@ -210,7 +235,7 @@ module Polytrix
|
|
210
235
|
# intended to be customized) is created in the project's root directory
|
211
236
|
# and one or more gems will be added to the project's Gemfile.
|
212
237
|
# D
|
213
|
-
# tasks["init"].options = Polytrix::
|
238
|
+
# tasks["init"].options = Polytrix::CLI::Report.class_options
|
214
239
|
|
215
240
|
private
|
216
241
|
|
@@ -43,7 +43,7 @@ module Polytrix
|
|
43
43
|
when 'clone' then colorize('Cloned', :cyan)
|
44
44
|
when 'bootstrap' then colorize('Bootstrapped', :magenta)
|
45
45
|
when 'exec' then colorize('Executed', :blue)
|
46
|
-
when 'verify' then colorize("Verified (
|
46
|
+
when 'verify' then colorize("Verified (x#{challenge.validations.count})", :yellow)
|
47
47
|
when nil then colorize('<Not Found>', :red)
|
48
48
|
else colorize("<Unknown (#{challenge.last_action})>", :white)
|
49
49
|
end
|
@@ -0,0 +1,94 @@
|
|
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
|
+
module Command
|
10
|
+
class Report < Polytrix::Command::Base
|
11
|
+
def call
|
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
|
73
|
+
|
74
|
+
def colorize(string, *args)
|
75
|
+
shell.set_color(string, *args)
|
76
|
+
end
|
77
|
+
|
78
|
+
def color_pad(string)
|
79
|
+
string + colorize('', :white)
|
80
|
+
end
|
81
|
+
|
82
|
+
def format_last_action(challenge)
|
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
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/polytrix/command.rb
CHANGED
@@ -87,10 +87,11 @@ module Polytrix
|
|
87
87
|
def solo_setup
|
88
88
|
suites = {}
|
89
89
|
solo_basedir = @options.solo
|
90
|
-
solo_glob = @options.fetch(
|
90
|
+
solo_glob = @options.fetch('solo_glob', "**/*.{#{SUPPORTED_EXTENSIONS.join(',')}}")
|
91
91
|
Dir[File.join(solo_basedir, solo_glob)].each do | code_sample |
|
92
92
|
code_sample = Pathname.new(code_sample)
|
93
93
|
suite_name = relativize(code_sample.dirname, solo_basedir).to_s
|
94
|
+
suite_name = solo_basedir if suite_name == '.'
|
94
95
|
scenario_name = code_sample.basename(code_sample.extname).to_s
|
95
96
|
suite = suites[suite_name] ||= Polytrix::Manifest::Suite.new(samples: [])
|
96
97
|
suite.samples << scenario_name
|
@@ -61,7 +61,7 @@ module Polytrix
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def default_validator
|
64
|
-
@default_validator ||= Validator.new(suite: //, scenario: //, &default_validator_callback)
|
64
|
+
@default_validator ||= Validator.new('default validator', suite: //, scenario: //, &default_validator_callback)
|
65
65
|
end
|
66
66
|
|
67
67
|
attr_writer :default_validator_callback
|
@@ -12,11 +12,14 @@ module Polytrix
|
|
12
12
|
potential_files.concat Dir.glob(glob_string.gsub('_', '-'), File::FNM_CASEFOLD)
|
13
13
|
potential_files.concat Dir.glob(glob_string.gsub('_', ''), File::FNM_CASEFOLD)
|
14
14
|
|
15
|
-
#
|
16
|
-
|
15
|
+
# Filter out ignored filesFind the first file, not including generated files
|
16
|
+
files = potential_files.select do |f|
|
17
17
|
!ignored? ignored_patterns, search_path, f
|
18
18
|
end
|
19
19
|
|
20
|
+
# Select the shortest path, likely the best match
|
21
|
+
file = files.min_by(&:length)
|
22
|
+
|
20
23
|
fail FileNotFound, "No file was found for #{scenario_name} within #{search_path}" if file.nil?
|
21
24
|
Pathname.new file
|
22
25
|
end
|
@@ -40,7 +40,7 @@ module Polytrix
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
def code2doc(source_file, language)
|
43
|
+
def code2doc(source_file, language = nil)
|
44
44
|
source_code = File.read(source_file)
|
45
45
|
if language.nil?
|
46
46
|
language, comment_style = Documentation::CommentStyles.infer File.extname(source_file)
|
data/lib/polytrix/manifest.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module Polytrix
|
4
|
+
module Reports
|
5
|
+
class HashReporter
|
6
|
+
def initialize(io = $stdout)
|
7
|
+
@buffer = io
|
8
|
+
end
|
9
|
+
|
10
|
+
def print_table(table)
|
11
|
+
headers = table[0]
|
12
|
+
data = []
|
13
|
+
table[1..-1].map do |row|
|
14
|
+
row_data = {}
|
15
|
+
row.each_with_index do |value, index|
|
16
|
+
row_data[headers[index]] = value
|
17
|
+
end
|
18
|
+
data << row_data
|
19
|
+
end
|
20
|
+
@buffer.puts convert(data)
|
21
|
+
end
|
22
|
+
|
23
|
+
def convert(data)
|
24
|
+
fail 'Subclass HashReporter and convert the data to the target format'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Polytrix
|
2
|
+
module Reports
|
3
|
+
class MarkdownReporter
|
4
|
+
def initialize(io = $stdout)
|
5
|
+
@buffer = io
|
6
|
+
end
|
7
|
+
|
8
|
+
def print_table(table)
|
9
|
+
@buffer.puts # Markdown tables don't always render properly without a break
|
10
|
+
header_data = table[0]
|
11
|
+
header_line = header_data.join ' | '
|
12
|
+
@buffer.puts header_line
|
13
|
+
@buffer.puts header_line.gsub(/[^|]/, '-')
|
14
|
+
|
15
|
+
table[1..-1].each do |data_line|
|
16
|
+
@buffer.puts data_line.join ' | '
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/polytrix/rspec.rb
CHANGED
@@ -19,7 +19,7 @@ module Polytrix
|
|
19
19
|
samples.each do |scenario|
|
20
20
|
describe scenario.name do
|
21
21
|
Polytrix.implementors.each do |sdk|
|
22
|
-
it sdk.name, sdk.name.to_sym => true do
|
22
|
+
it sdk.name, sdk.name.to_sym => true do | example |
|
23
23
|
begin
|
24
24
|
skip "#{sdk.name} is not setup" unless File.directory? sdk.basedir
|
25
25
|
slug = Polytrix::Challenge.slugify(suite_name, scenario.name, sdk.name)
|
@@ -15,6 +15,7 @@ module Polytrix
|
|
15
15
|
|
16
16
|
module Executor
|
17
17
|
attr_writer :executor
|
18
|
+
attr_accessor :env
|
18
19
|
|
19
20
|
def executor
|
20
21
|
@executor ||= if RUBY_PLATFORM == 'java'
|
@@ -25,6 +26,7 @@ module Polytrix
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def execute(command, opts = {})
|
29
|
+
opts[:env] = env unless env.nil?
|
28
30
|
executor.execute(command, opts)
|
29
31
|
end
|
30
32
|
end
|
@@ -8,9 +8,10 @@ module Polytrix
|
|
8
8
|
def challenge_command(env_file, challenge_script)
|
9
9
|
challenge_script = "./#{challenge_script}" unless challenge_script.to_s.start_with? '/'
|
10
10
|
if File.exist? 'scripts/wrapper'
|
11
|
-
". #{env_file} && scripts/wrapper #{challenge_script}"
|
11
|
+
# ". #{env_file} && scripts/wrapper #{challenge_script}"
|
12
|
+
"scripts/wrapper #{challenge_script}"
|
12
13
|
else
|
13
|
-
"
|
14
|
+
"#{challenge_script}"
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
@@ -18,21 +18,23 @@ module Polytrix
|
|
18
18
|
end
|
19
19
|
vars = vars.merge env[:vars].dup
|
20
20
|
|
21
|
-
|
21
|
+
setup_env_vars(env[:name], vars, env[:challenge_runner])
|
22
|
+
# env[:env_file] = setup_env_vars(env[:name], vars, env[:challenge_runner])
|
22
23
|
@app.call env
|
23
24
|
end
|
24
25
|
|
25
26
|
private
|
26
27
|
|
27
28
|
def setup_env_vars(challenge_name, vars, challenge_runner)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
file.
|
29
|
+
challenge_runner.env = vars.to_hash
|
30
|
+
# FileUtils.mkdir_p 'tmp'
|
31
|
+
# extension = challenge_runner.script_extension
|
32
|
+
# file = File.open(slugify("tmp/#{challenge_name}_vars.#{extension}"), 'w')
|
33
|
+
# vars.each do |key, value|
|
34
|
+
# file.puts challenge_runner.save_environment_variable(key, value)
|
35
|
+
# end
|
36
|
+
# file.close
|
37
|
+
# file.path
|
36
38
|
end
|
37
39
|
end
|
38
40
|
end
|
data/lib/polytrix/state_file.rb
CHANGED
data/lib/polytrix/validator.rb
CHANGED
@@ -5,9 +5,10 @@ module Polytrix
|
|
5
5
|
include RSpec::Matchers
|
6
6
|
|
7
7
|
UNIVERSAL_MATCHER = //
|
8
|
-
attr_reader :suite, :sample, :level, :callback
|
8
|
+
attr_reader :description, :suite, :sample, :level, :callback
|
9
9
|
|
10
|
-
def initialize(scope = {}, &validator)
|
10
|
+
def initialize(description, scope = {}, &validator)
|
11
|
+
@description = description
|
11
12
|
@suite = scope[:suite] ||= UNIVERSAL_MATCHER
|
12
13
|
@sample = scope[:sample] ||= UNIVERSAL_MATCHER
|
13
14
|
@callback = validator
|
@@ -20,5 +21,9 @@ module Polytrix
|
|
20
21
|
def validate(challenge)
|
21
22
|
instance_exec challenge, &@callback if should_validate?(challenge)
|
22
23
|
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
@description
|
27
|
+
end
|
23
28
|
end
|
24
29
|
end
|
@@ -13,11 +13,8 @@ module Polytrix
|
|
13
13
|
instance.validators
|
14
14
|
end
|
15
15
|
|
16
|
-
def register(validator, &callback)
|
17
|
-
if block_given?
|
18
|
-
match_rules = validator
|
19
|
-
validator = Validator.new(match_rules, &callback)
|
20
|
-
end
|
16
|
+
def register(validator, scope = {}, &callback)
|
17
|
+
validator = Validator.new(validator, scope, &callback) if block_given?
|
21
18
|
validators << validator
|
22
19
|
end
|
23
20
|
|
data/lib/polytrix/version.rb
CHANGED
data/lib/polytrix.rb
CHANGED
@@ -101,12 +101,9 @@ module Polytrix
|
|
101
101
|
|
102
102
|
# Registers a {Polytrix::Validator} that will be used during test
|
103
103
|
# execution on matching {Polytrix::Challenge}s.
|
104
|
-
def validate(scope = { suite: //, sample: // },
|
105
|
-
|
106
|
-
|
107
|
-
elsif validator.nil?
|
108
|
-
fail ArgumentError 'You must a block or a Validator as the second argument'
|
109
|
-
end
|
104
|
+
def validate(desc, scope = { suite: //, sample: // }, &block)
|
105
|
+
fail ArgumentError 'You must pass block' unless block_given?
|
106
|
+
validator = Polytrix::Validator.new(desc, scope, &block)
|
110
107
|
|
111
108
|
Polytrix::ValidatorRegistry.register validator
|
112
109
|
validator
|
data/polytrix.gemspec
CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_dependency "mixlib-shellout", "~> 1.3" # Used for MRI
|
24
24
|
spec.add_dependency "buff-shell_out", "~> 0.1" # Used for JRuby
|
25
25
|
spec.add_dependency "middleware", "~> 0.1"
|
26
|
-
spec.add_dependency "rspec", "~>
|
26
|
+
spec.add_dependency "rspec", "~> 3.0"
|
27
27
|
spec.add_dependency "hashie", "~> 3.0"
|
28
28
|
spec.add_dependency "padrino-helpers", "~> 0.12"
|
29
29
|
spec.add_development_dependency "bundler", "~> 1.5"
|
data/samples/polytrix.rb
CHANGED
@@ -1,18 +1,14 @@
|
|
1
1
|
require 'polytrix'
|
2
2
|
|
3
|
-
|
4
|
-
c.expose_current_running_example_as :example
|
5
|
-
end
|
6
|
-
|
7
|
-
Polytrix.validate suite: 'Katas', sample: 'hello world' do |challenge|
|
3
|
+
Polytrix.validate 'Hello world validator', suite: 'Katas', sample: 'hello world' do |challenge|
|
8
4
|
expect(challenge.result.stdout).to eq "Hello, world!\n"
|
9
5
|
end
|
10
6
|
|
11
|
-
Polytrix.validate suite: 'Katas', sample: 'quine' do |challenge|
|
7
|
+
Polytrix.validate 'Quine output matches source code', suite: 'Katas', sample: 'quine' do |challenge|
|
12
8
|
expect(challenge.result.stdout).to eq(challenge.source)
|
13
9
|
end
|
14
10
|
|
15
|
-
Polytrix.validate do |challenge|
|
11
|
+
Polytrix.validate 'default validator' do |challenge|
|
16
12
|
expect(challenge.result.exitstatus).to eq(0)
|
17
13
|
expect(challenge.result.stderr).to be_empty
|
18
14
|
expect(challenge.result.stdout).to end_with "\n"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'polytrix'
|
2
|
+
|
3
|
+
Polytrix.validate 'Hello world validator', suite: 'Katas', sample: 'hello world' do |challenge|
|
4
|
+
expect(challenge.result.stdout).to eq "Hello, world!\n"
|
5
|
+
end
|
6
|
+
|
7
|
+
Polytrix.validate 'Quine output matches source code', suite: 'Katas', sample: 'quine' do |challenge|
|
8
|
+
expect(challenge.result.stdout).to eq(challenge.source)
|
9
|
+
end
|
10
|
+
|
11
|
+
Polytrix.validate 'default validator' do |challenge|
|
12
|
+
expect(challenge.result.exitstatus).to eq(0)
|
13
|
+
expect(challenge.result.stderr).to be_empty
|
14
|
+
expect(challenge.result.stdout).to end_with "\n"
|
15
|
+
end
|
@@ -3,9 +3,11 @@ require 'hashie/mash'
|
|
3
3
|
Fabricator(:validator, from: Polytrix::Validator) do
|
4
4
|
initialize_with do
|
5
5
|
callback = @_transient_attributes.delete :callback
|
6
|
+
desc = @_transient_attributes.delete :description
|
6
7
|
scope = @_transient_attributes
|
7
|
-
@_klass.new(scope, &callback)
|
8
|
+
@_klass.new(desc, scope, &callback)
|
8
9
|
end # Hash based initialization
|
10
|
+
transient description: 'Sample validator'
|
9
11
|
transient suite: LANGUAGES.sample
|
10
12
|
transient sample: SAMPLE_NAMES.sample
|
11
13
|
transient callback: Proc.new { Proc.new { |challenge| } } # rubocop:disable Proc
|
@@ -5,11 +5,12 @@ module Polytrix
|
|
5
5
|
describe '#register' do
|
6
6
|
it 'registers a validator' do
|
7
7
|
callback = proc do |challenge|
|
8
|
+
expect(challenge[:result]).to_not be_nil
|
8
9
|
expect(challenge[:result].execution_result.exitstatus).to eq(0)
|
9
10
|
end
|
10
11
|
|
11
12
|
expect(registry.validators).to be_empty
|
12
|
-
registry.register suite: 'java', sample: 'hello world', &callback
|
13
|
+
registry.register(Validator.new('dummy', suite: 'java', sample: 'hello world', &callback))
|
13
14
|
validator = registry.validators.first
|
14
15
|
expect(validator.suite).to eql('java')
|
15
16
|
expect(validator.sample).to eql('hello world')
|
@@ -6,14 +6,14 @@ module Polytrix
|
|
6
6
|
let(:global_matcher) { Validator::UNIVERSAL_MATCHER }
|
7
7
|
|
8
8
|
it 'accepts scope options and callback' do
|
9
|
-
validator = Validator.new suite: 'java', sample: 'hello world' do |challenge|
|
9
|
+
validator = Validator.new 'dummy', suite: 'java', sample: 'hello world' do |challenge|
|
10
10
|
# Validate the challenge
|
11
11
|
end
|
12
12
|
expect(validator.suite).to eq('java')
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'defaults suite and sample to the universal matcher' do
|
16
|
-
validator = Validator.new do |challenge|
|
16
|
+
validator = Validator.new 'dummy' do |challenge|
|
17
17
|
# Validate
|
18
18
|
end
|
19
19
|
expect(validator.suite).to eq(Validator::UNIVERSAL_MATCHER)
|
@@ -44,7 +44,7 @@ module Polytrix
|
|
44
44
|
|
45
45
|
xit 'calls the validation callback' do
|
46
46
|
called = false
|
47
|
-
validator = Validator.new do |challenge|
|
47
|
+
validator = Validator.new 'dummy' do |challenge|
|
48
48
|
called = true
|
49
49
|
end
|
50
50
|
expect { validator.validate challenge }.to change { called }.from(false).to(true)
|
@@ -55,7 +55,7 @@ module Polytrix
|
|
55
55
|
scope = {}
|
56
56
|
scope[:suite] = args[0]
|
57
57
|
scope[:sample] = args[1] if args[1]
|
58
|
-
Validator.new scope do |challenge|
|
58
|
+
Validator.new 'dummy', scope do |challenge|
|
59
59
|
# Dummy validator
|
60
60
|
end
|
61
61
|
end
|
data/spec/polytrix_spec.rb
CHANGED
@@ -28,7 +28,7 @@ describe Polytrix do
|
|
28
28
|
describe '.validate' do
|
29
29
|
context 'block given' do
|
30
30
|
it 'creates and registers a validator' do
|
31
|
-
Polytrix.validate suite: 'test', sample: 'test' do |challenge|
|
31
|
+
Polytrix.validate 'custom validator', suite: 'test', sample: 'test' do |challenge|
|
32
32
|
# Validate the challenge results
|
33
33
|
end
|
34
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polytrix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Max Lincoln
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '3.0'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '3.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: hashie
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -234,16 +234,12 @@ files:
|
|
234
234
|
- lib/polytrix/challenge_runner.rb
|
235
235
|
- lib/polytrix/challenges.rb
|
236
236
|
- lib/polytrix/cli.rb
|
237
|
-
- lib/polytrix/cli/add.rb
|
238
237
|
- lib/polytrix/cli/report.rb
|
239
|
-
- lib/polytrix/cli/reports/hash_reporter.rb
|
240
|
-
- lib/polytrix/cli/reports/json_reporter.rb
|
241
|
-
- lib/polytrix/cli/reports/markdown_reporter.rb
|
242
|
-
- lib/polytrix/cli/reports/yaml_reporter.rb
|
243
238
|
- lib/polytrix/color.rb
|
244
239
|
- lib/polytrix/command.rb
|
245
240
|
- lib/polytrix/command/action.rb
|
246
241
|
- lib/polytrix/command/list.rb
|
242
|
+
- lib/polytrix/command/report.rb
|
247
243
|
- lib/polytrix/command/rundoc.rb
|
248
244
|
- lib/polytrix/command/test.rb
|
249
245
|
- lib/polytrix/configuration.rb
|
@@ -261,6 +257,10 @@ files:
|
|
261
257
|
- lib/polytrix/logger.rb
|
262
258
|
- lib/polytrix/logging.rb
|
263
259
|
- lib/polytrix/manifest.rb
|
260
|
+
- lib/polytrix/reports/hash_reporter.rb
|
261
|
+
- lib/polytrix/reports/json_reporter.rb
|
262
|
+
- lib/polytrix/reports/markdown_reporter.rb
|
263
|
+
- lib/polytrix/reports/yaml_reporter.rb
|
264
264
|
- lib/polytrix/result.rb
|
265
265
|
- lib/polytrix/rspec.rb
|
266
266
|
- lib/polytrix/rspec/documentation_formatter.rb
|
@@ -303,6 +303,7 @@ files:
|
|
303
303
|
- samples/sdks/python/challenges/quine.py
|
304
304
|
- samples/sdks/python/scripts/wrapper
|
305
305
|
- samples/sdks/ruby/challenges/hello_world.rb
|
306
|
+
- samples/tests/polytrix/validators.rb
|
306
307
|
- scripts/bootstrap
|
307
308
|
- scripts/wrapper
|
308
309
|
- spec/fabricators/challenge_fabricator.rb
|
data/lib/polytrix/cli/add.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
module Polytrix
|
2
|
-
module CLI
|
3
|
-
class Add < Polytrix::CLI::Base
|
4
|
-
include Thor::Actions
|
5
|
-
desc 'sample IMPLEMENTOR SCENARIO', 'Add a code sample for an implementor'
|
6
|
-
# sdk_options
|
7
|
-
method_option :language, type: 'string', desc: 'Programming language to use (if not already configured by the implementor)', default: 'rb'
|
8
|
-
def sample(implementor, scenario)
|
9
|
-
# implementor = pick_implementor(options[:sdk])
|
10
|
-
implementor = pick_implementor implementor
|
11
|
-
language = implementor.language || options[:language]
|
12
|
-
generate_source implementor, scenario, language
|
13
|
-
end
|
14
|
-
|
15
|
-
protected
|
16
|
-
|
17
|
-
source_root Polytrix.configuration.template_dir
|
18
|
-
# source_root implementor.basedir
|
19
|
-
|
20
|
-
def generate_source(implementor, scenario, language)
|
21
|
-
source_paths.prepend File.expand_path(implementor.basedir)
|
22
|
-
@implementor = implementor
|
23
|
-
@scenario = implementor.build_challenge(
|
24
|
-
name: scenario
|
25
|
-
)
|
26
|
-
@language = language
|
27
|
-
|
28
|
-
output_file = File.join(implementor.basedir, "#{scenario.gsub(' ', '_')}.#{language}")
|
29
|
-
template('code_sample.tt', output_file)
|
30
|
-
end
|
31
|
-
|
32
|
-
def commented(comment)
|
33
|
-
return if comment.nil?
|
34
|
-
|
35
|
-
buffer = StringIO.new
|
36
|
-
_lang, comment_style = Polytrix::Documentation::CommentStyles.infer @language
|
37
|
-
if use_multiline? comment, comment_style
|
38
|
-
buffer.puts comment_style[:multi][:start]
|
39
|
-
comment.lines.each do |line|
|
40
|
-
buffer.puts comment_line(line, comment_style[:multi][:middle])
|
41
|
-
end
|
42
|
-
buffer.puts comment_style[:multi][:end]
|
43
|
-
else
|
44
|
-
comment.lines.each do |line|
|
45
|
-
buffer.puts comment_line(line, comment_style[:single])
|
46
|
-
end
|
47
|
-
end
|
48
|
-
buffer.string
|
49
|
-
end
|
50
|
-
|
51
|
-
def comment_line(line, comment_string)
|
52
|
-
comment_string ||= ''
|
53
|
-
if line.strip.empty?
|
54
|
-
whitespace, line = line.gsub("\n", ''), ''
|
55
|
-
else
|
56
|
-
whitespace, line = line.rstrip.match(/([\s]*)(.*)/).captures
|
57
|
-
end
|
58
|
-
|
59
|
-
"#{whitespace}#{comment_string} #{line}"
|
60
|
-
end
|
61
|
-
|
62
|
-
def use_multiline?(comment, comment_style)
|
63
|
-
comment.lines.size > 1 && !comment_style[:multi].nil? && (comment_style[:multi][:idiomatic] != false)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'csv'
|
2
|
-
|
3
|
-
module Polytrix
|
4
|
-
module CLI
|
5
|
-
module Reports
|
6
|
-
class HashReporter
|
7
|
-
def initialize(io = $stdout)
|
8
|
-
@buffer = io
|
9
|
-
end
|
10
|
-
|
11
|
-
def print_table(table)
|
12
|
-
headers = table[0]
|
13
|
-
data = []
|
14
|
-
table[1..-1].map do |row|
|
15
|
-
row_data = {}
|
16
|
-
row.each_with_index do |value, index|
|
17
|
-
row_data[headers[index]] = value
|
18
|
-
end
|
19
|
-
data << row_data
|
20
|
-
end
|
21
|
-
@buffer.puts convert(data)
|
22
|
-
end
|
23
|
-
|
24
|
-
def convert(data)
|
25
|
-
fail 'Subclass HashReporter and convert the data to the target format'
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module Polytrix
|
2
|
-
module CLI
|
3
|
-
module Reports
|
4
|
-
class MarkdownReporter
|
5
|
-
def initialize(io = $stdout)
|
6
|
-
@buffer = io
|
7
|
-
end
|
8
|
-
|
9
|
-
def print_table(table)
|
10
|
-
@buffer.puts # Markdown tables don't always render properly without a break
|
11
|
-
header_data = table[0]
|
12
|
-
header_line = header_data.join ' | '
|
13
|
-
@buffer.puts header_line
|
14
|
-
@buffer.puts header_line.gsub(/[^|]/, '-')
|
15
|
-
|
16
|
-
table[1..-1].each do |data_line|
|
17
|
-
@buffer.puts data_line.join ' | '
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|