polytrix 0.0.1 → 0.1.0.pre

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.
Files changed (238) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -2
  3. data/.rspec +1 -6
  4. data/.rubocop-todo.yml +19 -0
  5. data/.rubocop.yml +10 -0
  6. data/.travis.yml +11 -0
  7. data/Gemfile +0 -16
  8. data/README.md +119 -28
  9. data/Rakefile +18 -123
  10. data/bin/polytrix +5 -0
  11. data/doc-src/_markdown.md +5 -0
  12. data/doc-src/default_bootstrap.md +13 -0
  13. data/docs/influences.md +28 -0
  14. data/docs/samples/code2doc/java/HelloWorld.md +13 -0
  15. data/docs/samples/code2doc/java/Quine.md +33 -0
  16. data/docs/samples/code2doc/python/hello_world.md +3 -0
  17. data/docs/samples/code2doc/python/quine.md +4 -0
  18. data/docs/samples/code2doc/ruby/hello_world.md +7 -0
  19. data/features/execution.feature +67 -0
  20. data/features/fixtures/configs/empty.yml +12 -0
  21. data/features/fixtures/configs/hello_world.yml +10 -0
  22. data/features/fixtures/spec/polytrix_merge.rb +5 -0
  23. data/features/fixtures/spec/polytrix_spec.rb +10 -0
  24. data/features/reporting.feature +140 -0
  25. data/features/step_definitions/sdk_steps.rb +12 -0
  26. data/features/support/env.rb +8 -0
  27. data/lib/polytrix/challenge.rb +20 -7
  28. data/lib/polytrix/challenge_runner.rb +9 -44
  29. data/lib/polytrix/cli/add.rb +67 -0
  30. data/lib/polytrix/cli/report.rb +88 -0
  31. data/lib/polytrix/cli/reports/hash_reporter.rb +30 -0
  32. data/lib/polytrix/cli/reports/json_reporter.rb +14 -0
  33. data/lib/polytrix/cli/reports/markdown_reporter.rb +23 -0
  34. data/lib/polytrix/cli/reports/yaml_reporter.rb +14 -0
  35. data/lib/polytrix/cli.rb +158 -0
  36. data/lib/polytrix/configuration.rb +65 -4
  37. data/lib/polytrix/core/file_system_helper.rb +75 -0
  38. data/lib/polytrix/core/implementor.rb +31 -3
  39. data/lib/polytrix/documentation/code_segmenter.rb +168 -0
  40. data/lib/polytrix/documentation/comment_styles.rb +87 -0
  41. data/lib/polytrix/documentation/helpers/code_helper.rb +85 -0
  42. data/lib/polytrix/documentation/view_helper.rb +21 -0
  43. data/lib/polytrix/documentation_generator.rb +59 -10
  44. data/lib/polytrix/executor.rb +89 -0
  45. data/lib/polytrix/logger.rb +17 -0
  46. data/lib/polytrix/manifest.rb +64 -7
  47. data/lib/polytrix/result.rb +16 -2
  48. data/lib/polytrix/rspec/documentation_formatter.rb +41 -16
  49. data/lib/polytrix/rspec/yaml_report.rb +51 -0
  50. data/lib/polytrix/rspec.rb +32 -53
  51. data/lib/polytrix/runners/middleware/feature_executor.rb +4 -3
  52. data/lib/polytrix/runners/middleware/setup_env_vars.rb +6 -4
  53. data/lib/polytrix/validation.rb +20 -0
  54. data/lib/polytrix/validations.rb +23 -0
  55. data/lib/polytrix/validator.rb +20 -0
  56. data/lib/polytrix/validator_registry.rb +34 -0
  57. data/lib/polytrix/version.rb +1 -1
  58. data/lib/polytrix.rb +125 -22
  59. data/polytrix.gemspec +7 -2
  60. data/polytrix.rb +6 -0
  61. data/polytrix_tests.yml +20 -0
  62. data/resources/code_sample.tt +2 -0
  63. data/samples/.gitignore +2 -0
  64. data/samples/_markdown.md +5 -0
  65. data/samples/default_bootstrap.rb +14 -0
  66. data/samples/polytrix.rb +28 -0
  67. data/samples/polytrix_cli.sh +7 -0
  68. data/samples/polytrix_tests.yml +10 -0
  69. data/{sdks/fog → samples}/scripts/bootstrap +0 -2
  70. data/samples/scripts/wrapper +7 -0
  71. data/samples/sdks/custom/polytrix.yml +2 -0
  72. data/samples/sdks/java/.gitignore +2 -0
  73. data/samples/sdks/java/build.gradle +14 -0
  74. data/samples/sdks/java/challenges/HelloWorld.java +10 -0
  75. data/samples/sdks/java/challenges/Quine.java +31 -0
  76. data/samples/sdks/java/code_sample.tt +11 -0
  77. data/samples/sdks/java/scripts/bootstrap +2 -0
  78. data/samples/sdks/java/scripts/wrapper +8 -0
  79. data/samples/sdks/python/challenges/hello_world.py +2 -0
  80. data/samples/sdks/python/challenges/quine.py +2 -0
  81. data/{sdks/pkgcloud → samples/sdks/python}/scripts/wrapper +1 -1
  82. data/samples/sdks/ruby/challenges/hello_world.rb +4 -0
  83. data/scripts/bootstrap +1 -9
  84. data/scripts/wrapper +7 -0
  85. data/spec/fabricators/challenge_fabricator.rb +17 -0
  86. data/spec/fabricators/manifest_fabricator.rb +50 -0
  87. data/spec/fabricators/validator_fabricator.rb +12 -0
  88. data/spec/fixtures/{polytrix.yml → polytrix_tests.yml} +0 -0
  89. data/spec/fixtures/src-doc/_scenario.md.erb +1 -0
  90. data/spec/polytrix/challenge_runner_spec.rb +3 -3
  91. data/spec/polytrix/challenge_spec.rb +3 -4
  92. data/spec/polytrix/cli_spec.rb +39 -0
  93. data/spec/polytrix/configuration_spec.rb +45 -1
  94. data/spec/polytrix/documentation/helpers/code_helper_spec.rb +120 -0
  95. data/spec/polytrix/documentation_generator_spec.rb +41 -20
  96. data/spec/polytrix/file_finder_spec.rb +4 -3
  97. data/spec/polytrix/implementor_spec.rb +33 -0
  98. data/spec/polytrix/manifest_spec.rb +32 -14
  99. data/spec/polytrix/middleware/feature_executor_spec.rb +1 -1
  100. data/spec/polytrix/result_spec.rb +49 -0
  101. data/spec/polytrix/validations_spec.rb +16 -0
  102. data/spec/polytrix/validator_registry_spec.rb +39 -0
  103. data/spec/polytrix/validator_spec.rb +63 -0
  104. data/spec/polytrix_spec.rb +33 -7
  105. data/spec/spec_helper.rb +14 -1
  106. data/spec/thor_spy.rb +64 -0
  107. metadata +177 -160
  108. data/.rspec_parallel +0 -10
  109. data/Vagrantfile +0 -41
  110. data/features/0_identity_spec.rb +0 -40
  111. data/features/1_cloud_files_spec.rb +0 -48
  112. data/features/2_servers_spec.rb +0 -19
  113. data/features/features_helper.rb +0 -46
  114. data/features/helpers/cloudfiles_helper.rb +0 -31
  115. data/features/helpers/pacto_helper.rb +0 -33
  116. data/features/helpers/teardown_helper.rb +0 -49
  117. data/features/pacto/extensions/loaders/api_blueprint_loader.rb +0 -63
  118. data/features/pacto/extensions/loaders/simple_loader.rb +0 -55
  119. data/features/pacto/extensions/loaders/yaml_or_json_loader.rb +0 -17
  120. data/features/pacto/extensions/matchers.rb +0 -38
  121. data/features/phase2/feature_coverage_report.rb +0 -109
  122. data/features/phase2/run_all_features.rb +0 -14
  123. data/features/static_site/fixtures/index.html +0 -6
  124. data/lib/polytrix/challenge_builder.rb +0 -16
  125. data/lib/polytrix/core/file_finder.rb +0 -43
  126. data/lib/polytrix/core/result_tracker.rb +0 -25
  127. data/lib/polytrix/runners/middleware/pacto.rb +0 -59
  128. data/packer/.gitignore +0 -3
  129. data/packer/Berksfile +0 -15
  130. data/packer/Gemfile +0 -5
  131. data/packer/Vagrantfile +0 -128
  132. data/packer/cookbooks/drg/metadata.rb +0 -27
  133. data/packer/cookbooks/drg/recipes/admins.rb +0 -22
  134. data/packer/cookbooks/drg/recipes/default.rb +0 -9
  135. data/packer/cookbooks/drg/recipes/dotnet.rb +0 -4
  136. data/packer/cookbooks/drg/recipes/golang.rb +0 -4
  137. data/packer/cookbooks/drg/recipes/java.rb +0 -5
  138. data/packer/cookbooks/drg/recipes/php.rb +0 -10
  139. data/packer/cookbooks/drg/recipes/ruby.rb +0 -29
  140. data/packer/cookbooks/drg/recipes/system.rb +0 -13
  141. data/packer/create_box.sh +0 -10
  142. data/packer/http/preseed.cfg +0 -87
  143. data/packer/packer.json +0 -91
  144. data/packer/scripts/root_setup.sh +0 -37
  145. data/packer/scripts/setup.sh +0 -32
  146. data/pacto/config/pacto_server.rb +0 -40
  147. data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/extensions.json +0 -64
  148. data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/flavors/id.json +0 -100
  149. data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/images/id.json +0 -176
  150. data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/servers/id.json +0 -189
  151. data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/servers.json +0 -63
  152. data/pacto/contracts/dns.api.rackspacecloud.com/v1.0/_tenant_id/domains.json +0 -62
  153. data/pacto/contracts/identity.api.rackspacecloud.com/v2.0/tokens.json +0 -192
  154. data/pacto/contracts/monitoring.api.rackspacecloud.com/v1.0/_tenant_id/account.json +0 -39
  155. data/pacto/contracts/ord.autoscale.api.rackspacecloud.com/v1.0/_tenant_id/groups.json +0 -38
  156. data/pacto/contracts/ord.blockstorage.api.rackspacecloud.com/v1/_tenant_id/volumes.json +0 -30
  157. data/pacto/contracts/ord.databases.api.rackspacecloud.com/v1.0/_tenant_id/instances.json +0 -30
  158. data/pacto/contracts/ord.loadbalancers.api.rackspacecloud.com/v1.0/_tenant_id/loadbalancers.json +0 -114
  159. data/pacto/contracts/ord.queues.api.rackspacecloud.com/v1/_tenant_id/queues.json +0 -13
  160. data/pacto/contracts/ord.servers.api.rackspacecloud.com/v2/_tenant_id/os-networksv2.json +0 -46
  161. data/pacto/contracts/ord.servers.api.rackspacecloud.com/v2/_tenant_id/servers/detail.json +0 -230
  162. data/pacto/contracts/storage101.dfw1.clouddrive.com/v1/mosso_account/container/object.json +0 -15
  163. data/pacto/contracts/storage101.dfw1.clouddrive.com/v1/mosso_account.json +0 -43
  164. data/pacto/contracts/storage101.ord1.clouddrive.com/v1/_mosso_id.json +0 -44
  165. data/pacto/pacto_server.rb +0 -100
  166. data/pacto/rackspace_uri_map.yaml +0 -229
  167. data/scripts/cibuild +0 -4
  168. data/sdks/fog/.gitignore +0 -1
  169. data/sdks/fog/Gemfile +0 -5
  170. data/sdks/fog/challenges/all_connections.rb +0 -45
  171. data/sdks/fog/challenges/authenticate_token.rb +0 -15
  172. data/sdks/fog/challenges/cdn_enable_container.rb +0 -20
  173. data/sdks/fog/challenges/create_a_container.rb +0 -17
  174. data/sdks/fog/challenges/create_server.rb +0 -36
  175. data/sdks/fog/challenges/get_object_metadata.rb +0 -13
  176. data/sdks/fog/challenges/list_containers.rb +0 -10
  177. data/sdks/fog/challenges/provision_scalable_webapp.rb +0 -30
  178. data/sdks/fog/challenges/upload_folder.rb +0 -25
  179. data/sdks/fog/scripts/bootstrap.ps1 +0 -1
  180. data/sdks/fog/scripts/wrapper +0 -2
  181. data/sdks/fog/scripts/wrapper.ps1 +0 -1
  182. data/sdks/gophercloud/.gitignore +0 -2
  183. data/sdks/gophercloud/challenges/authenticate_token.go +0 -23
  184. data/sdks/gophercloud/scripts/bootstrap +0 -6
  185. data/sdks/gophercloud/scripts/wrapper +0 -10
  186. data/sdks/jclouds/.gitignore +0 -1
  187. data/sdks/jclouds/challenges/AuthenticateToken.java +0 -115
  188. data/sdks/jclouds/pom.xml +0 -34
  189. data/sdks/jclouds/scripts/bootstrap +0 -3
  190. data/sdks/jclouds/scripts/wrapper +0 -7
  191. data/sdks/openstack.net/.gitignore +0 -4
  192. data/sdks/openstack.net/.nuget/Microsoft.Build.dll +0 -0
  193. data/sdks/openstack.net/.nuget/NuGet.Config +0 -6
  194. data/sdks/openstack.net/.nuget/NuGet.exe +0 -0
  195. data/sdks/openstack.net/.nuget/NuGet.targets +0 -136
  196. data/sdks/openstack.net/Challenge.cs +0 -10
  197. data/sdks/openstack.net/RunChallenge.cs +0 -19
  198. data/sdks/openstack.net/challenges/AuthenticateToken.cs +0 -24
  199. data/sdks/openstack.net/challenges/Weird.cs +0 -133
  200. data/sdks/openstack.net/openstack.net.csproj +0 -58
  201. data/sdks/openstack.net/openstack.net.sln +0 -27
  202. data/sdks/openstack.net/openstack.net.userprefs +0 -8
  203. data/sdks/openstack.net/packages.config +0 -6
  204. data/sdks/openstack.net/scripts/bootstrap +0 -2
  205. data/sdks/openstack.net/scripts/bootstrap.ps1 +0 -2
  206. data/sdks/openstack.net/scripts/wrapper +0 -7
  207. data/sdks/openstack.net/scripts/wrapper.ps1 +0 -1
  208. data/sdks/php-opencloud/.gitignore +0 -4
  209. data/sdks/php-opencloud/challenges/all_connections.php +0 -64
  210. data/sdks/php-opencloud/challenges/authenticate_token.php +0 -14
  211. data/sdks/php-opencloud/challenges/create_server.php +0 -39
  212. data/sdks/php-opencloud/challenges/get_object_metadata.php +0 -19
  213. data/sdks/php-opencloud/composer.json +0 -5
  214. data/sdks/php-opencloud/scripts/bootstrap +0 -4
  215. data/sdks/php-opencloud/scripts/bootstrap.ps1 +0 -2
  216. data/sdks/php-opencloud/scripts/wrapper +0 -2
  217. data/sdks/php-opencloud/scripts/wrapper.ps1 +0 -1
  218. data/sdks/pkgcloud/.gitignore +0 -1
  219. data/sdks/pkgcloud/challenges/authenticate_token.js +0 -17
  220. data/sdks/pkgcloud/challenges/get_object_metadata.js +0 -18
  221. data/sdks/pkgcloud/scripts/bootstrap +0 -2
  222. data/sdks/pkgcloud/scripts/bootstrap.ps1 +0 -1
  223. data/sdks/pkgcloud/scripts/wrapper.ps1 +0 -1
  224. data/sdks/pyrax/.gitignore +0 -2
  225. data/sdks/pyrax/challenges/all_connections.py +0 -61
  226. data/sdks/pyrax/challenges/authenticate_token.py +0 -17
  227. data/sdks/pyrax/challenges/cdn_enable_container.py +0 -22
  228. data/sdks/pyrax/challenges/create_a_container.py +0 -21
  229. data/sdks/pyrax/challenges/create_server.py +0 -35
  230. data/sdks/pyrax/challenges/get_object_metadata.py +0 -17
  231. data/sdks/pyrax/challenges/upload_folder.py +0 -32
  232. data/sdks/pyrax/requirements.txt +0 -21
  233. data/sdks/pyrax/scripts/bootstrap +0 -9
  234. data/sdks/pyrax/scripts/bootstrap.ps1 +0 -7
  235. data/sdks/pyrax/scripts/wrapper +0 -3
  236. data/sdks/pyrax/scripts/wrapper.ps1 +0 -2
  237. data/spec/polytrix/challenge_builder_spec.rb +0 -16
  238. data/spec/rspec_spec.rb +0 -17
