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.
- checksums.yaml +4 -4
- data/.gitignore +2 -2
- data/.rspec +1 -6
- data/.rubocop-todo.yml +19 -0
- data/.rubocop.yml +10 -0
- data/.travis.yml +11 -0
- data/Gemfile +0 -16
- data/README.md +119 -28
- data/Rakefile +18 -123
- data/bin/polytrix +5 -0
- data/doc-src/_markdown.md +5 -0
- data/doc-src/default_bootstrap.md +13 -0
- data/docs/influences.md +28 -0
- data/docs/samples/code2doc/java/HelloWorld.md +13 -0
- data/docs/samples/code2doc/java/Quine.md +33 -0
- data/docs/samples/code2doc/python/hello_world.md +3 -0
- data/docs/samples/code2doc/python/quine.md +4 -0
- data/docs/samples/code2doc/ruby/hello_world.md +7 -0
- data/features/execution.feature +67 -0
- data/features/fixtures/configs/empty.yml +12 -0
- data/features/fixtures/configs/hello_world.yml +10 -0
- data/features/fixtures/spec/polytrix_merge.rb +5 -0
- data/features/fixtures/spec/polytrix_spec.rb +10 -0
- data/features/reporting.feature +140 -0
- data/features/step_definitions/sdk_steps.rb +12 -0
- data/features/support/env.rb +8 -0
- data/lib/polytrix/challenge.rb +20 -7
- data/lib/polytrix/challenge_runner.rb +9 -44
- data/lib/polytrix/cli/add.rb +67 -0
- data/lib/polytrix/cli/report.rb +88 -0
- data/lib/polytrix/cli/reports/hash_reporter.rb +30 -0
- data/lib/polytrix/cli/reports/json_reporter.rb +14 -0
- data/lib/polytrix/cli/reports/markdown_reporter.rb +23 -0
- data/lib/polytrix/cli/reports/yaml_reporter.rb +14 -0
- data/lib/polytrix/cli.rb +158 -0
- data/lib/polytrix/configuration.rb +65 -4
- data/lib/polytrix/core/file_system_helper.rb +75 -0
- data/lib/polytrix/core/implementor.rb +31 -3
- data/lib/polytrix/documentation/code_segmenter.rb +168 -0
- data/lib/polytrix/documentation/comment_styles.rb +87 -0
- data/lib/polytrix/documentation/helpers/code_helper.rb +85 -0
- data/lib/polytrix/documentation/view_helper.rb +21 -0
- data/lib/polytrix/documentation_generator.rb +59 -10
- data/lib/polytrix/executor.rb +89 -0
- data/lib/polytrix/logger.rb +17 -0
- data/lib/polytrix/manifest.rb +64 -7
- data/lib/polytrix/result.rb +16 -2
- data/lib/polytrix/rspec/documentation_formatter.rb +41 -16
- data/lib/polytrix/rspec/yaml_report.rb +51 -0
- data/lib/polytrix/rspec.rb +32 -53
- data/lib/polytrix/runners/middleware/feature_executor.rb +4 -3
- data/lib/polytrix/runners/middleware/setup_env_vars.rb +6 -4
- data/lib/polytrix/validation.rb +20 -0
- data/lib/polytrix/validations.rb +23 -0
- data/lib/polytrix/validator.rb +20 -0
- data/lib/polytrix/validator_registry.rb +34 -0
- data/lib/polytrix/version.rb +1 -1
- data/lib/polytrix.rb +125 -22
- data/polytrix.gemspec +7 -2
- data/polytrix.rb +6 -0
- data/polytrix_tests.yml +20 -0
- data/resources/code_sample.tt +2 -0
- data/samples/.gitignore +2 -0
- data/samples/_markdown.md +5 -0
- data/samples/default_bootstrap.rb +14 -0
- data/samples/polytrix.rb +28 -0
- data/samples/polytrix_cli.sh +7 -0
- data/samples/polytrix_tests.yml +10 -0
- data/{sdks/fog → samples}/scripts/bootstrap +0 -2
- data/samples/scripts/wrapper +7 -0
- data/samples/sdks/custom/polytrix.yml +2 -0
- data/samples/sdks/java/.gitignore +2 -0
- data/samples/sdks/java/build.gradle +14 -0
- data/samples/sdks/java/challenges/HelloWorld.java +10 -0
- data/samples/sdks/java/challenges/Quine.java +31 -0
- data/samples/sdks/java/code_sample.tt +11 -0
- data/samples/sdks/java/scripts/bootstrap +2 -0
- data/samples/sdks/java/scripts/wrapper +8 -0
- data/samples/sdks/python/challenges/hello_world.py +2 -0
- data/samples/sdks/python/challenges/quine.py +2 -0
- data/{sdks/pkgcloud → samples/sdks/python}/scripts/wrapper +1 -1
- data/samples/sdks/ruby/challenges/hello_world.rb +4 -0
- data/scripts/bootstrap +1 -9
- data/scripts/wrapper +7 -0
- data/spec/fabricators/challenge_fabricator.rb +17 -0
- data/spec/fabricators/manifest_fabricator.rb +50 -0
- data/spec/fabricators/validator_fabricator.rb +12 -0
- data/spec/fixtures/{polytrix.yml → polytrix_tests.yml} +0 -0
- data/spec/fixtures/src-doc/_scenario.md.erb +1 -0
- data/spec/polytrix/challenge_runner_spec.rb +3 -3
- data/spec/polytrix/challenge_spec.rb +3 -4
- data/spec/polytrix/cli_spec.rb +39 -0
- data/spec/polytrix/configuration_spec.rb +45 -1
- data/spec/polytrix/documentation/helpers/code_helper_spec.rb +120 -0
- data/spec/polytrix/documentation_generator_spec.rb +41 -20
- data/spec/polytrix/file_finder_spec.rb +4 -3
- data/spec/polytrix/implementor_spec.rb +33 -0
- data/spec/polytrix/manifest_spec.rb +32 -14
- data/spec/polytrix/middleware/feature_executor_spec.rb +1 -1
- data/spec/polytrix/result_spec.rb +49 -0
- data/spec/polytrix/validations_spec.rb +16 -0
- data/spec/polytrix/validator_registry_spec.rb +39 -0
- data/spec/polytrix/validator_spec.rb +63 -0
- data/spec/polytrix_spec.rb +33 -7
- data/spec/spec_helper.rb +14 -1
- data/spec/thor_spy.rb +64 -0
- metadata +177 -160
- data/.rspec_parallel +0 -10
- data/Vagrantfile +0 -41
- data/features/0_identity_spec.rb +0 -40
- data/features/1_cloud_files_spec.rb +0 -48
- data/features/2_servers_spec.rb +0 -19
- data/features/features_helper.rb +0 -46
- data/features/helpers/cloudfiles_helper.rb +0 -31
- data/features/helpers/pacto_helper.rb +0 -33
- data/features/helpers/teardown_helper.rb +0 -49
- data/features/pacto/extensions/loaders/api_blueprint_loader.rb +0 -63
- data/features/pacto/extensions/loaders/simple_loader.rb +0 -55
- data/features/pacto/extensions/loaders/yaml_or_json_loader.rb +0 -17
- data/features/pacto/extensions/matchers.rb +0 -38
- data/features/phase2/feature_coverage_report.rb +0 -109
- data/features/phase2/run_all_features.rb +0 -14
- data/features/static_site/fixtures/index.html +0 -6
- data/lib/polytrix/challenge_builder.rb +0 -16
- data/lib/polytrix/core/file_finder.rb +0 -43
- data/lib/polytrix/core/result_tracker.rb +0 -25
- data/lib/polytrix/runners/middleware/pacto.rb +0 -59
- data/packer/.gitignore +0 -3
- data/packer/Berksfile +0 -15
- data/packer/Gemfile +0 -5
- data/packer/Vagrantfile +0 -128
- data/packer/cookbooks/drg/metadata.rb +0 -27
- data/packer/cookbooks/drg/recipes/admins.rb +0 -22
- data/packer/cookbooks/drg/recipes/default.rb +0 -9
- data/packer/cookbooks/drg/recipes/dotnet.rb +0 -4
- data/packer/cookbooks/drg/recipes/golang.rb +0 -4
- data/packer/cookbooks/drg/recipes/java.rb +0 -5
- data/packer/cookbooks/drg/recipes/php.rb +0 -10
- data/packer/cookbooks/drg/recipes/ruby.rb +0 -29
- data/packer/cookbooks/drg/recipes/system.rb +0 -13
- data/packer/create_box.sh +0 -10
- data/packer/http/preseed.cfg +0 -87
- data/packer/packer.json +0 -91
- data/packer/scripts/root_setup.sh +0 -37
- data/packer/scripts/setup.sh +0 -32
- data/pacto/config/pacto_server.rb +0 -40
- data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/extensions.json +0 -64
- data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/flavors/id.json +0 -100
- data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/images/id.json +0 -176
- data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/servers/id.json +0 -189
- data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/servers.json +0 -63
- data/pacto/contracts/dns.api.rackspacecloud.com/v1.0/_tenant_id/domains.json +0 -62
- data/pacto/contracts/identity.api.rackspacecloud.com/v2.0/tokens.json +0 -192
- data/pacto/contracts/monitoring.api.rackspacecloud.com/v1.0/_tenant_id/account.json +0 -39
- data/pacto/contracts/ord.autoscale.api.rackspacecloud.com/v1.0/_tenant_id/groups.json +0 -38
- data/pacto/contracts/ord.blockstorage.api.rackspacecloud.com/v1/_tenant_id/volumes.json +0 -30
- data/pacto/contracts/ord.databases.api.rackspacecloud.com/v1.0/_tenant_id/instances.json +0 -30
- data/pacto/contracts/ord.loadbalancers.api.rackspacecloud.com/v1.0/_tenant_id/loadbalancers.json +0 -114
- data/pacto/contracts/ord.queues.api.rackspacecloud.com/v1/_tenant_id/queues.json +0 -13
- data/pacto/contracts/ord.servers.api.rackspacecloud.com/v2/_tenant_id/os-networksv2.json +0 -46
- data/pacto/contracts/ord.servers.api.rackspacecloud.com/v2/_tenant_id/servers/detail.json +0 -230
- data/pacto/contracts/storage101.dfw1.clouddrive.com/v1/mosso_account/container/object.json +0 -15
- data/pacto/contracts/storage101.dfw1.clouddrive.com/v1/mosso_account.json +0 -43
- data/pacto/contracts/storage101.ord1.clouddrive.com/v1/_mosso_id.json +0 -44
- data/pacto/pacto_server.rb +0 -100
- data/pacto/rackspace_uri_map.yaml +0 -229
- data/scripts/cibuild +0 -4
- data/sdks/fog/.gitignore +0 -1
- data/sdks/fog/Gemfile +0 -5
- data/sdks/fog/challenges/all_connections.rb +0 -45
- data/sdks/fog/challenges/authenticate_token.rb +0 -15
- data/sdks/fog/challenges/cdn_enable_container.rb +0 -20
- data/sdks/fog/challenges/create_a_container.rb +0 -17
- data/sdks/fog/challenges/create_server.rb +0 -36
- data/sdks/fog/challenges/get_object_metadata.rb +0 -13
- data/sdks/fog/challenges/list_containers.rb +0 -10
- data/sdks/fog/challenges/provision_scalable_webapp.rb +0 -30
- data/sdks/fog/challenges/upload_folder.rb +0 -25
- data/sdks/fog/scripts/bootstrap.ps1 +0 -1
- data/sdks/fog/scripts/wrapper +0 -2
- data/sdks/fog/scripts/wrapper.ps1 +0 -1
- data/sdks/gophercloud/.gitignore +0 -2
- data/sdks/gophercloud/challenges/authenticate_token.go +0 -23
- data/sdks/gophercloud/scripts/bootstrap +0 -6
- data/sdks/gophercloud/scripts/wrapper +0 -10
- data/sdks/jclouds/.gitignore +0 -1
- data/sdks/jclouds/challenges/AuthenticateToken.java +0 -115
- data/sdks/jclouds/pom.xml +0 -34
- data/sdks/jclouds/scripts/bootstrap +0 -3
- data/sdks/jclouds/scripts/wrapper +0 -7
- data/sdks/openstack.net/.gitignore +0 -4
- data/sdks/openstack.net/.nuget/Microsoft.Build.dll +0 -0
- data/sdks/openstack.net/.nuget/NuGet.Config +0 -6
- data/sdks/openstack.net/.nuget/NuGet.exe +0 -0
- data/sdks/openstack.net/.nuget/NuGet.targets +0 -136
- data/sdks/openstack.net/Challenge.cs +0 -10
- data/sdks/openstack.net/RunChallenge.cs +0 -19
- data/sdks/openstack.net/challenges/AuthenticateToken.cs +0 -24
- data/sdks/openstack.net/challenges/Weird.cs +0 -133
- data/sdks/openstack.net/openstack.net.csproj +0 -58
- data/sdks/openstack.net/openstack.net.sln +0 -27
- data/sdks/openstack.net/openstack.net.userprefs +0 -8
- data/sdks/openstack.net/packages.config +0 -6
- data/sdks/openstack.net/scripts/bootstrap +0 -2
- data/sdks/openstack.net/scripts/bootstrap.ps1 +0 -2
- data/sdks/openstack.net/scripts/wrapper +0 -7
- data/sdks/openstack.net/scripts/wrapper.ps1 +0 -1
- data/sdks/php-opencloud/.gitignore +0 -4
- data/sdks/php-opencloud/challenges/all_connections.php +0 -64
- data/sdks/php-opencloud/challenges/authenticate_token.php +0 -14
- data/sdks/php-opencloud/challenges/create_server.php +0 -39
- data/sdks/php-opencloud/challenges/get_object_metadata.php +0 -19
- data/sdks/php-opencloud/composer.json +0 -5
- data/sdks/php-opencloud/scripts/bootstrap +0 -4
- data/sdks/php-opencloud/scripts/bootstrap.ps1 +0 -2
- data/sdks/php-opencloud/scripts/wrapper +0 -2
- data/sdks/php-opencloud/scripts/wrapper.ps1 +0 -1
- data/sdks/pkgcloud/.gitignore +0 -1
- data/sdks/pkgcloud/challenges/authenticate_token.js +0 -17
- data/sdks/pkgcloud/challenges/get_object_metadata.js +0 -18
- data/sdks/pkgcloud/scripts/bootstrap +0 -2
- data/sdks/pkgcloud/scripts/bootstrap.ps1 +0 -1
- data/sdks/pkgcloud/scripts/wrapper.ps1 +0 -1
- data/sdks/pyrax/.gitignore +0 -2
- data/sdks/pyrax/challenges/all_connections.py +0 -61
- data/sdks/pyrax/challenges/authenticate_token.py +0 -17
- data/sdks/pyrax/challenges/cdn_enable_container.py +0 -22
- data/sdks/pyrax/challenges/create_a_container.py +0 -21
- data/sdks/pyrax/challenges/create_server.py +0 -35
- data/sdks/pyrax/challenges/get_object_metadata.py +0 -17
- data/sdks/pyrax/challenges/upload_folder.py +0 -32
- data/sdks/pyrax/requirements.txt +0 -21
- data/sdks/pyrax/scripts/bootstrap +0 -9
- data/sdks/pyrax/scripts/bootstrap.ps1 +0 -7
- data/sdks/pyrax/scripts/wrapper +0 -3
- data/sdks/pyrax/scripts/wrapper.ps1 +0 -2
- data/spec/polytrix/challenge_builder_spec.rb +0 -16
- data/spec/rspec_spec.rb +0 -17
@@ -0,0 +1,50 @@
|
|
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(:manifest, from: Polytrix::Manifest) do
|
12
|
+
initialize_with { @_klass.new to_hash } # Hash based initialization
|
13
|
+
transient suite_count: 3
|
14
|
+
transient samples_per_suite: 3
|
15
|
+
global_env do
|
16
|
+
{
|
17
|
+
VAR1: 1,
|
18
|
+
VAR2: 2
|
19
|
+
}
|
20
|
+
end
|
21
|
+
suites do |attr|
|
22
|
+
suite_count = attr[:suite_count]
|
23
|
+
if suite_count
|
24
|
+
suites = attr[:suite_count].times.reduce({}) do |h, i|
|
25
|
+
name = LANGUAGES[i] ||= "suite_#{i}"
|
26
|
+
h[name] = Fabricate(:suite, name: name, sample_count: attr[:samples_per_suite])
|
27
|
+
h
|
28
|
+
end
|
29
|
+
suites
|
30
|
+
else
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
Fabricator(:suite, from: Hashie::Mash) do
|
37
|
+
initialize_with { @_klass.new to_hash } # Hash based initialization
|
38
|
+
transient name: LANGUAGES[0]
|
39
|
+
transient sample_count: 3
|
40
|
+
samples do |attr|
|
41
|
+
sample_count = attr[:sample_count]
|
42
|
+
if sample_count
|
43
|
+
attr[:sample_count].times.map do |i|
|
44
|
+
SAMPLE_NAMES[i] ||= "sample_#{i}"
|
45
|
+
end
|
46
|
+
else
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'hashie/mash'
|
2
|
+
|
3
|
+
Fabricator(:validator, from: Polytrix::Validator) do
|
4
|
+
initialize_with do
|
5
|
+
callback = @_transient_attributes.delete :callback
|
6
|
+
scope = @_transient_attributes
|
7
|
+
@_klass.new(scope, &callback)
|
8
|
+
end # Hash based initialization
|
9
|
+
transient suite: LANGUAGES.sample
|
10
|
+
transient sample: SAMPLE_NAMES.sample
|
11
|
+
transient callback: Proc.new { Proc.new { |challenge| } } # rubocop:disable Proc
|
12
|
+
end
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
I am a generic template that is being used for the <%= scenario %> scenario.
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Polytrix
|
2
2
|
describe ChallengeRunner do
|
3
|
-
subject(:runner) { ChallengeRunner.
|
3
|
+
subject(:runner) { ChallengeRunner.create_runner }
|
4
4
|
let(:challenge) do
|
5
|
-
|
5
|
+
Fabricate(:challenge, name: 'factorial', source_file: 'spec/fixtures/factorial.py', basedir: 'spec/fixtures')
|
6
6
|
end
|
7
7
|
|
8
8
|
describe '#run_challenge' do
|
@@ -11,4 +11,4 @@ module Polytrix
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
14
|
-
end
|
14
|
+
end
|
@@ -1,9 +1,8 @@
|
|
1
1
|
module Polytrix
|
2
2
|
describe Challenge do
|
3
3
|
subject(:challenge) do
|
4
|
-
implementor = Polytrix::Implementor.new :
|
5
|
-
|
6
|
-
builder.build :name => 'factorial', :vars => {}
|
4
|
+
implementor = Polytrix::Implementor.new name: 'some_sdk', basedir: 'spec/fixtures'
|
5
|
+
implementor.build_challenge name: 'factorial', vars: {}
|
7
6
|
end
|
8
7
|
|
9
8
|
describe '#run' do
|
@@ -17,4 +16,4 @@ module Polytrix
|
|
17
16
|
end
|
18
17
|
end
|
19
18
|
end
|
20
|
-
end
|
19
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'polytrix/cli'
|
3
|
+
|
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
|
16
|
+
end
|
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
|
29
|
+
end
|
30
|
+
|
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
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -3,8 +3,52 @@ module Polytrix
|
|
3
3
|
subject(:configuration) { Configuration.new }
|
4
4
|
|
5
5
|
it 'creates a logger' do
|
6
|
-
expect(configuration.logger).to be_kind_of Logger
|
6
|
+
expect(configuration.logger).to be_kind_of ::Logger
|
7
7
|
end
|
8
8
|
|
9
|
+
describe '.test_manifest' do
|
10
|
+
it 'parses the YAML file and registers the manifest' do
|
11
|
+
original_manifest = configuration.test_manifest
|
12
|
+
configuration.test_manifest = 'spec/fixtures/polytrix_tests.yml'
|
13
|
+
new_manifest = configuration.test_manifest
|
14
|
+
expect(original_manifest).to_not eq(new_manifest)
|
15
|
+
expect(new_manifest).to(be_an_instance_of(Polytrix::Manifest))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '.implementor' do
|
20
|
+
context 'argument is a Hash' do
|
21
|
+
it 'creates and registers Implementors' do
|
22
|
+
# This'd be a bit nicer w/ rspec 3...
|
23
|
+
expect do
|
24
|
+
configuration.implementor name: 'test', basedir: '.'
|
25
|
+
end.to change {
|
26
|
+
configuration.implementors
|
27
|
+
}.from(be_empty).to be_an_instance_of(Array)
|
28
|
+
|
29
|
+
expect(configuration.implementors.first).to be_an_instance_of Polytrix::Implementor
|
30
|
+
expect(configuration.implementors.first.name).to eq('test')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
context 'argument is a String' do
|
34
|
+
context 'directory exists' do
|
35
|
+
context 'polytrix.yml does not exist' do
|
36
|
+
it 'builds an implementor with default settings' do
|
37
|
+
implementor = configuration.implementor('samples/sdks/ruby')
|
38
|
+
expect(implementor).to be_an_instance_of(Polytrix::Implementor)
|
39
|
+
expect(implementor.name).to eq('ruby') # directory name
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'polytrix_tests.yml exists' do
|
44
|
+
it 'loads settings from polytrix.yml' do
|
45
|
+
implementor = configuration.implementor('samples/sdks/custom')
|
46
|
+
expect(implementor).to be_an_instance_of(Polytrix::Implementor)
|
47
|
+
expect(implementor.name).to eq('My Custom project')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
9
53
|
end
|
10
54
|
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Polytrix
|
2
|
+
module Documentation
|
3
|
+
module Helpers
|
4
|
+
describe CodeHelper do
|
5
|
+
let(:challenge) { Fabricate(:challenge, name: 'test', source_file: @source_file) }
|
6
|
+
let(:source) do
|
7
|
+
%q[
|
8
|
+
# This snippet should not be in the output.
|
9
|
+
puts "Random: #{rand}"
|
10
|
+
|
11
|
+
# Snippet: Hello, world!
|
12
|
+
puts 'Hello, world!'
|
13
|
+
|
14
|
+
# Nor should this snippet
|
15
|
+
puts 'Done'
|
16
|
+
]
|
17
|
+
end
|
18
|
+
let(:expected_snippet) do
|
19
|
+
%q[
|
20
|
+
puts 'Hello, world!'
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
around do | example |
|
25
|
+
with_files(source: source) do | files |
|
26
|
+
@source_file = files.first
|
27
|
+
example.run
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#snippet_after' do
|
32
|
+
it 'returns the code block after the match (string)' do
|
33
|
+
snippet = challenge.snippet_after 'Snippet: Hello, world!'
|
34
|
+
expect(snippet.strip).to eq(expected_snippet.strip)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'returns the code block after the match (regex)' do
|
38
|
+
snippet = challenge.snippet_after(/Snippet: .*/)
|
39
|
+
expect(snippet.strip).to eq(expected_snippet.strip)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns nothing if no match is found' do
|
43
|
+
snippet = challenge.snippet_after 'Nothing matches'
|
44
|
+
expect(snippet).to be_empty
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#snippet_between' do
|
49
|
+
# Yes, whitespace doesn't work very well w/ snippet_between
|
50
|
+
let(:expected_snippet) do
|
51
|
+
%q[
|
52
|
+
puts "Random: #{rand}"
|
53
|
+
# Snippet: Hello, world!
|
54
|
+
puts 'Hello, world!'
|
55
|
+
]
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'inserts all code blocks between the matching regexes' do
|
59
|
+
snippet = challenge.snippet_between 'This snippet should not be in the output', 'Nor should this snippet'
|
60
|
+
expect(snippet.strip).to eq(expected_snippet.strip)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'inserts nothing unless both matches are found' do
|
64
|
+
# Neither match
|
65
|
+
snippet = challenge.snippet_between 'foo', 'bar'
|
66
|
+
expect(snippet.strip).to be_empty
|
67
|
+
|
68
|
+
# First matches
|
69
|
+
snippet = challenge.snippet_between 'This snippet should not be in the output', 'foo'
|
70
|
+
expect(snippet.strip).to be_empty
|
71
|
+
|
72
|
+
# Last matches
|
73
|
+
snippet = challenge.snippet_between 'foo', 'Nor should this snippet'
|
74
|
+
expect(snippet.strip).to be_empty
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '#code_block' do
|
80
|
+
it 'generates markdown code blocks by default' do
|
81
|
+
expected = "```ruby\n" + source + "\n```\n"
|
82
|
+
code_block = challenge.code_block(challenge.source, 'ruby')
|
83
|
+
expect(code_block).to eq(expected)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'generates rst for format :rst' do
|
87
|
+
indented_source = source.lines.map do|line|
|
88
|
+
" #{line}"
|
89
|
+
end.join("\n")
|
90
|
+
expected = ".. code-block:: ruby\n" + indented_source + "\n"
|
91
|
+
code_block = challenge.code_block(challenge.source, 'ruby', format: :rst)
|
92
|
+
expect(code_block).to eq(expected)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def generate_doc_for(template_file, source_file)
|
97
|
+
doc_gen = DocumentationGenerator.new(template_file, 'testing')
|
98
|
+
challenge = Fabricate(:challenge, name: 'test', source_file: source_file)
|
99
|
+
doc_gen.process(challenge)
|
100
|
+
end
|
101
|
+
|
102
|
+
def with_files(files)
|
103
|
+
tmpfiles = []
|
104
|
+
begin
|
105
|
+
files.each do |k, v|
|
106
|
+
file = Tempfile.new(k.to_s)
|
107
|
+
file.write(v)
|
108
|
+
file.close
|
109
|
+
tmpfiles << file
|
110
|
+
end
|
111
|
+
yield tmpfiles.map(&:path)
|
112
|
+
ensure
|
113
|
+
tmpfiles.each { |tmpfile| tmpfile.unlink }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -1,35 +1,56 @@
|
|
1
1
|
module Polytrix
|
2
2
|
describe DocumentationGenerator do
|
3
|
-
let(:
|
3
|
+
let(:scenario_name) { 'Quine' }
|
4
|
+
# let(:search_path) { 'spec/fixtures/src-doc' }
|
4
5
|
let(:bound_data) { double }
|
5
|
-
subject(:generator) { DocumentationGenerator.new(search_path) }
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
describe 'process' do
|
8
|
+
let(:generated_doc) { generator.process bound_data }
|
9
|
+
|
10
|
+
context 'when template is readable' do
|
11
|
+
subject(:generator) { DocumentationGenerator.new('spec/fixtures/src-doc/quine.md.erb', scenario_name) }
|
12
|
+
|
13
|
+
it 'processes the template' do
|
14
|
+
expect(generated_doc).to include 'Examples for Quine scenario:'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when template is not readable' do
|
19
|
+
subject(:generator) { DocumentationGenerator.new('non_existant_file.md', scenario_name) }
|
20
|
+
it 'processes the template' do
|
21
|
+
expect(generated_doc).to be_nil
|
22
|
+
end
|
10
23
|
end
|
11
24
|
end
|
12
25
|
|
13
|
-
|
26
|
+
describe 'code2doc' do
|
27
|
+
subject(:generator) { DocumentationGenerator.new }
|
14
28
|
|
15
|
-
let(:
|
29
|
+
let(:source_code) do
|
30
|
+
<<-eos.gsub(/^( |\t)+/, '')
|
31
|
+
#!/usr/bin/env ruby
|
16
32
|
|
17
|
-
|
18
|
-
|
33
|
+
# Comments are documentation
|
34
|
+
puts 'And this is a code block'
|
35
|
+
eos
|
19
36
|
end
|
20
37
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
fail 'This test requires implementors' unless Polytrix.implementors
|
38
|
+
let(:source_file) do
|
39
|
+
file = Tempfile.new(['source', '.rb'])
|
40
|
+
file.write source_code
|
41
|
+
file.close
|
42
|
+
file.path
|
43
|
+
end
|
28
44
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
45
|
+
it 'converts source code to documentation' do
|
46
|
+
expect(generator.code2doc(source_file, 'ruby')).to eq(
|
47
|
+
<<-eos.gsub(/^( |\t)+/, '')
|
48
|
+
Comments are documentation
|
49
|
+
```ruby
|
50
|
+
puts 'And this is a code block'
|
51
|
+
```
|
52
|
+
eos
|
53
|
+
)
|
33
54
|
end
|
34
55
|
end
|
35
56
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Polytrix
|
2
2
|
module Core
|
3
|
-
describe
|
3
|
+
describe FileSystemHelper do
|
4
4
|
subject(:finder) do
|
5
|
-
Object.new.extend(Polytrix::Core::
|
5
|
+
Object.new.extend(Polytrix::Core::FileSystemHelper)
|
6
6
|
end
|
7
7
|
|
8
8
|
it 'finds files within the search path' do
|
@@ -12,10 +12,11 @@ module Polytrix
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'raises FileNotFound except if a file is not found' do
|
15
|
-
expect { finder.find_file 'spec/fixtures/src-doc', 'quinez' }.to raise_error
|
15
|
+
expect { finder.find_file 'spec/fixtures/src-doc', 'quinez' }.to raise_error FileSystemHelper::FileNotFound
|
16
16
|
end
|
17
17
|
|
18
18
|
private
|
19
|
+
|
19
20
|
def path(p)
|
20
21
|
Pathname.new p
|
21
22
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Polytrix
|
4
|
+
describe Implementor do
|
5
|
+
subject(:implementor) { described_class.new(name: 'test', language: 'ruby', basedir: 'sdks/test') }
|
6
|
+
let(:executor) { double('executor') }
|
7
|
+
|
8
|
+
before do
|
9
|
+
subject.executor = executor
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#bootstrap' do
|
13
|
+
it 'executes script/bootstrap' do
|
14
|
+
expect(executor).to receive(:execute).with('./scripts/bootstrap', cwd: Pathname.new(File.absolute_path('sdks/test')), prefix: 'test')
|
15
|
+
implementor.bootstrap
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#build_challenge' do
|
20
|
+
subject(:implementor) { Polytrix::Implementor.new name: 'some_sdk', basedir: File.absolute_path('spec/fixtures') }
|
21
|
+
let(:challenge) { Fabricate(:challenge, name: 'factorial', vars: {}) }
|
22
|
+
|
23
|
+
it 'builds a Challenge' do
|
24
|
+
expect(challenge).to be_an_instance_of Polytrix::Challenge
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'finds the source' do
|
28
|
+
expected_file = Pathname.new 'spec/fixtures/factorial.py'
|
29
|
+
expect(challenge.source_file).to eq(expected_file)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,26 +1,44 @@
|
|
1
1
|
module Polytrix
|
2
|
-
|
3
|
-
describe
|
4
|
-
|
5
|
-
subject(:manifest) { described_class.from_yaml 'spec/fixtures/polytrix.yml' }
|
2
|
+
describe Manifest do
|
3
|
+
describe '#from_yaml' do
|
4
|
+
subject(:manifest) { described_class.from_yaml 'spec/fixtures/polytrix_tests.yml' }
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
it 'initializes a manifest' do
|
7
|
+
expect(manifest).to be_an_instance_of Polytrix::Manifest
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
it 'processes ERB' do
|
11
|
+
expect(manifest.global_env['LOCALE']).to eq(ENV['LANG'])
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'parses global_env' do
|
15
|
+
expect(manifest.global_env).to be_an_instance_of Polytrix::Manifest::Environment
|
16
|
+
end
|
14
17
|
|
15
|
-
|
16
|
-
|
18
|
+
it 'parses suites' do
|
19
|
+
expect(manifest.suites).to be_an_instance_of Polytrix::Manifest::Suites
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#find_suite' do
|
23
|
+
before(:each) do
|
24
|
+
Polytrix.configuration.test_manifest = 'samples/polytrix_tests.yml'
|
25
|
+
end
|
26
|
+
it 'returns nil if no suite matches' do
|
27
|
+
suite = subject.find_suite('none')
|
28
|
+
expect(suite).to be_nil
|
17
29
|
end
|
18
30
|
|
19
|
-
it '
|
20
|
-
|
31
|
+
it 'returns the suite if one is found' do
|
32
|
+
suite = subject.find_suite('Katas')
|
33
|
+
expect(suite).to be_an_instance_of Polytrix::Manifest::Suite
|
21
34
|
end
|
22
35
|
|
36
|
+
it 'is not case sensitive' do
|
37
|
+
suite = subject.find_suite('katas')
|
38
|
+
expect(suite).to be_an_instance_of Polytrix::Manifest::Suite
|
39
|
+
end
|
23
40
|
end
|
41
|
+
|
24
42
|
end
|
25
43
|
end
|
26
44
|
end
|
@@ -19,7 +19,7 @@ module Polytrix
|
|
19
19
|
|
20
20
|
before do
|
21
21
|
allow(challenge_runner).to receive(:challenge_command).with(env[:env_file], Pathname.new('test.js')).and_return('some command to execute')
|
22
|
-
allow(challenge_runner).to receive(:run_command).with('some command to execute').and_return Polytrix::Result.new(
|
22
|
+
allow(challenge_runner).to receive(:run_command).with('some command to execute').and_return Polytrix::Result.new(execution_result: 'a', source_file: 'b')
|
23
23
|
allow(app).to receive(:call).with(env)
|
24
24
|
end
|
25
25
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Polytrix
|
4
|
+
describe Result do
|
5
|
+
describe '#status' do
|
6
|
+
context 'mixed pass/fail' do
|
7
|
+
let(:subject) do
|
8
|
+
Polytrix::Result.new(
|
9
|
+
validations: [
|
10
|
+
{ validated_by: 'max', result: 'passed' },
|
11
|
+
{ validated_by: 'polytrix', result: 'failed' }
|
12
|
+
]
|
13
|
+
).status
|
14
|
+
end
|
15
|
+
it 'reports the failed status' do
|
16
|
+
is_expected.to eq('failed')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
context 'mix passed/pending/skipped' do
|
20
|
+
let(:subject) do
|
21
|
+
Polytrix::Result.new(
|
22
|
+
validations: [
|
23
|
+
{ validated_by: 'max', result: 'passed' },
|
24
|
+
{ validated_by: 'polytrix', result: 'pending' },
|
25
|
+
{ validated_by: 'john doe', result: 'skipped' }
|
26
|
+
]
|
27
|
+
).status
|
28
|
+
end
|
29
|
+
it 'reports the passed status' do
|
30
|
+
is_expected.to eq('passed')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
context 'mix pending/skipped' do
|
34
|
+
let(:subject) do
|
35
|
+
Polytrix::Result.new(
|
36
|
+
validations: [
|
37
|
+
{ validated_by: 'max', result: 'pending' },
|
38
|
+
{ validated_by: 'polytrix', result: 'pending' },
|
39
|
+
{ validated_by: 'john doe', result: 'skipped' }
|
40
|
+
]
|
41
|
+
).status
|
42
|
+
end
|
43
|
+
it 'reports the pending status' do
|
44
|
+
is_expected.to eq('pending')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Polytrix
|
4
|
+
describe Validations do
|
5
|
+
describe '#coerce' do
|
6
|
+
it 'accepts an array when built via Result' do
|
7
|
+
Polytrix::Result.new(
|
8
|
+
validations: [
|
9
|
+
{ validated_by: 'max', result: 'passed' },
|
10
|
+
{ validated_by: 'polytrix', result: 'skipped' }
|
11
|
+
]
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Polytrix
|
2
|
+
describe 'ValidatorRegistry' do
|
3
|
+
subject(:registry) { Polytrix::ValidatorRegistry }
|
4
|
+
|
5
|
+
describe '#register' do
|
6
|
+
it 'registers a validator' do
|
7
|
+
callback = proc do |challenge|
|
8
|
+
expect(challenge[:result].execution_result.exitstatus).to eq(0)
|
9
|
+
end
|
10
|
+
|
11
|
+
expect(registry.validators).to be_empty
|
12
|
+
registry.register suite: 'java', sample: 'hello world', &callback
|
13
|
+
validator = registry.validators.first
|
14
|
+
expect(validator.suite).to eql('java')
|
15
|
+
expect(validator.sample).to eql('hello world')
|
16
|
+
expect(validator.instance_variable_get('@callback')).to eql(callback)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#validators_for' do
|
21
|
+
let(:java_hello_world_validator) { Fabricate(:validator, suite: 'java', sample: 'hello world') }
|
22
|
+
let(:java_validator) { Fabricate(:validator, suite: 'java', sample: //) }
|
23
|
+
let(:ruby_validator) { Fabricate(:validator, suite: 'ruby') }
|
24
|
+
|
25
|
+
before do
|
26
|
+
registry.register(java_hello_world_validator)
|
27
|
+
registry.register(java_validator)
|
28
|
+
registry.register(ruby_validator)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns registered validators that match the scope of the challenge' do
|
32
|
+
challenge = Fabricate(:challenge, suite: 'java', name: 'hello world')
|
33
|
+
validators = registry.validators_for challenge
|
34
|
+
expect(validators).to include(java_hello_world_validator, java_validator)
|
35
|
+
expect(validators).to_not include(ruby_validator)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|