polytrix 0.0.1 → 0.1.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8655afabebaa23eba72bb5028b0efb5d22ecc7d7
4
- data.tar.gz: 336634653e22e6b814edbb9fc00598fc32c431f5
3
+ metadata.gz: 1c91cf7e97c088e23aa0134c2e20acfab0640195
4
+ data.tar.gz: 9bd8c63ae3cfbbc3bc75fc54c3b094ad848dd8c7
5
5
  SHA512:
6
- metadata.gz: 16ee58b313175b50b7b446a9bbcfc3699b80261ab3502d26c2b785ce51e121b7d50ced60f72edd61396ec75c42167da7ca6ea4049799af9ce9eb531e8c47c39b
7
- data.tar.gz: 4e0cdb6e135581bbdaee0eb5fb06d0771335448f4b944eb345cec16772e4a2447a28a3e3bc0d93dd256fd9f123e22e137ed50bd06784b7265e77b9a9ffe198ce
6
+ metadata.gz: 5361e579064d58b4168e5929f995d1a42506c2faa49b246ddccd83eec3f2adef3d28b2761ab0bfd9b173e6ef690702b7eba56caef2e1a75746045c48c29e97b3
7
+ data.tar.gz: 61bcc9b099b67a95695cc59ac0d23baf3791cb8eec7c1bed382964c25e03ebc18fac01e6bce5bed6be1666e45a58ada4ef611323121dcf1bdc5c43c3c4f6823c
data/.gitignore CHANGED
@@ -1,13 +1,13 @@
1
1
  Gemfile.lock
2
2
  pacto.log
3
3
  **/.bundle/*.log
4
- reports/
4
+ /reports/
5
5
  .rbenv-vars
6
6
  .packer-creds.json
7
7
  **/tmp/
8
8
  node_modules/
9
9
  .tokens.json
10
- docs/
11
10
  /polytrix/
12
11
  pkg/
13
12
  coverage/
13
+ .yardoc/
data/.rspec CHANGED
@@ -1,11 +1,6 @@
1
- -I features
2
- --format MatrixFormatter::Formatters::JSONFormatter
3
- --out reports/matrix<%= ENV['TEST_ENV_NUMBER'].to_i %>.json
4
- --format MatrixFormatter::Formatters::HTMLFormatter
5
- --out reports/matrix.html
1
+ -r spec_helper
6
2
  --format html
7
3
  --out reports/rspec.html
8
4
  --format documentation
9
5
  --color
10
- --require features_helper.rb
11
6
 
