polytrix 0.1.0.pre → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +7 -2
  4. data/.travis.yml +2 -1
  5. data/Gemfile +1 -0
  6. data/README.md +190 -98
  7. data/Rakefile +8 -6
  8. data/bin/polytrix +2 -1
  9. data/docs/samples/code2doc/java/HelloWorld.md +4 -0
  10. data/docs/samples/code2doc/java/Quine.md +2 -0
  11. data/docs/samples/code2doc/python/hello_world.md +2 -0
  12. data/docs/samples/code2doc/python/quine.md +2 -0
  13. data/docs/samples/code2doc/ruby/hello_world.md +4 -0
  14. data/features/bootstrapping.feature +36 -0
  15. data/features/cloning.feature +34 -0
  16. data/features/execution.feature +2 -16
  17. data/features/fixtures/configs/empty.yml +12 -1
  18. data/features/fixtures/configs/hello_world.yml +11 -1
  19. data/features/fixtures/spec/polytrix_spec.rb +1 -4
  20. data/features/solo.feature +12 -0
  21. data/features/states.feature +40 -0
  22. data/features/step_definitions/sdk_steps.rb +11 -1
  23. data/features/support/env.rb +2 -1
  24. data/lib/polytrix/challenge.rb +211 -13
  25. data/lib/polytrix/challenge_result.rb +9 -0
  26. data/lib/polytrix/challenge_runner.rb +4 -11
  27. data/lib/polytrix/challenges.rb +16 -0
  28. data/lib/polytrix/cli/report.rb +0 -4
  29. data/lib/polytrix/cli.rb +229 -137
  30. data/lib/polytrix/color.rb +40 -0
  31. data/lib/polytrix/command/action.rb +26 -0
  32. data/lib/polytrix/command/list.rb +53 -0
  33. data/lib/polytrix/command/rundoc.rb +27 -0
  34. data/lib/polytrix/command/test.rb +24 -0
  35. data/lib/polytrix/command.rb +209 -0
  36. data/lib/polytrix/configuration.rb +30 -40
  37. data/lib/polytrix/core/file_system_helper.rb +2 -5
  38. data/lib/polytrix/core/hashie.rb +14 -0
  39. data/lib/polytrix/core/implementor.rb +52 -12
  40. data/lib/polytrix/core/manifest_section.rb +4 -0
  41. data/lib/polytrix/core/string_helpers.rb +15 -0
  42. data/lib/polytrix/documentation/helpers/code_helper.rb +3 -1
  43. data/lib/polytrix/error.rb +209 -0
  44. data/lib/polytrix/logger.rb +365 -8
  45. data/lib/polytrix/logging.rb +34 -0
  46. data/lib/polytrix/manifest.rb +40 -26
  47. data/lib/polytrix/result.rb +1 -0
  48. data/lib/polytrix/rspec.rb +7 -5
  49. data/lib/polytrix/runners/buff_shellout_executor.rb +19 -0
  50. data/lib/polytrix/runners/executor.rb +32 -0
  51. data/lib/polytrix/runners/mixlib_shellout_executor.rb +83 -0
  52. data/lib/polytrix/state_file.rb +60 -0
  53. data/lib/polytrix/util.rb +155 -0
  54. data/lib/polytrix/validation.rb +1 -1
  55. data/lib/polytrix/validator.rb +9 -5
  56. data/lib/polytrix/version.rb +1 -1
  57. data/lib/polytrix.rb +55 -33
  58. data/polytrix.gemspec +4 -2
  59. data/polytrix.rb +0 -5
  60. data/{polytrix_tests.yml → polytrix.yml} +5 -0
  61. data/samples/default_bootstrap.rb +0 -7
  62. data/samples/polytrix.rb +0 -9
  63. data/samples/{polytrix_tests.yml → polytrix.yml} +11 -0
  64. data/samples/polytrix_cli.sh +1 -1
  65. data/spec/fabricators/implementor_fabricator.rb +20 -0
  66. data/spec/fabricators/manifest_fabricator.rb +4 -1
  67. data/spec/fixtures/{polytrix_tests.yml → polytrix.yml} +10 -0
  68. data/spec/polytrix/challenge_runner_spec.rb +3 -2
  69. data/spec/polytrix/challenge_spec.rb +5 -4
  70. data/spec/polytrix/cli_spec.rb +23 -26
  71. data/spec/polytrix/configuration_spec.rb +4 -43
  72. data/spec/polytrix/documentation/helpers/code_helper_spec.rb +1 -1
  73. data/spec/polytrix/documentation_generator_spec.rb +2 -0
  74. data/spec/polytrix/implementor_spec.rb +44 -2
  75. data/spec/polytrix/manifest_spec.rb +7 -4
  76. data/spec/polytrix_spec.rb +9 -11
  77. data/spec/thor_spy.rb +2 -0
  78. metadata +66 -16
  79. data/features/fixtures/spec/polytrix_merge.rb +0 -5
  80. data/features/reporting.feature +0 -140
  81. data/lib/polytrix/executor.rb +0 -89
  82. data/samples/sdks/custom/polytrix.yml +0 -2
