polytrix 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/features/states.feature +1 -1
  3. data/lib/polytrix/challenge.rb +18 -14
  4. data/lib/polytrix/challenge_runner.rb +2 -2
  5. data/lib/polytrix/cli/report.rb +8 -8
  6. data/lib/polytrix/cli.rb +28 -3
  7. data/lib/polytrix/command/list.rb +1 -1
  8. data/lib/polytrix/command/report.rb +94 -0
  9. data/lib/polytrix/command.rb +2 -1
  10. data/lib/polytrix/configuration.rb +1 -1
  11. data/lib/polytrix/core/file_system_helper.rb +5 -2
  12. data/lib/polytrix/documentation_generator.rb +1 -1
  13. data/lib/polytrix/manifest.rb +2 -0
  14. data/lib/polytrix/reports/hash_reporter.rb +28 -0
  15. data/lib/polytrix/reports/json_reporter.rb +12 -0
  16. data/lib/polytrix/reports/markdown_reporter.rb +21 -0
  17. data/lib/polytrix/reports/yaml_reporter.rb +12 -0
  18. data/lib/polytrix/rspec.rb +1 -1
  19. data/lib/polytrix/runners/executor.rb +2 -0
  20. data/lib/polytrix/runners/linux_challenge_runner.rb +3 -2
  21. data/lib/polytrix/runners/middleware/setup_env_vars.rb +11 -9
  22. data/lib/polytrix/state_file.rb +1 -1
  23. data/lib/polytrix/validator.rb +7 -2
  24. data/lib/polytrix/validator_registry.rb +2 -5
  25. data/lib/polytrix/version.rb +1 -1
  26. data/lib/polytrix.rb +3 -6
  27. data/polytrix.gemspec +1 -1
  28. data/samples/polytrix.rb +3 -7
  29. data/samples/tests/polytrix/validators.rb +15 -0
  30. data/spec/fabricators/validator_fabricator.rb +3 -1
  31. data/spec/polytrix/validator_registry_spec.rb +2 -1
  32. data/spec/polytrix/validator_spec.rb +4 -4
  33. data/spec/polytrix_spec.rb +1 -1
  34. metadata +10 -9
  35. data/lib/polytrix/cli/add.rb +0 -67
  36. data/lib/polytrix/cli/reports/hash_reporter.rb +0 -30
  37. data/lib/polytrix/cli/reports/json_reporter.rb +0 -14
  38. data/lib/polytrix/cli/reports/markdown_reporter.rb +0 -23
  39. 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: 57453fe422a3e27d1aaa87f79689d05c8aa9bcc0
4
- data.tar.gz: b3fd502c953d29fba9948eb12053b1341d1ce15b
3
+ metadata.gz: a7ffce1e75b5eb183162405a377b984462fc0bc9
4
+ data.tar.gz: 747e6c4a45538f02101cb551c2e8e766efd0fbfe
5
5
  SHA512:
6
- metadata.gz: 3ad963f3478969e5d44cfce5f10e652d94acaa488a9fe5969c377f0ca1133325c022201e211338be5d1b9917664ccdef702b307564cd9258e621d62ca26050c7
7
- data.tar.gz: 80e47b9677116fbc2652dc38a54ab0979bc11b10a00cffee865a1026a3bb1609763464a1a67d455714ec3832df1cac33f9676dbae827f309a54d1e4164900d4a
6
+ metadata.gz: 13df8aff0ebe16f43ad0ea00d7e77e463c2675a316a9d660c3955475ff631fb9e030f619bfe6c11ac0fb0c5844a57e366654b5c77ad32c1abb136fc66088e2a8
7
+ data.tar.gz: ac2e37d38cd6b2823d05c88199f0fc03ab55887628f9020472ca6d3bfff9bf8a2c034bb56e06f2d58b065b140efdca980fe80baa60c1316fcde1bbdf5fd88dad
@@ -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 (Level 0)
37
+ Katas hello world ruby Verified (x1)
38
38
  Katas hello world java <Not Found>
39
39
  Katas hello world python Executed