data/.rubocop-todo.yml ADDED
@@ -0,0 +1,19 @@
1
+ # This configuration was generated by `rubocop --auto-gen-config`
2
+ # on 2014-06-12 15:05:43 -0400 using RuboCop version 0.18.1.
3
+ # The point is for the user to remove these configuration records
4
+ # one by one as the offences are removed from the code base.
5
+ # Note that changes in the inspected code, or installation of new
6
+ # versions of RuboCop, may require this file to be generated again.
7
+
8
+ # Offence count: 41
9
+ Documentation:
10
+ Enabled: false
11
+
12
+ # Offence count: 57
13
+ LineLength:
14
+ Max: 165
15
+
16
+ # Offence count: 6
17
+ # Configuration parameters: CountComments.
18
+ MethodLength:
19
+ Max: 21
data/.rubocop.yml ADDED
@@ -0,0 +1,10 @@
1
+ inherit_from: .rubocop-todo.yml
2
+
3
+ AllCops:
4
+ Include:
5
+ - Guardfile
6
+ - Rakefile
7
+ - pacto.gemspec
8
+ Exclude:
9
+ - bin/**
10
+ - tmp/**
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ before_install:
2
+ - sudo add-apt-repository ppa:cwchien/gradle
3
+ - sudo apt-get update -qq
4
+ - sudo apt-get install -qq gradle
5
+ rvm:
6
+ - 1.9.3
7
+ - 2.0.0
8
+ - 2.1.0
9
+ allow_failures:
10
+ rvm:
11
+ - 1.9.3 # YAML formatting differs
data/Gemfile CHANGED
@@ -2,22 +2,6 @@
2
2
  source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
- gem "pacto", :git => 'https://github.com/thoughtworks/pacto', :branch => 'uri_templates'
6
- # uriTemplate support merged into webmock but not yet released - webmock#334
7
- gem "webmock", :git => 'https://github.com/bblimke/webmock', :branch => 'master'
8
- # optional param fix merged but not yet released - addressable#140
9
- gem "addressable", :git => 'https://github.com/sporkmonger/addressable.git', :branch => 'master'
10
- gem "fog", '~> 1.19'
11
- gem "vcr"
12
- gem "goliath"
13
- gem "excon"
14
- gem "em-http-request"
15
- gem "rspec_junit_formatter"
16
5
  gem "pry"
17
- gem "matrix_formatter", :git => 'https://github.com/maxlinc/matrix_formatter', :branch => 'html5'
18
- gem "highline"
19
- gem "parallel_tests"
20
6
  gem "rake-notes"
21
7
  gem "simplecov"
22
- gem "mixlib-shellout"
23
-
data/README.md CHANGED
@@ -1,48 +1,139 @@
1
- # DRG Tests #
1
+ # Polytrix - the Polyglot Testing Matrix
2
2
 
3
- This repo contains smoke tests for Rackspace SDKs. In order to run it you'll either need:
4
- - Lots of dependencies installed on your laptop
5
- - VirtualBox & Vagrant, so you can install the necessary dependencies inside a local VM
6
- - Packer and Vagrant-Rackspace, so you can build images and use images on the Rackspace cloud to run tests
3
+ Polytrix is a polyglot test runner and documentation generator. It aims to let you run sample code written in any language. It's especially useful if you want to run similar code samples in multiple languages. Simply put, if a project like [Slate](https://github.com/tripit/slate) looks like an interesting documentation option, then you might be interested in Polytrix for testing.
7
4
 
8
- The last option can also be combined with Jenkins JClouds plugin in order to setup CI builds using the images produced by Packer.
5
+ # Features
9
6
 
10
- ## Dependencies
7
+ Polytrix samples defined in a "test manifest" written in YAML. The test manifest is meant to be portable so you can use you can create a "lightweight sample runner" in your preferred build/test tool of choice for your language, and then integrate the samples with Polytrix later to get the extra features. Polytrix can:
8
+ - Run sample code in any language and several platforms
9
+ - Perform compatibility testing checking multiple implementations (in different langauges) against the same set of assertions
10
+ - Generate documentation from sample code and test results
11
+ - Generate compatibility or feature matrix reports
11
12
 
12
- The tests will use package managers for each SDK where appropriate (e.g. bundler for fog, npm for pkgcloud, etc.) You need to be setup at least to the point where those package managers can run. You'll also need dnsmasq in order to intercept some of the HTTP transactions for testing purposes. It is possible to set this all up on your own machine - but the easiest way is to use Vagrant, Packer, or anything else that will let you use the Chef scripts in the project (targeted for Ubuntu).
13
+ Polytrix provides a few built-in assertions, but also has a plugin system that you can use to do more advanced validation, like using [Pacto](https://github.com/thoughtworks/pacto) to intercept and validate the usage of RESTful services.
13
14
 
14
- ## Creating a DRG Image
15
+ # Usage preview
15
16
 
16
- ### Packer
17
+ Polytrix is currently run via rspec. You can create a script that looks like this and run it with rspec:
17
18
 
18
- The easiest way to create an image is with [Packer](http://www.packer.io).
19
+ ```ruby
20
+ require 'polytrix/rspec'
19
21
 
20
- ### Rackspace credentials
22
+ Polytrix.implementors = Dir['sdks/*'].map{ |sdk|
23
+ name = File.basename(sdk)
24
+ Polytrix::Implementor.new :name => name
25
+ }
21
26
 
22
- You need to create a `.rbenv-vars` file with your Rackspace credentials. These will be loaded as environment variables when the tests run. The file should contain:
27
+ Polytrix.load_manifest 'polytrix_tests.yml'
28
+ Polytrix.bootstrap
29
+ Polytrix.run_tests
30
+ ```
31
+
32
+ Polytrix will use the information in the Manifest and Implementors (see the sections below) to build an rspec test suite. It will setup tags for each Implementor, and names corresponding with the tests in the manifest.
33
+
34
+ So in our Polytrix examples project you can use commands like:
35
+
36
+ ```sh
37
+ $ # Only run tests for the Java implementor
38
+ $ bundle exec rspec -t java
39
+ $ # Run the "hello world" tests in each language
40
+ $ bundle exec rspec -e "hello world"
41
+ ```
42
+
43
+ ## Usage Breakdown
44
+
45
+ ### Defining Implementors (SDKs)
46
+
47
+ Polytrix can run the tests against multiple implementors. This usually means an SDK, but we used the generic term implementor because Polytrix works equally well for testing code katas, coursework, or other items. Perhaps even things like multi-platform plugins for [Calatrava](https://github.com/calatrava/calatrava/wiki/Plugins) or [PhoneGap](http://docs.phonegap.com/en/3.4.0/guide_hybrid_plugins_index.md.html#Plugin%20Development%20Guide).
48
+
49
+ This snippet defines the implementors:
50
+ ```ruby
51
+ Polytrix.implementors = Dir['sdks/*'].map{ |sdk|
52
+ name = File.basename(sdk)
53
+ Polytrix::Implementor.new :name => name
54
+ }
55
+ ```
56
+
57
+ See the full Implementor documentation for details on other attributes you can set, like `:language`. Polytrix will try to infer any information you don't pass.
58
+
59
+ #### Bootstrapping, compiling, wrapper scripts
23
60
 
61
+ Polytrix currently uses the [script/bootstrap](http://wynnnetherland.com/linked/2013012801/bootstrapping-consistency) pattern to allow each implementor to hook into dependency management, build tools, or other systems. Polytrix will look for three scripts (on Windows it will look for a *.ps1 version written in PowerShell):
62
+
63
+ | File | Purpose |
64
+ | ---------------- | -------------------------------------------------------------- |
65
+ | script/bootstrap | Prepare the SDK, usually by running depenency management tool. |
66
+ | script/wrapper | Wrapper script instead of executing code samples as scripts |
67
+
68
+ The bootstrap script is called by `Polytrix.bootstrap`. The wrapper script, if it exists, wraps the executino of the code sample. If there is no wrapper script, Polytrix will try to execute the sample code as a script. That works for many non-compiled scripting languages, like Ruby or Python, but won't work for something like Java.
69
+
70
+ If there is a wrapper script, Polytrix will call it with teh sample source file as the first argument, e.g.:
71
+ ```sh
72
+ $ cd my_java_sdk
73
+ $ ./script/wrapper src/samples/HelloWorld.java
24
74
  ```
25
- RAX_USERNAME=<your_rackspace_username>
26
- RAX_API_KEY=<your_rackspace_api_key>
75
+
76
+ ### Defining tests - the test manifest
77
+
78
+ Tests are defined in a YAML "test manifest" which defines what sample code should be executed, and what input it should receive. Standardizing the input is important for compliance testing, becaues it is difficult to maintain tests where one example expects "FOO=bar" and another expects "--foo bar".
79
+
80
+ A simple test manifest looks like this:
81
+ ```yaml
82
+ ---
83
+ global_env: # global_env defines input available for all scenarios
84
+ LOCALE: <%= ENV['LANG'] %> # templating is allowed
85
+ FAVORITE_NUMBER: 5
86
+ suites: # suites defines the test suites that can be executed
87
+ Katas: # "Katas" is the name of the first suite
88
+ env: # These "env" values are only available within the "Katas" suite
89
+ NAME: 'Max'
90
+ samples: # samples defines the individual tests in a suite
91
+ - hello world
92
+ - quine
93
+ Tutorials: # "Tutorials" is the name of the second suite
94
+ env:
95
+ samples:
96
+ - deploying
97
+ - documenting
27
98
  ```
28
99
 
29
- ### Getting a DRG box
100
+ ### Test setup
101
+
102
+ `Polytrix.run_tests` runs the tests. Actually, right now it really just defines them in rspec, you still need to run the whole script via the RSpec command for the tests to run.
103
+
104
+ ### Finding samples
105
+
106
+ Polytrix finds samples based on a loose naming convention. This makes it easier to use file names that are idiomatic for each implementor, while still allowing Polytrix to find the right file.
107
+
108
+ Polytrix basically does a case-insensitive search for a file whose name matches the scenario name, ignoring subfolders, spaces, prefixes, puctuation and file extension. So these files all match a scenario named "hello world":
109
+ - hello_world.rb
110
+ - src/com/world/HelloWorld.java
111
+ - samples/01_hello_world.go
112
+
113
+ ### Reports and documentation
114
+
115
+ You can use any RSpec formatter with Polytrix, since Polytrix is based on RSpec.
116
+
117
+ There are also some Polytrix specific documentation and report generators. You can generate:
118
+ - Scenario-level reports: Documentation or reports for a single scenario
119
+ - Global reports: Documentation or reports summarizing all tested scenarios
120
+
121
+ The documentatio/reports are generated via a template processing system. Polytrix searches the template directory ('doc-src/' by default) for scenario-level samples using the same logic as in the "Finding samples" section above. It looks for a template matching "index" (e.g. index.md, index.rst, index.html) for the global report.
30
122
 
31
- There is a Vagrantfile in the project. It uses a "DRG" box. There isn't currently a published DRG box, so you'll need to produce your own. You can:
123
+ The templates are processed as ERB. In addition to being able to access the top-level Polytrix API, the following variables are bound:
124
+ | Variable | Description |
125
+ | ---------- | ---------------------------------------- |
126
+ | scenario | The name of the scenario being processed |
127
+ | challenges | One or more Challenge objects containing the scenario configuration and results |
32
128
 
33
- * Comment out `config.vm.box = "drg"` and uncomment the other lines with an alternate box.
34
- * Run `vagrant up`, `vagrant provision`, and then `vagrant package --output drg.box`. These steps will take a while.
35
- * Run `vagrant box add drg drg.box`
36
- * You now have a drg box, and can restore the Vagrant file to it's original state.
129
+ ### Common compliance tests
37
130
 
38
- ### Running tests
131
+ Refactoring... documentation coming soon.
39
132
 
133
+ ### Plugins
40
134
 
135
+ Refactoring... documentation coming soon.
41
136
 
42
- ### (Tenative) Roadmap
43
- * Use standard, shared images (travis-images? vagrantcloud?)
44
- * Integrate with travis-build for .travis.yml support
45
- * Separate Polytrix framework from reference tests
137
+ # Influences
46
138
 
47
- ### BHAG
48
- * Run tests as an interactive course via a browser
139
+ Several projects have influenced ideas in Polytrix. If you find Polytrix interesting or want to contribute, you may want to look at those projects. See influence.md.
data/Rakefile CHANGED
@@ -1,30 +1,19 @@
1
1
  require 'polytrix'
2
2
  require 'bundler/gem_tasks'
3
- require 'rspec/core/rake_task'
4
- require 'pacto/rake_task'
5
3
  require 'rake/notes/rake_task'
6
- require 'highline/import'
7
- require 'json'
8
-
9
- NOT_SETUP = "You need to set RAX_USERNAME and RAX_API_KEY env vars in order to run tests"
4
+ require 'rspec/core/rake_task'
5
+ require 'cucumber'
6
+ require 'cucumber/rake/task'
7
+ require 'rubocop/rake_task'
10
8
 
11
- RSpec::Core::RakeTask.new('features') do |t|
12
- t.rspec_opts = "-I features"
13
- t.pattern = 'features/**/*_spec.rb'
14
- end
9
+ task :default => [:spec, :features, :self, :rubocop]
15
10
 