@@ -0,0 +1,60 @@
1
+ require 'hashie'
2
+
3
+ module Polytrix
4
+ class StateFileLoadError < StandardError; end
5
+ class StateFile
6
+ def initialize(polytrix_root, name)
7
+ @file_name = File.expand_path(
8
+ File.join(polytrix_root, '.polytrix', "#{name}.yml")
9
+ )
10
+ end
11
+
12
+ def read
13
+ if File.exist?(file_name)
14
+ Hashie::Mash.load(file_name).dup
15
+ else
16
+ Hashie::Mash.new
17
+ end
18
+ end
19
+
20
+ def write(state)
21
+ dir = File.dirname(file_name)
22
+ serialized_string = serialize_hash(Util.stringified_hash(state))
23
+
24
+ FileUtils.mkdir_p(dir) unless File.directory?(dir)
25
+ File.open(file_name, 'wb') { |f| f.write(serialized_string) }
26
+ end
27
+
28
+ def destroy
29
+ FileUtils.rm_f(file_name) if File.exist?(file_name)
30
+ end
31
+
32
+ def diagnose
33
+ raw = read
34
+ result = {}
35
+ raw.keys.sort.each { |k| result[k] = raw[k] }
36
+ result
37
+ end
38
+
39
+ private
40
+
41
+ attr_reader :file_name
42
+
43
+ # @api private
44
+ def read_file
45
+ IO.read(file_name)
46
+ end
47
+
48
+ # @api private
49
+ def deserialize_string(string)
50
+ SafeYAML.load(string)
51
+ rescue SyntaxError, Psych::SyntaxError => ex
52
+ raise StateFileLoadError, "Error parsing #{file_name} (#{ex.message})"
53
+ end
54
+
55
+ # @api private
56
+ def serialize_hash(hash)
57
+ ::YAML.dump(hash)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,155 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2012, 2013, 2014, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ module Polytrix
20
+ # Stateless utility methods used in different contexts. Essentially a mini
21
+ # PassiveSupport library.
22
+ module Util
23
+ # Returns the standard library Logger level constants for a given symbol
24
+ # representation.
25
+ #
26
+ # @param symbol [Symbol] symbol representation of a logger level (:debug,
27
+ # :info, :warn, :error, :fatal)
28
+ # @return [Integer] Logger::Severity constant value or nil if input is not
29
+ # valid
30
+ def self.to_logger_level(symbol)
31
+ return nil unless [:debug, :info, :warn, :error, :fatal].include?(symbol)
32
+
33
+ Logger.const_get(symbol.to_s.upcase)
34
+ end
35
+
36
+ # Returns the symbol represenation of a logging levels for a given
37
+ # standard library Logger::Severity constant.
38
+ #
39
+ # @param const [Integer] Logger::Severity constant value for a logging
40
+ # level (Logger::DEBUG, Logger::INFO, Logger::WARN, Logger::ERROR,
41
+ # Logger::FATAL)
42
+ # @return [Symbol] symbol representation of the logging level
43
+ def self.from_logger_level(const)
44
+ case const
45
+ when Logger::DEBUG then :debug
46
+ when Logger::INFO then :info
47
+ when Logger::WARN then :warn
48
+ when Logger::ERROR then :error
49
+ else :fatal
50
+ end
51
+ end
52
+
53
+ # Returns a new Hash with all key values coerced to symbols. All keys
54
+ # within a Hash are coerced by calling #to_sym and hashes within arrays
55
+ # and other hashes are traversed.
56
+ #
57
+ # @param obj [Object] the hash to be processed. While intended for
58
+ # hashes, this method safely processes arbitrary objects
59
+ # @return [Object] a converted hash with all keys as symbols
60
+ def self.symbolized_hash(obj)
61
+ if obj.is_a?(Hash)
62
+ obj.reduce({}) do |h, (k, v)|
63
+ h[k.to_sym] = symbolized_hash(v)
64
+ h
65
+ end
66
+ elsif obj.is_a?(Array)
67
+ obj.reduce([]) do |a, e|
68
+ a << symbolized_hash(e)
69
+ a
70
+ end
71
+ else
72
+ obj
73
+ end
74
+ end
75
+
76
+ # Returns a new Hash with all key values coerced to strings. All keys
77
+ # within a Hash are coerced by calling #to_s and hashes with arrays
78
+ # and other hashes are traversed.
79
+ #
80
+ # @param obj [Object] the hash to be processed. While intended for
81
+ # hashes, this method safely processes arbitrary objects
82
+ # @return [Object] a converted hash with all keys as strings
83
+ def self.stringified_hash(obj)
84
+ if obj.is_a?(Hash)
85
+ obj.reduce({}) do |h, (k, v)|
86
+ h[k.to_s] = stringified_hash(v)
87
+ h
88
+ end
89
+ elsif obj.is_a?(Array)
90
+ obj.reduce([]) do |a, e|
91
+ a << stringified_hash(e)
92
+ a
93
+ end
94
+ else
95
+ obj
96
+ end
97
+ end
98
+
99
+ # Returns a formatted string representing a duration in seconds.
100
+ #
101
+ # @param total [Integer] the total number of seconds
102
+ # @return [String] a formatted string of the form (XmYY.00s)
103
+ def self.duration(total)
104
+ total = 0 if total.nil?
105
+ minutes = (total / 60).to_i
106
+ seconds = (total - (minutes * 60))
107
+ format('(%dm%.2fs)', minutes, seconds)
108
+ end
109
+
110
+ # Generates a command (or series of commands) wrapped so that it can be
111
+ # invoked on a remote instance or locally.
112
+ #
113
+ # This method uses the Bourne shell (/bin/sh) to maximize the chance of
114
+ # cross platform portability on Unixlike systems.
115
+ #
116
+ # @param [String] the command
117
+ # @return [String] a wrapped command string
118
+ def self.wrap_command(cmd)
119
+ cmd = 'false' if cmd.nil?
120
+ cmd = 'true' if cmd.to_s.empty?
121
+ cmd = cmd.sub(/\n\Z/, '') if cmd =~ /\n\Z/
122
+
123
+ "sh -c '\n#{cmd}\n'"
124
+ end
125
+
126
+ # Modifes the given string to strip leading whitespace on each line, the
127
+ # amount which is calculated by using the first line of text.
128
+ #
129
+ # @example
130
+ #
131
+ # string = <<-STRING
132
+ # a
133
+ # b
134
+ # c
135
+ # STRING
136
+ # Util.outdent!(string) # => "a\n b\nc\n"
137
+ #
138
+ # @param string [String] the string that will be modified
139
+ # @return [String] the modified string
140
+ def self.outdent!(string)
141
+ string.gsub!(/^ {#{string.index(/[^ ]/)}}/, '')
142
+ end
143
+
144
+ # Returns a set of Bourne Shell (AKA /bin/sh) compatible helper
145
+ # functions. This function is usually called inline in a string that
146
+ # will be executed remotely on a test instance.
147
+ #
148
+ # @return [String] a string representation of useful helper functions
149
+ def self.shell_helpers
150
+ IO.read(File.join(
151
+ File.dirname(__FILE__), %w[.. .. support download_helpers.sh]
152
+ ))
153
+ end
154
+ end
155
+ end
@@ -1,7 +1,7 @@
1
1
  require 'hashie/dash'
2
2
 
3
3
  module Polytrix
4
- class Validation < Hashie::Dash
4
+ class Validation < Polytrix::ManifestSection
5
5
  ALLOWABLE_STATES = %w(passed pending failed skipped)
6
6
  property :validated_by, required: true
7
7
  property :result
@@ -1,7 +1,11 @@
1
+ require 'rspec/expectations'
2
+
1
3
  module Polytrix
2
4
  class Validator
5
+ include RSpec::Matchers
6
+
3
7
  UNIVERSAL_MATCHER = //
4
- attr_reader :suite, :sample, :callback
8
+ attr_reader :suite, :sample, :level, :callback
5
9
 
6
10
  def initialize(scope = {}, &validator)
7
11
  @suite = scope[:suite] ||= UNIVERSAL_MATCHER
@@ -10,11 +14,11 @@ module Polytrix
10
14
  end
11
15
 
12
16
  def should_validate?(challenge)
13
- !!(@suite.match(challenge.suite) && @sample.match(challenge.name))
17
+ !!(@suite.match(challenge.suite.to_s) && @sample.match(challenge.name.to_s))
14
18
  end
15
19
 
16
- # def validate(challenge)
17
- # instance_exec challenge, @callback if should_validate?(challenge)
18
- # end
20
+ def validate(challenge)
21
+ instance_exec challenge, &@callback if should_validate?(challenge)
22
+ end
19
23
  end
20
24
  end
@@ -1,3 +1,3 @@
1
1
  module Polytrix
2
- VERSION = '0.1.0.pre'
2
+ VERSION = '0.1.0'
3
3
  end
data/lib/polytrix.rb CHANGED
@@ -1,14 +1,21 @@
1
1
  require 'pathname'
2
- require 'hashie/dash'
3
- require 'hashie/mash'
4
- require 'hashie/extensions/coercion'
2
+ require 'polytrix/error'
3
+ require 'polytrix/core/hashie'
4
+ require 'polytrix/core/string_helpers'
5
5
  require 'polytrix/version'
6
+ require 'polytrix/util'
7
+ require 'polytrix/color'
6
8
  require 'polytrix/logger'
9
+ require 'polytrix/logging'
10
+ require 'polytrix/state_file'
7
11
  require 'polytrix/core/file_system_helper'
8
- require 'polytrix/executor'
12
+ require 'polytrix/runners/executor'
13
+ require 'polytrix/core/manifest_section'
9
14
  require 'polytrix/core/implementor'
10
15
  require 'polytrix/challenge_runner'
16
+ require 'polytrix/challenge_result'
11
17
  require 'polytrix/challenge'
18
+ require 'polytrix/challenges'
12
19
  require 'polytrix/manifest'
13
20
  require 'polytrix/configuration'
14
21
  require 'polytrix/validation'
@@ -21,11 +28,15 @@ require 'polytrix/validator_registry'
21
28
  require 'polytrix/rspec'
22
29
 
23
30
  module Polytrix
24
- include Polytrix::Logger
31
+ include Polytrix::DefaultLogger
32
+ include Polytrix::Logging
25
33
 
26
34
  class << self
27
35
  include Polytrix::Core::FileSystemHelper
28
36
 
37
+ # @return [Mutex] a common mutex for global coordination
38
+ attr_accessor :mutex
39
+
29
40
  def reset
30
41
  @configuration = nil
31
42
  Polytrix::ValidatorRegistry.clear
@@ -33,12 +44,12 @@ module Polytrix
33
44
 
34
45
  # The {Polytrix::Manifest} that describes the test scenarios known to Polytrix.
35
46
  def manifest
36
- configuration.test_manifest
47
+ configuration.manifest
37
48
  end
38
49
 
39
50
  # The set of {Polytrix::Implementor}s registered with Polytrix.
40
51
  def implementors
41
- configuration.implementors
52
+ manifest.implementors.values
42
53
  end
43
54
 
44
55
  def find_implementor(file)
@@ -49,12 +60,17 @@ module Polytrix
49
60
  end
50
61
  return existing_implementor if existing_implementor
51
62
 
52
- implementor_basedir = recursive_parent_search(File.dirname(file), 'polytrix.yml')
53
- return Polytrix.configuration.implementor implementor_basedir if implementor_basedir
54
-
55
63
  nil
56
64
  end
57
65
 
66
+ # Invokes the clone action for each SDK.
67
+ # @see Polytrix::Implementor#clone
68
+ def clone(*sdks)
69
+ select_implementors(sdks).each do |implementor|
70
+ implementor.clone
71
+ end
72
+ end
73
+
58
74
  # Invokes the bootstrap action for each SDK.
59
75
  # @see Polytrix::Implementor#bootstrap
60
76
  def bootstrap(*sdks)
@@ -63,18 +79,24 @@ module Polytrix
63
79
  end
64
80
  end
65
81
 
66
- def exec(file, exec_options)
67
- implementor = find_implementor(file) || exec_options[:default_implementor]
68
-
69
- extension = File.extname(file)
70
- name = File.basename(file, extension)
71
- challenge_data = {
72
- name: name,
73
- # language: extension,
74
- source_file: File.expand_path(file, Dir.pwd)
75
- }
76
- challenge = implementor.build_challenge challenge_data
77
- challenge.run
82
+ def exec(*files)
83
+ # files.map do | file |
84
+ # Dir.glob file
85
+ # end.flatten
86
+
87
+ files.each do | file |
88
+ implementor = find_implementor(file) # || exec_options[:default_implementor]
89
+
90
+ extension = File.extname(file)
91
+ name = File.basename(file, extension)
92
+ challenge_data = {
93
+ name: name,
94
+ # language: extension,
95
+ source_file: File.expand_path(file, Dir.pwd)
96
+ }
97
+ challenge = implementor.build_challenge challenge_data
98
+ challenge.exec
99
+ end
78
100
  end
79
101
 
80
102
  # Registers a {Polytrix::Validator} that will be used during test
@@ -91,11 +113,12 @@ module Polytrix
91
113
  end
92
114
 
93
115
  def load_tests
116
+ manifest.build_challenges
94
117
  Polytrix::RSpec.run_manifest(manifest)
95
118
  end
96
119
 
97
120
  # Runs all of the tests described in the {manifest}
98
- def run_tests(implementors = [])
121
+ def verify(implementors = [])
99
122
  test_env = ENV['TEST_ENV_NUMBER'].to_i
100
123
  rspec_options = %W[--color -f documentation -f Polytrix::RSpec::YAMLReport -o reports/test_report#{test_env}.yaml]
101
124
  rspec_options.concat Polytrix.configuration.rspec_options.split if Polytrix.configuration.rspec_options
@@ -128,15 +151,12 @@ module Polytrix
128
151
  yield(configuration)
129
152
  end
130
153
 
131
- # Merges multiple test results files produced the rspec {Polytrix::RSpec::YAMLReport} formatter.
132
- # @param result_files [Array] the location of the files to merge.
133
- # @return [String] the merged content
134
- def merge_results(result_files)
135
- merged_results = Polytrix::Manifest.new
136
- result_files.each do |result_file|
137
- merged_results.deep_merge! YAML.load(File.read(result_file))
138
- end
139
- YAML.dump(merged_results.to_hash)
154
+ # Returns whether or not standard output is associated with a terminal
155
+ # device (tty).
156
+ #
157
+ # @return [true,false] is there a tty?
158
+ def tty?
159
+ $stdout.tty?
140
160
  end
141
161
 
142
162
  protected
@@ -149,7 +169,7 @@ module Polytrix
149
169
  sdk_dir = File.absolute_path(sdk)
150
170
  implementors.find { |i| File.absolute_path(i.basedir) == sdk_dir } || configuration.implementor(sdk_dir)
151
171
  else
152
- implementor = implementors.find { |i| i.name == sdk }
172
+ implementor = implementors.find { |i| i.name.to_s.downcase == sdk.to_s.downcase }
153
173
  fail ArgumentError, "SDK #{sdk} not found" if implementor.nil?
154
174
  implementor
155
175
  end
@@ -157,3 +177,5 @@ module Polytrix
157
177
  end
158
178
  end
159
179
  end
180
+
181
+ Polytrix.mutex = Mutex.new
data/polytrix.gemspec CHANGED
@@ -19,10 +19,12 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency "thor", "~> 0.19"
22
- spec.add_dependency "mixlib-shellout", "~> 1.3"
22
+ spec.add_dependency "logging", "~> 1.8"
23
+ spec.add_dependency "mixlib-shellout", "~> 1.3" # Used for MRI
24
+ spec.add_dependency "buff-shell_out", "~> 0.1" # Used for JRuby
23
25
  spec.add_dependency "middleware", "~> 0.1"
24
26
  spec.add_dependency "rspec", "~> 2.99"
25
- spec.add_dependency "hashie", "~> 2.1"
27
+ spec.add_dependency "hashie", "~> 3.0"
26
28
  spec.add_dependency "padrino-helpers", "~> 0.12"
27
29
  spec.add_development_dependency "bundler", "~> 1.5"
28
30
  spec.add_development_dependency "rake"
data/polytrix.rb CHANGED
@@ -1,6 +1 @@
1
1
  Polytrix.configuration.default_doc_template = 'doc-src/_markdown.md'
2
-
3
- Polytrix.configure do |polytrix|
4
- polytrix.test_manifest = 'polytrix_tests.yml'
5
- polytrix.implementor name: 'polytrix', language: 'ruby', basedir: 'samples/'
6
- end
@@ -1,4 +1,9 @@
1
1
  ---
2
+ implementors:
3
+ polytrix:
4
+ language: 'ruby'
5
+ basedir: 'samples/'
6
+
2
7
  global_env: # global_env defines input available for all scenarios
3
8
  LOCALE: <%= ENV['LANG'] %> # templating is allowed
4
9
  FAVORITE_NUMBER: 5
@@ -3,12 +3,5 @@
3
3
  # This example shows the default behavior of `Polytrix#bootstrap`
4
4
  require 'polytrix'
5
5
 
6
- Polytrix.configure do |polytrix|
7
- Dir['sdks/*'].each do |sdk|
8
- name = File.basename(sdk)
9
- polytrix.implementor name: name, basedir: sdk
10
- end
11
- end
12
-
13
6
  # Snippet: bootstrap
14
7
  Polytrix.bootstrap
data/samples/polytrix.rb CHANGED
@@ -1,14 +1,5 @@
1
1
  require 'polytrix'
2
2
 
3
- basedir = File.expand_path('..', __FILE__)
4
-
5
- Polytrix.configure do |polytrix|
6
- Dir["#{basedir}/sdks/*"].each do |sdk|
7
- name = File.basename(sdk)
8
- polytrix.implementor name: name, basedir: sdk
9
- end
10
- end
11
-
12
3
  RSpec.configure do |c|
13
4
  c.expose_current_running_example_as :example
14
5
  end
@@ -1,4 +1,15 @@
1
1
  ---
2
+ implementors:
3
+ ruby:
4
+ language: 'ruby'
5
+ basedir: 'sdks/ruby'
6
+ java:
7
+ language: 'java'
8
+ basedir: 'sdks/java'
9
+ python:
10
+ language: 'python'
11
+ basedir: 'sdks/python'
12
+
2
13
  global_env: # global_env defines input available for all scenarios
3
14
  LOCALE: <%= ENV['LANG'] %> # templating is allowed
4
15
  suites:
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash -e
2
2
  bundle exec polytrix bootstrap
3
3
  bundle exec polytrix exec sdks/ruby/challenges/*.rb --code2doc --target-dir=docs/ruby/
4
- bundle exec polytrix test
4
+ # bundle exec polytrix test
5
5
  bundle exec polytrix report summary
6
6
  bundle exec polytrix report summary --format=markdown
7
7
  bundle exec polytrix report summary --format=yaml
@@ -0,0 +1,20 @@
1
+ require 'hashie/mash'
2
+
3
+ # Fabricates test manifests (.polytrix.yml files)
4
+ LANGUAGES = %w(java ruby python nodejs c# golang php)
5
+ SAMPLE_NAMES = [
6
+ 'hello world',
7
+ 'quine',
8
+ 'my_kata'
9
+ ]
10
+
11
+ Fabricator(:implementor, from: Polytrix::Implementor) do
12
+ initialize_with { @_klass.new to_hash } # Hash based initialization
13
+ language { LANGUAGES.sample }
14
+ name do |attr|
15
+ "my_#{attr[:language]}_project"
16
+ end
17
+ basedir do |attr|
18
+ "sdks/#{attr[:name]}"
19
+ end
20
+ end
@@ -1,6 +1,6 @@
1
1
  require 'hashie/mash'
2
2
 
3
- # Fabricates test manifests (.polytrix_tests.yml files)
3
+ # Fabricates test manifests (.polytrix.yml files)
4
4
  LANGUAGES = %w(java ruby python nodejs c# golang php)
5
5
  SAMPLE_NAMES = [
6
6
  'hello world',
@@ -12,6 +12,9 @@ Fabricator(:manifest, from: Polytrix::Manifest) do
12
12
  initialize_with { @_klass.new to_hash } # Hash based initialization
13
13
  transient suite_count: 3
14
14
  transient samples_per_suite: 3
15
+ implementors do
16
+ Fabricate(:implementor)
17
+ end
15
18
  global_env do
16
19
  {
17
20
  VAR1: 1,
@@ -1,4 +1,14 @@
1
1
  ---
2
+ implementors:
3
+ ruby:
4
+ language: 'ruby'
5
+ basedir: 'sdks/ruby'
6
+ java:
7
+ language: 'java'
8
+ basedir: 'sdks/java'
9
+ python:
10
+ language: 'python'
11
+ basedir: 'sdks/python'
2
12
  global_env:
3
13
  LOCALE: <%= ENV['LANG'] %>
4
14
  FAVORITE_NUMBER: 5
@@ -1,13 +1,14 @@
1
1
  module Polytrix
2
2
  describe ChallengeRunner do
3
3
  subject(:runner) { ChallengeRunner.create_runner }
4
+ let(:implementor) { Fabricate(:implementor) }
4
5
  let(:challenge) do
5
- Fabricate(:challenge, name: 'factorial', source_file: 'spec/fixtures/factorial.py', basedir: 'spec/fixtures')
6
+ Fabricate(:challenge, name: 'factorial', source_file: 'spec/fixtures/factorial.py', basedir: 'spec/fixtures', implementor: implementor)
6
7
  end
7
8
 
8
9
  describe '#run_challenge' do
9
10
  it 'executes a challenge' do
10
- expect(runner.run_challenge challenge).to be_an_instance_of Challenge
11
+ expect(runner.run_challenge challenge).to be_an_instance_of Result
11
12
  end
12
13
  end
13
14
  end
@@ -5,14 +5,15 @@ module Polytrix
5
5
  implementor.build_challenge name: 'factorial', vars: {}
6
6
  end
7
7
 
8
- describe '#run' do
8
+ describe '#exec' do
9
9
  it 'executes the challenge and returns itself' do
10
- expect(challenge.run).to be_an_instance_of Challenge
11
- expect(challenge.run).to eq(challenge)
10
+ expect(challenge.exec).to be_an_instance_of Challenge
11
+ expect(challenge.exec).to eq(challenge)
12
12
  end
13
13
 
14
14
  it 'stores the result' do
15
- expect(challenge.run[:result]).to be_an_instance_of Result
15
+ result = challenge.exec[:result]
16
+ expect(result).to be_an_instance_of Result
16
17
  end
17
18
  end
18
19
  end
@@ -2,36 +2,33 @@ require 'spec_helper'
2
2
  require 'polytrix/cli'
3
3
 
4
4
  module Polytrix
5
- module CLI
6
- describe Main do
7
- let(:kernel) { double(:kernel) }
8
- subject { ThorSpy.on(described_class, kernel) }
9
- describe 'bootstrap' do
10
- context 'with no args' do
11
- it 'calls Polytrix.bootstrap' do
12
- expect(kernel).to receive(:exit).with(0)
13
- expect(Polytrix).to receive(:bootstrap)
14
- subject.bootstrap
15
- end
5
+ describe CLI do
6
+ let(:kernel) { double(:kernel) }
7
+ subject { ThorSpy.on(described_class, kernel) }
8
+ describe 'bootstrap' do
9
+ context 'with no args' do
10
+ it 'calls bootstrap on each implementor' do
11
+ expect(kernel).to receive(:exit).with(0)
12
+ # TODO: Any way to test each implementor is called? We can't use
13
+ # `Polytrix.implementors` because it will be reloaded.
14
+ subject.bootstrap
16
15
  end
16
+ end
17
17
 
18
- context 'with an existing SDK' do
19
- before do
20
- @implementor = Polytrix.configuration.implementor name: 'test', basedir: '.'
21
- end
22
-
23
- it 'calls bootstrap on the SDK' do
24
- expect(@implementor).to receive(:bootstrap)
25
- expect(kernel).to receive(:exit).with(0)
26
- expect(subject.stderr.string).to eq('')
27
- subject.bootstrap('test')
28
- end
18
+ context 'with an existing SDK' do
19
+ xit 'calls bootstrap on the SDK' do
20
+ # expect(@implementor).to receive(:bootstrap)
21
+ expect(kernel).to receive(:exit).with(0)
22
+ expect(subject.stderr.string).to eq('')
23
+ subject.bootstrap('test')
29
24
  end
25
+ end
30
26
 
31
- context 'with an non-existant SDK' do
32
- it 'fails' do
33
- expect { subject.bootstrap('missing') }.to raise_error(SystemExit, 'SDK missing not found')
34
- end
27
+ context 'with an non-existant SDK' do
28
+ it 'fails' do
29
+ expect(kernel).to receive(:exit).with(1)
30
+ subject.bootstrap('missing')
31
+ expect(subject.stdout.string).to include('No scenarios for regex')
35
32
  end
36
33
  end
37
34
  end