@@ -4,12 +4,13 @@ module Polytrix
4
4
  module Runners
5
5
  module Middleware
6
6
  class SetupEnvVars
7
+ include Polytrix::Core::FileSystemHelper
8
+
7
9
  def initialize(app)
8
10
  @app = app
9
11
  end
10
12
 
11
13
  def call(env)
12
- challenge_runner = env[:challenge_runner]
13
14
  vars = begin
14
15
  Polytrix.manifest[:global_env].dup
15
16
  rescue
@@ -17,15 +18,16 @@ module Polytrix
17
18
  end
18
19
  vars = vars.merge env[:vars].dup
19
20
 
20
- env[:env_file] = setup_env_vars(vars, challenge_runner)
21
+ env[:env_file] = setup_env_vars(env[:name], vars, env[:challenge_runner])
21
22
  @app.call env
22
23
  end
23
24
 
24
25
  private
25
26
 
26
- def setup_env_vars(vars, challenge_runner)
27
+ def setup_env_vars(challenge_name, vars, challenge_runner)
27
28
  FileUtils.mkdir_p 'tmp'
28
- file = File.open("tmp/vars.#{challenge_runner.script_extension}", 'w')
29
+ extension = challenge_runner.script_extension
30
+ file = File.open(slugify("tmp/#{challenge_name}_vars.#{extension}"), 'w')
29
31
  vars.each do |key, value|
30
32
  file.puts challenge_runner.save_environment_variable(key, value)
31
33
  end
@@ -0,0 +1,20 @@
1
+ require 'hashie/dash'
2
+
3
+ module Polytrix
4
+ class Validation < Hashie::Dash
5
+ ALLOWABLE_STATES = %w(passed pending failed skipped)
6
+ property :validated_by, required: true
7
+ property :result
8
+
9
+ def result=(state)
10
+ fail invalidate_state_error unless ALLOWABLE_STATES.include? state
11
+ super
12
+ end
13
+
14
+ protected
15
+
16
+ def invalidate_state_error(state)
17
+ ArgumentError.new "Invalid result state: #{state}, should be one of #{ALLOWABLE_STATES.inspect}"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ require 'hashie/dash'
2
+
3
+ module Polytrix
4
+ class Validations < Set
5
+ def to_hash
6
+ map do |v|
7
+ v.to_hash
8
+ end
9
+ end
10
+
11
+ def to_yaml
12
+ to_hash.to_yaml
13
+ end
14
+
15
+ # Hashie Coercion - automatically treat all values as Validation
16
+ def self.coerce(obj)
17
+ data = obj.map do |value|
18
+ Validation.new(value)
19
+ end
20
+ new data
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module Polytrix
2
+ class Validator
3
+ UNIVERSAL_MATCHER = //
4
+ attr_reader :suite, :sample, :callback
5
+
6
+ def initialize(scope = {}, &validator)
7
+ @suite = scope[:suite] ||= UNIVERSAL_MATCHER
8
+ @sample = scope[:sample] ||= UNIVERSAL_MATCHER
9
+ @callback = validator
10
+ end
11
+
12
+ def should_validate?(challenge)
13
+ !!(@suite.match(challenge.suite) && @sample.match(challenge.name))
14
+ end
15
+
16
+ # def validate(challenge)
17
+ # instance_exec challenge, @callback if should_validate?(challenge)
18
+ # end
19
+ end
20
+ end
@@ -0,0 +1,34 @@
1
+ require 'singleton'
2
+
3
+ module Polytrix
4
+ class ValidatorRegistry
5
+ include Singleton
6
+
7
+ def validators
8
+ @validator ||= []
9
+ end
10
+
11
+ class << self
12
+ def validators
13
+ instance.validators
14
+ end
15
+
16
+ def register(validator, &callback)
17
+ if block_given?
18
+ match_rules = validator
19
+ validator = Validator.new(match_rules, &callback)
20
+ end
21
+ validators << validator
22
+ end
23
+
24
+ def validators_for(challenge)
25
+ selected_validators = validators.select { |v| v.should_validate? challenge }
26
+ selected_validators.empty? ? [Polytrix.configuration.default_validator] : selected_validators
27
+ end
28
+
29
+ def clear
30
+ validators.clear
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,3 +1,3 @@
1
1
  module Polytrix