40
40
  """
@@ -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, language)
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
- # @state_file.destroy
110
- # @state_file = nil
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 self
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
@@ -1,12 +1,12 @@
1
1
  module Polytrix
2
- module CLI
3
- module Reports
4
- # autoload :TextReporter, 'polytrix/cli/reports/text_reporter'
5
- autoload :MarkdownReporter, 'polytrix/cli/reports/markdown_reporter'
6
- # autoload :HTMLReporter, 'polytrix/cli/reports/html_reporter'
7
- autoload :JSONReporter, 'polytrix/cli/reports/json_reporter'
8
- autoload :YAMLReporter, 'polytrix/cli/reports/yaml_reporter'
9
- end
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::Generator::Init, "init",
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::Generator::Init.class_options
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 (Level #{challenge.verification_level})", :yellow)
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
@@ -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(:solo_glob, "**/*.{#{SUPPORTED_EXTENSIONS.join(',')}}")
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
- # Find the first file, not including generated files
16
- file = potential_files.find do |f|
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)
@@ -45,6 +45,8 @@ module Polytrix
45
45
  end
46
46
 
47
47
  class Environment < Hashie::Mash
48
+ include Hashie::Extensions::Coercion
49
+ coerce_value Integer, String
48
50
  end
49
51
 
50
52
  class CodeSample < Polytrix::ManifestSection
@@ -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,12 @@
1
+ require 'json'
2
+ require 'polytrix/cli/reports/hash_reporter'
3
+
4
+ module Polytrix
5
+ module Reports
6
+ class JSONReporter < HashReporter
7
+ def convert(data)
8
+ JSON.pretty_generate data
9
+ end
10
+ end
11
+ end
12
+ 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
@@ -0,0 +1,12 @@
1
+ require 'yaml'
2
+ require 'polytrix/cli/reports/hash_reporter'
3
+
4
+ module Polytrix
5
+ module Reports
6
+ class YAMLReporter < HashReporter
7
+ def convert(data)
8
+ YAML.dump data
9
+ end
10
+ end
11
+ end
12
+ end
@@ -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
- ". #{env_file} && #{challenge_script}"
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
- env[:env_file] = setup_env_vars(env[:name], vars, env[:challenge_runner])
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
- FileUtils.mkdir_p 'tmp'
29
- extension = challenge_runner.script_extension
30
- file = File.open(slugify("tmp/#{challenge_name}_vars.#{extension}"), 'w')
31
- vars.each do |key, value|
32
- file.puts challenge_runner.save_environment_variable(key, value)
33
- end
34
- file.close
35
- file.path
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
@@ -11,7 +11,7 @@ module Polytrix
11
11
 
12
12
  def read
13
13
  if File.exist?(file_name)
14
- Hashie::Mash.load(file_name).dup
14
+ Hashie::Mash.load(file_name).dup || {}
15
15
  else
16
16
  Hashie::Mash.new
17
17
  end
@@ -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
 
@@ -1,3 +1,3 @@
1
1
  module Polytrix
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
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: // }, validator = nil, &block)
105
- if block_given?
106
- validator = Polytrix::Validator.new(scope, &block)
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", "~> 2.99"
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
- RSpec.configure do |c|
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
@@ -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.0
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-19 00:00:00.000000000 Z
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: '2.99'
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: '2.99'
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
@@ -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,14 +0,0 @@
1
- require 'json'
2
- require 'polytrix/cli/reports/hash_reporter'
3
-
4
- module Polytrix
5
- module CLI
6
- module Reports
7
- class JSONReporter < HashReporter
8
- def convert(data)
9
- JSON.pretty_generate data
10
- end
11
- end
12
- end
13
- end
14
- 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
@@ -1,14 +0,0 @@
1
- require 'yaml'
2
- require 'polytrix/cli/reports/hash_reporter'
3
-
4
- module Polytrix
5
- module CLI
6
- module Reports
7
- class YAMLReporter < HashReporter
8
- def convert(data)
9
- YAML.dump data
10
- end
11
- end
12
- end
13
- end
14
- end