16
11
  RSpec::Core::RakeTask.new('spec') do |t|
17
12
  t.rspec_opts = "-f documentation"
18
13
  end
19
14
 
20
- task :default => :spec
21
-
22
- desc 'Run all the SDK tests'
23
- task :features => [:check_setup]
24
-
25
- desc 'Check pre-requisites'
26
- task :check_setup do
27
- fail NOT_SETUP unless ENV['RAX_USERNAME'] && ENV['RAX_API_KEY']
15
+ Cucumber::Rake::Task.new(:features) do |t|
16
+ t.cucumber_opts = "features --require features/support --require features/step_definitions"
28
17
  end
29
18
 
30
19
  desc 'Remove reports and other generated artifacts'
@@ -33,111 +22,17 @@ task :clean do
33
22
  FileUtils.rm_rf 'reports'
34
23
  end
35
24
 
36
- desc 'Fetch dependencies for each SDK'
37
- task :bootstrap do
38
- Bundler.with_clean_env do
39
- Dir['sdks/*'].each do |sdk_dir|
40
- Dir.chdir sdk_dir do
41
- if is_windows?
42
- system "PowerShell -NoProfile -ExecutionPolicy Bypass .\\scripts\\bootstrap"
43
- else
44
- system "scripts/bootstrap"
45
- end
46
- end
47
- end
48
- end
49
- end
50
-
51
- desc 'Configure the test framework'
52
- task :setup do
53
- username = ask "Enter your Rackspace Username: "
54
- api_key = ask("Enter your Rackspace API KEY: "){|q| q.echo = "*"}
55
- password = ask("Enter your Rackspace Password (for Packer): "){|q| q.echo = "*"}
56
-
57
- puts "Creating .rbenv-vars"
58
- File.open(".rbenv-vars", 'w') do |f|
59
- f.puts "RAX_USERNAME=#{username}"
60
- f.puts "RAX_API_KEY=#{api_key}"
61
- f.puts
62
- end
63
-
64
- puts "Creating .packer-creds.json"
65
- packer_creds = {
66
- "RAX_USERNAME" => username,
67
- "RAX_PASSWORD" => password
68
- }
69
- File.open(".packer-creds.json", "w") do |f|
70
- f.puts JSON.pretty_generate packer_creds
71
- end
72
- end
73
-
74
- namespace :documentation do
75
- desc 'Generate annoted source code'
76
- task :annotated do
77
- system "groc"
78
- end
79
-
80
- task :copy_src do
81
- sdks = Dir['sdks/*'].each do |sdk|
82
- sdk = File.basename sdk
83
- FileUtils.mkdir_p "docs/src/#{sdk}"
84
- FileUtils.cp_r "sdks/#{sdk}/challenges/", "docs/src/#{sdk}"
85
- end
86
- end
87
-
88
- desc 'Generate the Feature Matrix dashboard'
89
- task :dashboard => [:copy_src, :annotated] do
90
- $: << 'features'
91
- require 'features_helper'
92
- require "matrix_formatter/assets/generator"
93
- require "matrix_formatter/formatters/html5_report_writer"
94
- require 'fileutils'
95
-
96
- asset_generator_options = {
97
- :extra_resource_paths => ['lib/formatter/resources']
98
- }
99
- asset_generator = MatrixFormatter::Assets::Generator.new asset_generator_options
100
- asset_generator.generate
101
-
102
- output = File.open("docs/dashboard.html", 'w')
103
- options = {:view => 'angular.html.slim', :layout => 'default_layout.html.slim'}
104
- formatter = MatrixFormatter::Formatters::HTML5ReportWriter.new output, options
105
- matrix = formatter.parse_results Dir['reports/matrix*.json']
106
- # puts MultiJson.encode formatter.matrix
107
- formatter.write_report
108
- output.close
109
-
110
- fail "Combined results contain failures - check the reports" if formatter.has_failures?
111
- end
112
- end
113
-
114
- desc "Run the tests in parallel, split by SDK. Doesn't work on Windows, but you can use rspec_parallel to split by file instead."
115
- task :parallel_spec do
116
- tags = Dir['sdks/*'].map{|sdk| File.basename sdk}
117
- puts "Detected SDKs: #{tags}"
118
- threads = []
119
- Thread.main[:results] = []
120
- tags.each_with_index do | tag, index |
121
- threads << Thread.new do
122
- puts "Starting #{tag} on process #{index}"
123
- Thread.main[:results] << {
124
- :tag => tag,
125
- :success => sh("TEST_ENV_NUMBER=#{index} bundle exec rspec --options .rspec_parallel -t #{tag} features")
126
- }
127
- end
128
- end
129
- threads.each do |thread|
130
- thread.join
131
- end
132
- end
133
-
134
- namespace :image do
135
- desc 'Build a Rackspace image (using Packer)'
136
- task :rackspace do
137
- system "cd packer; packer build -var-file=../.packer-creds.json -only openstack packer.json"
138
- end
25
+ desc 'Self-test and self-document'
26
+ task :self do
27
+ sh 'bundle exec polytrix bootstrap'
28
+ sh 'bundle exec polytrix test'
29
+ sh 'bundle exec polytrix code2doc samples/sdks/java/challenges/*.java --target-dir=docs/samples/code2doc/java'
30
+ sh 'bundle exec polytrix code2doc samples/sdks/python/challenges/*.py --target-dir=docs/samples/code2doc/python'
31
+ sh 'bundle exec polytrix code2doc samples/sdks/ruby/challenges/*.rb --target-dir=docs/samples/code2doc/ruby'
32
+ # sh 'bundle exec polytrix code2doc samples/*.rb'
139
33
  end