2
- VERSION = '0.0.1'
2
+ VERSION = '0.1.0.pre'
3
3
  end
data/lib/polytrix.rb CHANGED
@@ -1,56 +1,159 @@
1
+ require 'pathname'
2
+ require 'hashie/dash'
3
+ require 'hashie/mash'
4
+ require 'hashie/extensions/coercion'
1
5
  require 'polytrix/version'
2
- require 'polytrix/manifest'
6
+ require 'polytrix/logger'
7
+ require 'polytrix/core/file_system_helper'
8
+ require 'polytrix/executor'
3
9
  require 'polytrix/core/implementor'
4
- require 'polytrix/core/result_tracker'
5
- require 'polytrix/core/file_finder'
6
10
  require 'polytrix/challenge_runner'
7
11
  require 'polytrix/challenge'
8
- require 'polytrix/challenge_builder'
12
+ require 'polytrix/manifest'
9
13
  require 'polytrix/configuration'
14
+ require 'polytrix/validation'
15
+ require 'polytrix/validations'
10
16
  require 'polytrix/result'
11
17
  require 'polytrix/documentation_generator'
18
+ require 'polytrix/validator'
19
+ require 'polytrix/validator_registry'
12
20
 
13
21
  require 'polytrix/rspec'
14
22
 
15
23
  module Polytrix
24
+ include Polytrix::Logger
25
+
16
26
  class << self
17
- attr_accessor :implementors
18
- attr_accessor :manifest
19
- attr_accessor :default_validator_callback
27
+ include Polytrix::Core::FileSystemHelper
28
+
29
+ def reset
30
+ @configuration = nil
31
+ Polytrix::ValidatorRegistry.clear
32
+ end
33
+
34
+ # The {Polytrix::Manifest} that describes the test scenarios known to Polytrix.
35
+ def manifest
36
+ configuration.test_manifest
37
+ end
38
+
39
+ # The set of {Polytrix::Implementor}s registered with Polytrix.
40
+ def implementors
41
+ configuration.implementors
42
+ end
43
+
44
+ def find_implementor(file)
45
+ existing_implementor = recursive_parent_search(File.dirname(file)) do |path|
46
+ implementors.find do |implementor|
47
+ File.absolute_path(implementor.basedir) == File.absolute_path(path)
48
+ end
49
+ end
50
+ return existing_implementor if existing_implementor
51
+
52
+ implementor_basedir = recursive_parent_search(File.dirname(file), 'polytrix.yml')
53
+ return Polytrix.configuration.implementor implementor_basedir if implementor_basedir
54
+
55
+ nil
56
+ end
20
57
 
21
- def default_validator_callback
22
- @default_validator_callback ||= proc{ |challenge|
23
- expect(challenge[:result].process.exitstatus).to eq(0)
58
+ # Invokes the bootstrap action for each SDK.
59
+ # @see Polytrix::Implementor#bootstrap
60
+ def bootstrap(*sdks)
61
+ select_implementors(sdks).each do |implementor|
62
+ implementor.bootstrap
63
+ end
64
+ end
65
+
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)
24
75
  }
76
+ challenge = implementor.build_challenge challenge_data
77
+ challenge.run
25
78
  end
26
79
 
27
- def default_validator_callback=(callback)
28
- @default_validator_callback = callback
80
+ # Registers a {Polytrix::Validator} that will be used during test
81
+ # execution on matching {Polytrix::Challenge}s.
82
+ def validate(scope = { suite: //, sample: // }, validator = nil, &block)
83
+ if block_given?
84
+ validator = Polytrix::Validator.new(scope, &block)
85
+ elsif validator.nil?
86
+ fail ArgumentError 'You must a block or a Validator as the second argument'
87
+ end
88
+
89
+ Polytrix::ValidatorRegistry.register validator
90
+ validator
29
91
  end
30
92
 
93
+ def load_tests
94
+ Polytrix::RSpec.run_manifest(manifest)
95
+ end
96
+
97
+ # Runs all of the tests described in the {manifest}
98
+ def run_tests(implementors = [])
99
+ test_env = ENV['TEST_ENV_NUMBER'].to_i
100
+ rspec_options = %W[--color -f documentation -f Polytrix::RSpec::YAMLReport -o reports/test_report#{test_env}.yaml]
101
+ rspec_options.concat Polytrix.configuration.rspec_options.split if Polytrix.configuration.rspec_options
102
+ unless implementors.empty?
103
+ target_sdks = implementors.map(&:name)
104
+ Polytrix.implementors.map(&:name).each do |sdk|
105
+ # We don't have an "or" for tags, so it's easier to exclude than include multiple tags
106
+ rspec_options.concat %W[-t ~#{sdk.to_sym}] unless target_sdks.include? sdk
107
+ end
108
+ end
109
+
110
+ load_tests
111
+ logger.info "polytrix:test\tTesting with rspec options: #{rspec_options.join ' '}"
112
+ ::RSpec::Core::Runner.run rspec_options
113
+ logger.info "polytrix:test\tTest execution completed"
114
+ end
115
+
116
+ def reset
117
+ @configuration = nil
118
+ end
119
+
120
+ # @see Polytrix::Configuration
31
121
  def configuration
32
122
  fail "configuration doesn't take a block, use configure" if block_given?
33
123
  @configuration ||= Configuration.new
34
124
  end
35
125
 
126
+ # @see Polytrix::Configuration
36
127
  def configure
37
128
  yield(configuration)
38
129
  end
39
130
 
40
- def sdk_dir(sdk)
41
- "sdks/#{sdk}"
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)
42
140
  end
43
141
 
44
- def load_manifest(yaml_file)
45
- @manifest = Polytrix::Manifest.from_yaml yaml_file
46
- end
142
+ protected
47
143
 
48
- def results
49
- Polytrix::ResultTracker.instance
50
- end
144
+ def select_implementors(sdks)
145
+ return implementors if sdks.empty?
51
146
 
52
- def run_tests
53
- Polytrix::RSpec.run_manifest(@manifest)
147
+ sdks.map do |sdk|
148
+ if File.directory? sdk
149
+ sdk_dir = File.absolute_path(sdk)
150
+ implementors.find { |i| File.absolute_path(i.basedir) == sdk_dir } || configuration.implementor(sdk_dir)
151
+ else
152
+ implementor = implementors.find { |i| i.name == sdk }
153
+ fail ArgumentError, "SDK #{sdk} not found" if implementor.nil?
154
+ implementor
155
+ end
156
+ end
54
157
  end
55
158
  end
56
159
  end
data/polytrix.gemspec CHANGED
@@ -18,10 +18,15 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_dependency "thor", "~> 0.19"
21
22
  spec.add_dependency "mixlib-shellout", "~> 1.3"
22
23
  spec.add_dependency "middleware", "~> 0.1"
23
- spec.add_dependency "rspec", "~> 2.14"
24
- spec.add_dependency "hashie", "~> 2.0"
24
+ spec.add_dependency "rspec", "~> 2.99"
25
+ spec.add_dependency "hashie", "~> 2.1"
26
+ spec.add_dependency "padrino-helpers", "~> 0.12"
25
27
  spec.add_development_dependency "bundler", "~> 1.5"
26
28
  spec.add_development_dependency "rake"
29
+ spec.add_development_dependency "aruba", "~> 0.5"
30
+ spec.add_development_dependency 'rubocop', '~> 0.18.0'
31
+ spec.add_development_dependency 'fabrication', '~> 2.11'
27
32
  end
data/polytrix.rb ADDED
@@ -0,0 +1,6 @@
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
@@ -0,0 +1,20 @@
1
+ ---
2
+ global_env: # global_env defines input available for all scenarios
3
+ LOCALE: <%= ENV['LANG'] %> # templating is allowed
4
+ FAVORITE_NUMBER: 5
5
+ suites:
6
+ Bootstrapping:
7
+ samples:
8
+ - default bootstrap
9
+ - custom bootstrap
10
+ Testing: # "Katas" is the name of the first suite
11
+ env: # These "env" values are only available within the "Katas" suite
12
+ NAME: 'Max'
13
+ samples: # samples defines the individual tests in a suite
14
+ - default validation
15
+ - custom validation
16
+ Plugins: # "Tutorials" is the name of the second suite
17
+ env:
18
+ samples:
19
+ - validating
20
+ - reporting
@@ -0,0 +1,2 @@
1
+ <%= commented "Sample for #{@scenario.name}" %>
2
+ <%= commented @scenario.description if @scenario.description %>
@@ -0,0 +1,2 @@
1
+ reports/
2
+ tmp/
@@ -0,0 +1,5 @@
1
+ <% challenges.compact.each do |challenge| %>
2
+ ``` <%= challenge.implementor.language %>
3
+ <%= File.read(challenge.source_file) %>
4
+ ```
5
+ <% end %>
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This example shows the default behavior of `Polytrix#bootstrap`
4
+ require 'polytrix'
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
+ # Snippet: bootstrap
14
+ Polytrix.bootstrap
@@ -0,0 +1,28 @@
1
+ require 'polytrix'
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
+ RSpec.configure do |c|
13
+ c.expose_current_running_example_as :example
14
+ end
15
+
16
+ Polytrix.validate suite: 'Katas', sample: 'hello world' do |challenge|
17
+ expect(challenge.result.stdout).to eq "Hello, world!\n"
18
+ end
19
+
20
+ Polytrix.validate suite: 'Katas', sample: 'quine' do |challenge|
21
+ expect(challenge.result.stdout).to eq(challenge.source)
22
+ end
23
+
24
+ Polytrix.validate do |challenge|
25
+ expect(challenge.result.exitstatus).to eq(0)
26
+ expect(challenge.result.stderr).to be_empty
27
+ expect(challenge.result.stdout).to end_with "\n"
28
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash -e
2
+ bundle exec polytrix bootstrap
3
+ bundle exec polytrix exec sdks/ruby/challenges/*.rb --code2doc --target-dir=docs/ruby/
4
+ bundle exec polytrix test
5
+ bundle exec polytrix report summary
6
+ bundle exec polytrix report summary --format=markdown
7
+ bundle exec polytrix report summary --format=yaml
@@ -0,0 +1,10 @@
1
+ ---
2
+ global_env: # global_env defines input available for all scenarios
3
+ LOCALE: <%= ENV['LANG'] %> # templating is allowed
4
+ suites:
5
+ Katas: # "Katas" is the name of the first test suite
6
+ env: # Unlike global_env, these variables are only for the Katas suite
7
+ COLOR: red
8
+ samples: # Test scenarios within Katas
9
+ - hello world
10
+ - quine
@@ -1,4 +1,2 @@
1
1
  #!/bin/bash
2
-
3
2
  bundle install
4
-
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ if [[ "$1" == *.rb ]]
3
+ then
4
+ bundle exec ruby "$@"
5
+ else
6
+ bundle exec "$@"
7
+ fi
@@ -0,0 +1,2 @@
1
+ ---
2
+ name: My Custom project
@@ -0,0 +1,2 @@
1
+ .gradle/
2
+ build/
@@ -0,0 +1,14 @@
1
+ apply plugin: 'java'
2
+ sourceSets {
3
+ main {
4
+ java {
5
+ srcDir 'challenges'
6
+ }
7
+ }
8
+ }
9
+ version = '1.0'
10
+ jar {
11
+ manifest {
12
+ attributes 'Implementation-Title': 'Java Samples', 'Implementation-Version': version
13
+ }
14
+ }
@@ -0,0 +1,10 @@
1
+ // This is an example of the standard [Hello World](http://en.wikipedia.org/wiki/Hello_world_program)
2
+ // program written in [Java][java].
3
+ public class HelloWorld {
4
+ // A Java CLI application is defined by creating a main method with this signature:
5
+ public static void main(String[] args) {
6
+ System.out.println("Hello, world!");
7
+ }
8
+ }
9
+
10
+ // [java]: http://en.wikipedia.org/wiki/Java_(programming_language)
@@ -0,0 +1,31 @@
1
+ public class Quine
2
+ {
3
+ public static void main(String[] args)
4
+ {
5
+ char q = 34; // Quotation mark character
6
+ String[] l = { // Array of source code
7
+ "public class Quine",
8
+ "{",
9
+ " public static void main(String[] args)",
10
+ " {",
11
+ " char q = 34; // Quotation mark character",
12
+ " String[] l = { // Array of source code",
13
+ " ",
14
+ " };",
15
+ " for(int i = 0; i < 6; i++ ) // Print opening code",
16
+ " System.out.println(l[i]);",
17
+ " for(int i = 0; i < l.length; i++) // Print string array",
18
+ " System.out.println( l[6] + q + l[i] + q + ',' );",
19
+ " for(int i = 7; i < l.length; i++) // Print this code",
20
+ " System.out.println( l[i] );",
21
+ " }",
22
+ "}",
23
+ };
24
+ for(int i = 0; i < 6; i++ ) // Print opening code
25
+ System.out.println(l[i]);
26
+ for(int i = 0; i < l.length; i++) // Print string array
27
+ System.out.println( l[6] + q + l[i] + q + ',' );
28
+ for(int i = 7; i < l.length; i++) // Print this code
29
+ System.out.println( l[i] );
30
+ }
31
+ }
@@ -0,0 +1,11 @@
1
+ public class <%= @scenario.name %> {
2
+ public static void main(String[] args) {
3
+ <%= commented @scenario.name %>
4
+ <%= commented """
5
+ This is
6
+ a multi line
7
+ test
8
+ """ %>
9
+ <%= commented "This is\nanother multi line\ntest\n" %>
10
+ }
11
+ }
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ gradle build
@@ -0,0 +1,8 @@
1
+ #!/bin/bash
2
+ SOURCE_FILE=$1
3
+ CLASSNAME=`basename $SOURCE_FILE .java`
4
+ #NAMESPACE=org.example.
5
+ CLASS="${NAMESPACE}${CLASSNAME}"
6
+ gradle assemble --quiet
7
+ java -classpath build/libs/java-1.0.jar $CLASS
8
+
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env python
2
+ print 'Hello, world!'
@@ -0,0 +1,2 @@
1
+ s = 's = %r\nprint(s%%s)'
2
+ print(s%s)
@@ -1,2 +1,2 @@
1
1
  #!/bin/bash
2
- node "$@"
2
+ python "$@"
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ name = 'world'
3
+ # This will print Hello, world!
4
+ puts "Hello, #{name}!"
data/scripts/bootstrap CHANGED
@@ -1,10 +1,2 @@
1
1
  #!/bin/bash
2
- gem install bundler --no-ri --no-rdoc
3
- rbenv rehash
4
- bundle update
5
- virtualenv polytrix
6
- source polytrix/bin/activate
7
- pip install pygments
8
- npm install groc
9
- export PATH="$PATH:`pwd`/node_modules/.bin"
10
- bundle exec rake bootstrap
2
+ bundle install
data/scripts/wrapper ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ if [[ "$1" == *.rb ]]
3
+ then
4
+ bundle exec ruby "$@"
5
+ else
6
+ bundle exec "$@"
7
+ fi
@@ -0,0 +1,17 @@
1
+ require 'hashie/mash'
2
+
3
+ # Fabricates test manifests (.polytrix_tests.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(:challenge, from: Polytrix::Challenge) do
12
+ initialize_with { @_klass.new to_hash } # Hash based initialization
13
+ name { SAMPLE_NAMES.sample }
14
+ suite { LANGUAGES.sample }
15
+ source_file { 'spec/fixtures/factorial.py' }
16
+ basedir { 'spec/fixtures' }
17
+ end