140
34
 
141
- def is_windows?
142
- RbConfig::CONFIG['host_os'] =~ /mswin(\d+)|mingw/i
35
+ Rubocop::RakeTask.new(:rubocop) do |task|
36
+ # abort rake on failure
37
+ task.fail_on_error = true
143
38
  end
data/bin/polytrix ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'polytrix/cli'
3
+
4
+ $LOAD_PATH << 'spec'
5
+ Polytrix::CLI::Main.start
@@ -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,13 @@
1
+ This code will cause Polytrix to bootstrap:
2
+
3
+ <% challenges.compact.each do |challenge| %>
4
+ ``` <%= challenge.implementor.language %>
5
+ <%= File.read(challenge.source_file) %>
6
+ ```
7
+
8
+ And the results will look like:
9
+ ```
10
+ <%= challenge.result.execution_result.stdout %>
11
+ ```
12
+
13
+ <% end %>
@@ -0,0 +1,28 @@
1
+ # Influences
2
+
3
+ This project was influenced by many other projects. The following projects are worth checking out, either as alternatives you might want to use instead of Polytrix, or to understand the domain better before contributing.
4
+
5
+ # Polyglot Testing
6
+
7
+ ## Travis-CI
8
+
9
+ I do not know of any project that is as far along as Travis in terms of making it easy to test projects in most common languages. Currently this project is inspired by Travis, but in the future I hope to re-use Travis components and contribute back to the Travis community.
10
+
11
+ The most important Travis components for Polyglot testing are:
12
+ - [travis-cookbooks](https://github.com/travis-ci/travis-cookbooks) and [travis-images](https://github.com/travis-ci/travis-images) - create environments that are setup for testing any popular language
13
+ - [https://github.com/travis-ci/travis-build](travis-build) - creates scripts that handle setting up the environment for a given platform (Linux, OSX, Windows) and follow language conventions for dependency management and compilation.
14
+
15
+ ## JSON-LD Test Suite and EARL Report
16
+
17
+ I've seen several compliance test suites, but the [JSON-LD suite](http://json-ld.org/test-suite/) is one of my favorites, including the [earl-report](https://github.com/gkellogg/earl-report) gem it uses to create reports.
18
+
19
+ The main difference between Polytrix and JSON-LD's test suite (and similar compliance tests for other projects) is that JSON-LD is data-driven and Polytrix is driven by sample code. The JSON-LD approach is good for standards about a data format like JSON-LD, while Polytrix is more for testing the functional completeness of similar SDKs.
20
+
21
+ ## Codecademy
22
+
23
+ Codecademy's [Course Creation](http://www.codecademy.com/docs/creation) documentation explains how they test code samples written in different languages. You can think of Polytrix as serving a similar function to Codecademy's [Submission Tests](http://www.codecademy.com/docs/submission_tests), with two important differences:
24
+
25
+ - Polytrix aims for a single submission test for all languages: so could share a "Hello, world!" submission correctness test for Ruby, Java, and PHP.
26
+ - Polytrix is being used for automated test suites where the code submissions are pre-written and repeatedly tested, though creating a course with Polytrix may be possible.
27
+
28
+ This of course has some limitations. Since Polytrix is polyglot, we generally test only the effect of running the sample and not the syntax. Polytrix is not suitable for testing each variation when [there's more than one way to do it](http://en.wikipedia.org/wiki/There's_more_than_one_way_to_do_it), but you can use it to test that at least one way is possible.
@@ -0,0 +1,13 @@
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
+ ```java
4
+ public class HelloWorld {
5
+ ```
6
+ A Java CLI application is defined by creating a main method with this signature:
7
+ ```java
8
+ public static void main(String[] args) {
9
+ System.out.println("Hello, world!");
10
+ }
11
+ }
12
+ ```
13
+ [java]: http://en.wikipedia.org/wiki/Java_(programming_language)
@@ -0,0 +1,33 @@
1
+ ```java
2
+ public class Quine
3
+ {
4
+ public static void main(String[] args)
5
+ {
6
+ char q = 34; // Quotation mark character
7
+ String[] l = { // Array of source code
8
+ "public class Quine",
9
+ "{",
10
+ " public static void main(String[] args)",
11
+ " {",
12
+ " char q = 34; // Quotation mark character",
13
+ " String[] l = { // Array of source code",
14
+ " ",
15
+ " };",
16
+ " for(int i = 0; i < 6; i++ ) // Print opening code",
17
+ " System.out.println(l[i]);",
18
+ " for(int i = 0; i < l.length; i++) // Print string array",
19
+ " System.out.println( l[6] + q + l[i] + q + ',' );",
20
+ " for(int i = 7; i < l.length; i++) // Print this code",
21
+ " System.out.println( l[i] );",
22
+ " }",
23
+ "}",
24
+ };
25
+ for(int i = 0; i < 6; i++ ) // Print opening code
26
+ System.out.println(l[i]);
27
+ for(int i = 0; i < l.length; i++) // Print string array
28
+ System.out.println( l[6] + q + l[i] + q + ',' );
29
+ for(int i = 7; i < l.length; i++) // Print this code
30
+ System.out.println( l[i] );
31
+ }
32
+ }
33
+ ```
@@ -0,0 +1,3 @@
1
+ ```py
2
+ print 'Hello, world!'
3
+ ```
@@ -0,0 +1,4 @@
1
+ ```py
2
+ s = 's = %r\nprint(s%%s)'
3
+ print(s%s)
4
+ ```
@@ -0,0 +1,7 @@
1
+ ```rb
2
+ name = 'world'
3
+ ```
4
+ This will print Hello, world!
5
+ ```rb
6
+ puts "Hello, #{name}!"
7
+ ```
@@ -0,0 +1,67 @@
1
+ Feature: Running SDKs
2
+
3
+ Polytrix uses the [script/bootstrap](http://wynnnetherland.com/linked/2013012801/bootstrapping-consistency) pattern to prepare SDKs for testing. You can hook into any package manager, compiler, build tool, or any other toolchain to prepare to build and run samples.
4
+
5
+ Polytrix also sets up tags for the SDKs so you can use the normal rspec `-t` option to select which SDK to run.
6
+
7
+ Scenario: Bootstrap an SDK
8
+ Given the java SDK
9
+ And the empty polytrix config
10
+ And the standard rspec setup
11
+ When I run `bundle exec rspec`
12
+ Then the output should contain ":compileJava"
13
+ And the output should contain "BUILD SUCCESSFUL"
14
+
15
+ Scenario: Running all SDKs
16
+ Given the ruby SDK
17
+ And the java SDK
18
+ And the python SDK
19
+ And the hello_world polytrix config
20
+ And the standard rspec setup
21
+ When I run `bundle exec rspec`
22
+ And the output should contain "3 examples, 0 failures"
23
+
24
+ Scenario: Running a single SDK
25
+ Given the ruby SDK
26
+ And the java SDK
27
+ And the python SDK
28
+ And the hello_world polytrix config
29
+ And the standard rspec setup
30
+ When I run `bundle exec rspec -t ruby`
31
+ Then the output should contain "Hello, world!"
32
+ And the output should contain "1 example, 0 failures"
33
+
34
+ Scenario: Custom assertions
35
+ Given the ruby SDK
36
+ And the java SDK
37
+ And the python SDK
38
+ And the hello_world polytrix config
39
+ And the standard rspec setup
40
+ And a file named "spec/custom_spec.rb" with:
41
+ """
42
+ require 'polytrix/rspec'
43
+
44
+ Polytrix.configure do |polytrix|
45
+ Dir['sdks/*'].each do |sdk|
46
+ polytrix.implementor sdk
47
+ end
48
+ polytrix.test_manifest = 'polytrix_tests.yml'
49
+ end
50
+
51
+ # This is more of an integration test, but makes sure the rspec API is working.
52
+ # Expect results to all be pending, because there's no implementors in this proj.
53
+
54
+ Polytrix.validate(suite: 'Katas', sample: 'hello world') do |challenge|
55
+ # You can make assertions about the process using the Mixlib::ShellOut API
56
+ expect(challenge[:result].execution_result.stdout).to include 'Hello, world!'
57
+ expect(challenge[:result].execution_result.stderr).to be_empty
58
+ expect(challenge[:result].execution_result.exitstatus).to eq(1) # normally this would be 0
59
+ end
60
+
61
+ Polytrix.validate(suite: 'Katas', sample: 'quine') do |challenge|
62
+ expect(challenge[:result].execution_result.stdout).to eq File.read(challenge[:result].source)
63
+ end
64
+ Polytrix.load_tests
65
+ """
66
+ When I run `bundle exec rspec spec/custom_spec.rb`
67
+ And the output should match /expected: 1\s+got: 0/
@@ -0,0 +1,12 @@
1
+ ---
2
+ global_env:
3
+ LOCALE: <%= ENV['LANG'] %>
4
+ FAVORITE_NUMBER: 5
5
+ suites:
6
+ Katas:
7
+ env:
8
+ NAME: 'Max'
9
+ samples:
10
+ Tutorials:
11
+ env:
12
+ samples: