polytrix 0.1.2 → 0.1.3
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.
- checksums.yaml +4 -4
- data/.rubocop-todo.yml +14 -5
- data/Gemfile +2 -1
- data/README.md +139 -177
- data/Rakefile +5 -12
- data/bin/polytrix +0 -1
- data/features/bootstrapping.feature +0 -3
- data/features/cloning.feature +0 -3
- data/features/show.feature +38 -0
- data/features/states.feature +12 -13
- data/features/step_definitions/sdk_steps.rb +0 -4
- data/lib/polytrix/challenge.rb +135 -53
- data/lib/polytrix/challenge_result.rb +0 -2
- data/lib/polytrix/challenge_runner.rb +28 -18
- data/lib/polytrix/cli.rb +53 -69
- data/lib/polytrix/color.rb +2 -2
- data/lib/polytrix/command/action.rb +4 -3
- data/lib/polytrix/command/list.rb +39 -28
- data/lib/polytrix/command/report.rb +9 -86
- data/lib/polytrix/command/reports/code2doc.rb +72 -0
- data/lib/polytrix/command/reports/dashboard.rb +125 -0
- data/lib/polytrix/command/show.rb +148 -0
- data/lib/polytrix/command.rb +37 -104
- data/lib/polytrix/configuration.rb +14 -18
- data/lib/polytrix/{core/hashie.rb → dash.rb} +4 -3
- data/lib/polytrix/documentation/code_segmenter.rb +8 -8
- data/lib/polytrix/documentation/comment_styles.rb +1 -1
- data/lib/polytrix/documentation/helpers/code_helper.rb +9 -0
- data/lib/polytrix/documentation_generator.rb +11 -14
- data/lib/polytrix/error.rb +104 -97
- data/lib/polytrix/executor.rb +33 -0
- data/lib/polytrix/{runners → executors}/buff_shellout_executor.rb +1 -1
- data/lib/polytrix/executors/linux_challenge_executor.rb +29 -0
- data/lib/polytrix/executors/mixlib_shellout_executor.rb +55 -0
- data/lib/polytrix/{runners/windows_challenge_runner.rb → executors/windows_challenge_executor.rb} +4 -11
- data/lib/polytrix/{core/implementor.rb → implementor.rb} +10 -6
- data/lib/polytrix/manifest.rb +2 -31
- data/lib/polytrix/{reports → reporters}/hash_reporter.rb +6 -2
- data/lib/polytrix/{reports → reporters}/json_reporter.rb +2 -2
- data/lib/polytrix/{reports → reporters}/markdown_reporter.rb +7 -2
- data/lib/polytrix/{reports → reporters}/yaml_reporter.rb +2 -2
- data/lib/polytrix/reporters.rb +27 -0
- data/lib/polytrix/result.rb +6 -5
- data/lib/polytrix/spies/file_system_spy.rb +15 -0
- data/lib/polytrix/spies.rb +61 -0
- data/lib/polytrix/state_file.rb +1 -20
- data/lib/polytrix/util.rb +157 -62
- data/lib/polytrix/validation.rb +41 -2
- data/lib/polytrix/validator.rb +9 -4
- data/lib/polytrix/version.rb +1 -1
- data/lib/polytrix.rb +110 -105
- data/polytrix.gemspec +7 -2
- data/polytrix.yml +16 -13
- data/resources/assets/pygments/autumn.css +58 -0
- data/resources/assets/pygments/borland.css +46 -0
- data/resources/assets/pygments/bw.css +34 -0
- data/resources/assets/pygments/colorful.css +61 -0
- data/resources/assets/pygments/default.css +62 -0
- data/resources/assets/pygments/emacs.css +61 -0
- data/resources/assets/pygments/friendly.css +61 -0
- data/resources/assets/pygments/fruity.css +69 -0
- data/resources/assets/pygments/github.css +61 -0
- data/resources/assets/pygments/manni.css +61 -0
- data/resources/assets/pygments/monokai.css +64 -0
- data/resources/assets/pygments/murphy.css +61 -0
- data/resources/assets/pygments/native.css +69 -0
- data/resources/assets/pygments/pastie.css +60 -0
- data/resources/assets/pygments/perldoc.css +58 -0
- data/resources/assets/pygments/tango.css +69 -0
- data/resources/assets/pygments/trac.css +59 -0
- data/resources/assets/pygments/vim.css +69 -0
- data/resources/assets/pygments/vs.css +33 -0
- data/resources/assets/pygments/zenburn.css +1 -0
- data/resources/assets/style.css +41 -0
- data/resources/templates/dashboard/files/dashboard.html.tt +82 -0
- data/resources/templates/dashboard/templates/_test_report.html.tt +87 -0
- data/samples/bootstrap.sh +2 -0
- data/samples/clone.sh +2 -0
- data/samples/code2doc.sh +4 -0
- data/samples/docs/samples/code2doc/java/katas-hello_world-java.md +17 -0
- data/samples/docs/samples/code2doc/java/katas-quine-java.md +35 -0
- data/samples/docs/samples/code2doc/python/katas-hello_world-python.md +5 -0
- data/samples/docs/samples/code2doc/python/katas-quine-python.md +6 -0
- data/samples/docs/samples/code2doc/ruby/katas-hello_world-ruby.md +11 -0
- data/samples/exec.sh +2 -0
- data/samples/polytrix.rb +2 -2
- data/samples/polytrix.yml +5 -2
- data/samples/show.sh +4 -0
- data/samples/test.sh +2 -0
- data/samples/tests/polytrix/validators.rb +2 -2
- data/samples/verify.sh +3 -0
- data/scripts/wrapper +4 -7
- data/spec/fabricators/challenge_fabricator.rb +2 -9
- data/spec/fabricators/implementor_fabricator.rb +0 -8
- data/spec/fabricators/manifest_fabricator.rb +2 -9
- data/spec/fabricators/validator_fabricator.rb +2 -4
- data/spec/polytrix/challenge_runner_spec.rb +20 -0
- data/spec/polytrix/documentation/helpers/code_helper_spec.rb +7 -7
- data/spec/polytrix/file_finder_spec.rb +5 -5
- data/spec/polytrix/manifest_spec.rb +0 -21
- data/spec/polytrix/result_spec.rb +14 -14
- data/spec/polytrix/validator_registry_spec.rb +4 -4
- data/spec/polytrix/validator_spec.rb +9 -9
- data/spec/polytrix_spec.rb +1 -25
- data/spec/spec_helper.rb +8 -1
- metadata +130 -38
- data/features/execution.feature +0 -53
- data/features/fixtures/spec/polytrix_spec.rb +0 -7
- data/lib/polytrix/cli/report.rb +0 -84
- data/lib/polytrix/command/rundoc.rb +0 -27
- data/lib/polytrix/core/file_system_helper.rb +0 -75
- data/lib/polytrix/core/manifest_section.rb +0 -4
- data/lib/polytrix/core/string_helpers.rb +0 -15
- data/lib/polytrix/documentation/view_helper.rb +0 -21
- data/lib/polytrix/rspec/documentation_formatter.rb +0 -66
- data/lib/polytrix/rspec/yaml_report.rb +0 -51
- data/lib/polytrix/rspec.rb +0 -56
- data/lib/polytrix/runners/executor.rb +0 -34
- data/lib/polytrix/runners/linux_challenge_runner.rb +0 -23
- data/lib/polytrix/runners/middleware/change_directory.rb +0 -20
- data/lib/polytrix/runners/middleware/feature_executor.rb +0 -24
- data/lib/polytrix/runners/middleware/setup_env_vars.rb +0 -42
- data/lib/polytrix/runners/mixlib_shellout_executor.rb +0 -83
- data/lib/polytrix/validations.rb +0 -23
- data/samples/scripts/wrapper +0 -7
- data/spec/polytrix/middleware/feature_executor_spec.rb +0 -48
- data/spec/polytrix/validations_spec.rb +0 -16
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<meta charset="UTF-8"/>
|
|
4
|
+
<link data-require="bootstrap-css@*" data-semver="3.0.0" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
|
|
5
|
+
<!-- <link href="style.css" rel="stylesheet"> -->
|
|
6
|
+
<style type="text/css">
|
|
7
|
+
td {
|
|
8
|
+
padding: 7px 10px;
|
|
9
|
+
vertical-align: top;
|
|
10
|
+
text-align: left;
|
|
11
|
+
border: 1px solid #ddd;
|
|
12
|
+
}
|
|
13
|
+
.passed {
|
|
14
|
+
background-color: green;
|
|
15
|
+
}
|
|
16
|
+
.partial {
|
|
17
|
+
background-color: #FF9900;
|
|
18
|
+
}
|
|
19
|
+
.failed {
|
|
20
|
+
background-color: red;
|
|
21
|
+
}
|
|
22
|
+
.pending {
|
|
23
|
+
background-color: LightGrey;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
a:link {
|
|
27
|
+
color: #000000;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* visited link */
|
|
31
|
+
a:visited {
|
|
32
|
+
color: #000000;
|
|
33
|
+
}
|
|
34
|
+
</style>
|
|
35
|
+
</head>
|
|
36
|
+
<body ng-app="main" ng-controller="DemoCtrl">
|
|
37
|
+
<script data-require="angular.js@*" data-semver="1.2.26" src="https://code.angularjs.org/1.2.26/angular.min.js"></script>
|
|
38
|
+
<script data-require="ng-table@*" data-semver="0.3.3" src="http://bazalt-cms.com/assets/ng-table/0.3.0/ng-table.js"></script>
|
|
39
|
+
<link data-require="ng-table@*" data-semver="0.3.3" href="http://bazalt-cms.com/assets/ng-table/0.3.3/ng-table.css" rel="stylesheet">
|
|
40
|
+
<script type="text/javascript">
|
|
41
|
+
var app = angular.module('main', ['ngTable']).
|
|
42
|
+
controller('DemoCtrl', function($scope, $filter, ngTableParams) {
|
|
43
|
+
var data = <%= as_json(results) %>;
|
|
44
|
+
|
|
45
|
+
$scope.tableParams = new ngTableParams({
|
|
46
|
+
page: 1, // show first page
|
|
47
|
+
count: data.length // count per page
|
|
48
|
+
}, {
|
|
49
|
+
counts: [],
|
|
50
|
+
groupBy: 'suite',
|
|
51
|
+
total: data.length,
|
|
52
|
+
getData: function($defer, params) {
|
|
53
|
+
var orderedData = params.sorting() ?
|
|
54
|
+
$filter('orderBy')(data, $scope.tableParams.orderBy()) :
|
|
55
|
+
data;
|
|
56
|
+
|
|
57
|
+
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
})
|
|
61
|
+
</script>
|
|
62
|
+
<table class="table" ng-table="tableParams">
|
|
63
|
+
<tbody ng-repeat="group in $groups">
|
|
64
|
+
<tr class="ng-table-group">
|
|
65
|
+
<td colspan="{{$columns.length}}">
|
|
66
|
+
<a href="" ng-click="group.$hideRows = !group.$hideRows"><span class="glyphicon" ng-class="{ 'glyphicon-chevron-right': group.$hideRows, 'glyphicon-chevron-down': !group.$hideRows }"></span><strong> {{ group.value }} </strong></a>
|
|
67
|
+
</td>
|
|
68
|
+
</tr>
|
|
69
|
+
<tr ng-hide="group.$hideRows" ng-repeat="results in group.data">
|
|
70
|
+
<td data-title="'Scenario'" sortable="scenario">
|
|
71
|
+
{{results.scenario}}
|
|
72
|
+
</td>
|
|
73
|
+
<% implementors.each do |implementor| %>
|
|
74
|
+
<td data-title="'<%= implementor %>'" ng-class="{'passed': results.<%= implementor %>.indexOf('Fully Verified') != -1, 'partial': results.<%= implementor %>.indexOf('Partially Verified') != -1, 'failed': results.<%= implementor %>.indexOf('Failed') != -1 }" sortable="<%= implementor %>">
|
|
75
|
+
<a href="details/{{results.slug_prefix}}-<%= implementor %>.html">{{results.<%= implementor %>}}</a>
|
|
76
|
+
</td>
|
|
77
|
+
<% end %>
|
|
78
|
+
</tr>
|
|
79
|
+
</tbody>
|
|
80
|
+
</table>
|
|
81
|
+
</body>
|
|
82
|
+
</html>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<meta charset="UTF-8"/>
|
|
4
|
+
<link data-require="bootstrap-css@*" data-semver="3.0.0" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
|
|
5
|
+
<link href="assets/pygments/<%= options[:code_style] %>.css" rel="stylesheet" type="text/css">
|
|
6
|
+
<link href="assets/style.css" rel="stylesheet" type="text/css">
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div class="panel panel-<%= bootstrap_color(@challenge.status_color) %>">
|
|
10
|
+
<div class="panel-heading">
|
|
11
|
+
<div class="panel-title">
|
|
12
|
+
<strong>
|
|
13
|
+
<%= @challenge.slug %>
|
|
14
|
+
<span class="label pull-right label-<%= bootstrap_color(@challenge.status_color) %>"><%= @challenge.status_description%></span>
|
|
15
|
+
</strong>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="panel-body">
|
|
19
|
+
<ul class="list-group">
|
|
20
|
+
<li class="list-group-item"><%= status('Test suite:', @challenge.suite) %></li>
|
|
21
|
+
<li class="list-group-item"><%= status('Test scenario:', @challenge.name) %></li>
|
|
22
|
+
<li class="list-group-item"><%= status('Implementor:', @challenge.implementor.name) %></li>
|
|
23
|
+
<% source_file = @challenge.absolute_source_file ? relativize(@challenge.absolute_source_file, Dir.pwd) : '<No code sample>' %>
|
|
24
|
+
<div class="list-group-item">
|
|
25
|
+
<strong class="list-group-item-heading">Code sample</strong>
|
|
26
|
+
<p class="list-group-item-text">
|
|
27
|
+
<% if @challenge.absolute_source_file %>
|
|
28
|
+
<%= @challenge.highlighted_code('html') %>
|
|
29
|
+
<% end %>
|
|
30
|
+
</p>
|
|
31
|
+
</div>
|
|
32
|
+
<% if @challenge.result %>
|
|
33
|
+
<li class="list-group-item">
|
|
34
|
+
<strong class="list-group-item-heading">Execution Results</strong>
|
|
35
|
+
<ul class="list-group">`
|
|
36
|
+
<li class="list-group-item">
|
|
37
|
+
<strong class="list-group-item-heading">Validation Results</strong>
|
|
38
|
+
<ul class="list-group">
|
|
39
|
+
<% @challenge.result.validations.each do |description, result| %>
|
|
40
|
+
<li class="list-group-item <%= result.result %>">
|
|
41
|
+
<strong class="list-group-item-heading"><%= description %></strong>
|
|
42
|
+
<% if result.error %>
|
|
43
|
+
<div class="list-group-item">
|
|
44
|
+
<strong class="list-group-item-heading">Error Message</strong>
|
|
45
|
+
<pre class="list-group-item-text console">
|
|
46
|
+
<%= ansi2html(h result.error.to_s) %>
|
|
47
|
+
</pre>
|
|
48
|
+
</div>
|
|
49
|
+
<div class="list-group-item">
|
|
50
|
+
<strong class="list-group-item-heading">Validator Source</strong>
|
|
51
|
+
<div class="list-group-item-text">
|
|
52
|
+
<%= highlight(result.error_source, language: 'ruby', formatter: 'html') %>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
<% end %>
|
|
56
|
+
</li>
|
|
57
|
+
<% end %>
|
|
58
|
+
</ul>
|
|
59
|
+
</li>
|
|
60
|
+
<li class="list-group-item">
|
|
61
|
+
<strong class="list-group-item-heading">STDOUT</strong>
|
|
62
|
+
<pre class="list-group-item-text console">
|
|
63
|
+
<% if @challenge.result %>
|
|
64
|
+
<code>
|
|
65
|
+
<%= ansi2html(@challenge.result.execution_result.stdout) %>
|
|
66
|
+
</code>
|
|
67
|
+
<% end %>
|
|
68
|
+
</pre>
|
|
69
|
+
</li>
|
|
70
|
+
<li class="list-group-item">
|
|
71
|
+
<strong class="list-group-item-heading">STDERR</strong>
|
|
72
|
+
<pre class="list-group-item-text console">
|
|
73
|
+
<% if @challenge.result %>
|
|
74
|
+
<code>
|
|
75
|
+
<%= ansi2html(@challenge.result.execution_result.stderr) %>
|
|
76
|
+
</code>
|
|
77
|
+
<% end %>
|
|
78
|
+
</p>
|
|
79
|
+
</li>
|
|
80
|
+
</ul>
|
|
81
|
+
</li>
|
|
82
|
+
<% end %>
|
|
83
|
+
</ul>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</body>
|
|
87
|
+
</html>
|
data/samples/clone.sh
ADDED
data/samples/code2doc.sh
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
|
|
4
|
+
```java
|
|
5
|
+
public class HelloWorld {
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
A Java CLI application is defined by creating a main method with this signature:
|
|
9
|
+
|
|
10
|
+
```java
|
|
11
|
+
public static void main(String[] args) {
|
|
12
|
+
System.out.println("Hello, world!");
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
[java]: http://en.wikipedia.org/wiki/Java_(programming_language)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
```java
|
|
3
|
+
public class Quine
|
|
4
|
+
{
|
|
5
|
+
public static void main(String[] args)
|
|
6
|
+
{
|
|
7
|
+
char q = 34; // Quotation mark character
|
|
8
|
+
String[] l = { // Array of source code
|
|
9
|
+
"public class Quine",
|
|
10
|
+
"{",
|
|
11
|
+
" public static void main(String[] args)",
|
|
12
|
+
" {",
|
|
13
|
+
" char q = 34; // Quotation mark character",
|
|
14
|
+
" String[] l = { // Array of source code",
|
|
15
|
+
" ",
|
|
16
|
+
" };",
|
|
17
|
+
" for(int i = 0; i < 6; i++ ) // Print opening code",
|
|
18
|
+
" System.out.println(l[i]);",
|
|
19
|
+
" for(int i = 0; i < l.length; i++) // Print string array",
|
|
20
|
+
" System.out.println( l[6] + q + l[i] + q + ',' );",
|
|
21
|
+
" for(int i = 7; i < l.length; i++) // Print this code",
|
|
22
|
+
" System.out.println( l[i] );",
|
|
23
|
+
" }",
|
|
24
|
+
"}",
|
|
25
|
+
};
|
|
26
|
+
for(int i = 0; i < 6; i++ ) // Print opening code
|
|
27
|
+
System.out.println(l[i]);
|
|
28
|
+
for(int i = 0; i < l.length; i++) // Print string array
|
|
29
|
+
System.out.println( l[6] + q + l[i] + q + ',' );
|
|
30
|
+
for(int i = 7; i < l.length; i++) // Print this code
|
|
31
|
+
System.out.println( l[i] );
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
data/samples/exec.sh
ADDED
data/samples/polytrix.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
require 'polytrix'
|
|
2
2
|
|
|
3
|
-
Polytrix.validate 'Hello world validator', suite: 'Katas',
|
|
3
|
+
Polytrix.validate 'Hello world validator', suite: 'Katas', scenario: 'hello world' do |challenge|
|
|
4
4
|
expect(challenge.result.stdout).to eq "Hello, world!\n"
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
-
Polytrix.validate 'Quine output matches source code', suite: 'Katas',
|
|
7
|
+
Polytrix.validate 'Quine output matches source code', suite: 'Katas', scenario: 'quine' do |challenge|
|
|
8
8
|
expect(challenge.result.stdout).to eq(challenge.source)
|
|
9
9
|
end
|
|
10
10
|
|
data/samples/polytrix.yml
CHANGED
|
@@ -14,8 +14,11 @@
|
|
|
14
14
|
LOCALE: <%= ENV['LANG'] %> # templating is allowed
|
|
15
15
|
suites:
|
|
16
16
|
Katas: # "Katas" is the name of the first test suite
|
|
17
|
-
env: # Unlike global_env, these variables are only for the Katas suite
|
|
18
|
-
COLOR: red
|
|
19
17
|
samples: # Test scenarios within Katas
|
|
20
18
|
- hello world
|
|
21
19
|
- quine
|
|
20
|
+
Environment:
|
|
21
|
+
env: # Unlike global_env, these variables are only for the Katas suite
|
|
22
|
+
COLOR: red
|
|
23
|
+
samples:
|
|
24
|
+
- echo_color
|
data/samples/show.sh
ADDED
data/samples/test.sh
ADDED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
require 'polytrix'
|
|
2
2
|
|
|
3
|
-
Polytrix.validate 'Hello world validator', suite: 'Katas',
|
|
3
|
+
Polytrix.validate 'Hello world validator', suite: 'Katas', scenario: 'hello world' do |challenge|
|
|
4
4
|
expect(challenge.result.stdout).to eq "Hello, world!\n"
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
-
Polytrix.validate 'Quine output matches source code', suite: 'Katas',
|
|
7
|
+
Polytrix.validate 'Quine output matches source code', suite: 'Katas', scenario: 'quine' do |challenge|
|
|
8
8
|
expect(challenge.result.stdout).to eq(challenge.source)
|
|
9
9
|
end
|
|
10
10
|
|
data/samples/verify.sh
ADDED
data/scripts/wrapper
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
else
|
|
6
|
-
bundle exec "$@"
|
|
7
|
-
fi
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# This is a trick to force a pty and capture colored output,
|
|
3
|
+
# because Polytrix does not currently run command with a PTY.
|
|
4
|
+
script -q /dev/null "$@"
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
require 'hashie/mash'
|
|
2
|
-
|
|
3
1
|
# 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
2
|
|
|
11
3
|
Fabricator(:challenge, from: Polytrix::Challenge) do
|
|
12
4
|
initialize_with { @_klass.new to_hash } # Hash based initialization
|
|
13
|
-
name {
|
|
5
|
+
name { SCENARIO_NAMES.sample }
|
|
14
6
|
suite { LANGUAGES.sample }
|
|
15
7
|
source_file { 'spec/fixtures/factorial.py' }
|
|
16
8
|
basedir { 'spec/fixtures' }
|
|
9
|
+
implementor
|
|
17
10
|
end
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
require 'hashie/mash'
|
|
2
|
-
|
|
3
1
|
# Fabricates test manifests (.polytrix.yml files)
|
|
4
|
-
LANGUAGES = %w(java ruby python nodejs c# golang php)
|
|
5
|
-
SAMPLE_NAMES = [
|
|
6
|
-
'hello world',
|
|
7
|
-
'quine',
|
|
8
|
-
'my_kata'
|
|
9
|
-
]
|
|
10
2
|
|
|
11
3
|
Fabricator(:implementor, from: Polytrix::Implementor) do
|
|
12
4
|
initialize_with { @_klass.new to_hash } # Hash based initialization
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
require 'hashie/mash'
|
|
2
2
|
|
|
3
3
|
# Fabricates test manifests (.polytrix.yml files)
|
|
4
|
-
LANGUAGES = %w(java ruby python nodejs c# golang php)
|
|
5
|
-
SAMPLE_NAMES = [
|
|
6
|
-
'hello world',
|
|
7
|
-
'quine',
|
|
8
|
-
'my_kata'
|
|
9
|
-
]
|
|
10
4
|
|
|
11
5
|
Fabricator(:manifest, from: Polytrix::Manifest) do
|
|
12
6
|
initialize_with { @_klass.new to_hash } # Hash based initialization
|
|
@@ -24,10 +18,9 @@ Fabricator(:manifest, from: Polytrix::Manifest) do
|
|
|
24
18
|
suites do |attr|
|
|
25
19
|
suite_count = attr[:suite_count]
|
|
26
20
|
if suite_count
|
|
27
|
-
suites = attr[:suite_count].times.
|
|
21
|
+
suites = attr[:suite_count].times.each_with_object({}) do |i, h|
|
|
28
22
|
name = LANGUAGES[i] ||= "suite_#{i}"
|
|
29
23
|
h[name] = Fabricate(:suite, name: name, sample_count: attr[:samples_per_suite])
|
|
30
|
-
h
|
|
31
24
|
end
|
|
32
25
|
suites
|
|
33
26
|
else
|
|
@@ -44,7 +37,7 @@ Fabricator(:suite, from: Hashie::Mash) do
|
|
|
44
37
|
sample_count = attr[:sample_count]
|
|
45
38
|
if sample_count
|
|
46
39
|
attr[:sample_count].times.map do |i|
|
|
47
|
-
|
|
40
|
+
SCENARIO_NAMES[i] ||= "sample_#{i}"
|
|
48
41
|
end
|
|
49
42
|
else
|
|
50
43
|
nil
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'hashie/mash'
|
|
2
|
-
|
|
3
1
|
Fabricator(:validator, from: Polytrix::Validator) do
|
|
4
2
|
initialize_with do
|
|
5
3
|
callback = @_transient_attributes.delete :callback
|
|
@@ -9,6 +7,6 @@ Fabricator(:validator, from: Polytrix::Validator) do
|
|
|
9
7
|
end # Hash based initialization
|
|
10
8
|
transient description: 'Sample validator'
|
|
11
9
|
transient suite: LANGUAGES.sample
|
|
12
|
-
transient
|
|
13
|
-
transient callback: Proc.new { Proc.new { |
|
|
10
|
+
transient scenario: SCENARIO_NAMES.sample
|
|
11
|
+
transient callback: Proc.new { Proc.new { |_challenge| } } # rubocop:disable Proc
|
|
14
12
|
end
|
|
@@ -10,6 +10,26 @@ module Polytrix
|
|
|
10
10
|
it 'executes a challenge' do
|
|
11
11
|
expect(runner.run_challenge challenge).to be_an_instance_of Result
|
|
12
12
|
end
|
|
13
|
+
|
|
14
|
+
it 'returns a result' do
|
|
15
|
+
expect(runner.run_challenge(challenge)).to be_an_instance_of Polytrix::Result
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'calls the spy chain' do
|
|
19
|
+
spies = double('Spies')
|
|
20
|
+
expect(spies).to receive(:observe).with challenge
|
|
21
|
+
runner.run_challenge(challenge, spies)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Most of this belongs in the ChallengeRunner...
|
|
25
|
+
xit 'finds the challenge' do
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
xit 'setups the env vars' do
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
xit 'gets the command' do
|
|
32
|
+
end
|
|
13
33
|
end
|
|
14
34
|
end
|
|
15
35
|
end
|
|
@@ -4,7 +4,7 @@ module Polytrix
|
|
|
4
4
|
describe CodeHelper do
|
|
5
5
|
let(:challenge) { Fabricate(:challenge, name: 'test', source_file: @source_file) }
|
|
6
6
|
let(:source) do
|
|
7
|
-
%q
|
|
7
|
+
%q(
|
|
8
8
|
# This snippet should not be in the output.
|
|
9
9
|
puts "Random: #{rand}"
|
|
10
10
|
|
|
@@ -13,12 +13,12 @@ module Polytrix
|
|
|
13
13
|
|
|
14
14
|
# Nor should this snippet
|
|
15
15
|
puts 'Done'
|
|
16
|
-
|
|
16
|
+
)
|
|
17
17
|
end
|
|
18
18
|
let(:expected_snippet) do
|
|
19
|
-
|
|
19
|
+
"
|
|
20
20
|
puts 'Hello, world!'
|
|
21
|
-
|
|
21
|
+
"
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
around do | example |
|
|
@@ -48,11 +48,11 @@ module Polytrix
|
|
|
48
48
|
describe '#snippet_between' do
|
|
49
49
|
# Yes, whitespace doesn't work very well w/ snippet_between
|
|
50
50
|
let(:expected_snippet) do
|
|
51
|
-
%q
|
|
51
|
+
%q(
|
|
52
52
|
puts "Random: #{rand}"
|
|
53
53
|
# Snippet: Hello, world!
|
|
54
54
|
puts 'Hello, world!'
|
|
55
|
-
|
|
55
|
+
)
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
it 'inserts all code blocks between the matching regexes' do
|
|
@@ -110,7 +110,7 @@ module Polytrix
|
|
|
110
110
|
end
|
|
111
111
|
yield tmpfiles.map(&:path)
|
|
112
112
|
ensure
|
|
113
|
-
tmpfiles.each
|
|
113
|
+
tmpfiles.each(&:unlink)
|
|
114
114
|
end
|
|
115
115
|
end
|
|
116
116
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module Polytrix
|
|
2
|
-
module
|
|
3
|
-
describe
|
|
2
|
+
module Util
|
|
3
|
+
describe FileSystem do
|
|
4
4
|
subject(:finder) do
|
|
5
|
-
Object.new.extend(Polytrix::
|
|
5
|
+
Object.new.extend(Polytrix::Util::FileSystem)
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
it 'finds files within the search path' do
|
|
@@ -11,8 +11,8 @@ module Polytrix
|
|
|
11
11
|
expect(file.relative_path_from path(search_path)).to eq(path('quine.md.erb'))
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
it 'raises
|
|
15
|
-
expect { finder.find_file 'spec/fixtures/src-doc', 'quinez' }.to raise_error
|
|
14
|
+
it 'raises Errno::ENOENT if no file is found' do
|
|
15
|
+
expect { finder.find_file 'spec/fixtures/src-doc', 'quinez' }.to raise_error Errno::ENOENT
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
private
|
|
@@ -21,27 +21,6 @@ module Polytrix
|
|
|
21
21
|
expect(suite).to be_an_instance_of Polytrix::Manifest::Suite
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
|
-
|
|
25
|
-
describe '#find_suite' do
|
|
26
|
-
before(:each) do
|
|
27
|
-
Polytrix.configuration.manifest = 'samples/polytrix.yml'
|
|
28
|
-
end
|
|
29
|
-
it 'returns nil if no suite matches' do
|
|
30
|
-
suite = subject.find_suite('none')
|
|
31
|
-
expect(suite).to be_nil
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
it 'returns the suite if one is found' do
|
|
35
|
-
suite = subject.find_suite('Katas')
|
|
36
|
-
expect(suite).to be_an_instance_of Polytrix::Manifest::Suite
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
it 'is not case sensitive' do
|
|
40
|
-
suite = subject.find_suite('katas')
|
|
41
|
-
expect(suite).to be_an_instance_of Polytrix::Manifest::Suite
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
24
|
end
|
|
46
25
|
end
|
|
47
26
|
end
|
|
@@ -6,10 +6,10 @@ module Polytrix
|
|
|
6
6
|
context 'mixed pass/fail' do
|
|
7
7
|
let(:subject) do
|
|
8
8
|
Polytrix::Result.new(
|
|
9
|
-
validations:
|
|
10
|
-
|
|
11
|
-
{
|
|
12
|
-
|
|
9
|
+
validations: {
|
|
10
|
+
'max' => { result: 'passed' },
|
|
11
|
+
'polytrix' => { result: 'failed', error: 'foo!' }
|
|
12
|
+
}
|
|
13
13
|
).status
|
|
14
14
|
end
|
|
15
15
|
it 'reports the failed status' do
|
|
@@ -19,11 +19,11 @@ module Polytrix
|
|
|
19
19
|
context 'mix passed/pending/skipped' do
|
|
20
20
|
let(:subject) do
|
|
21
21
|
Polytrix::Result.new(
|
|
22
|
-
validations:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
validations: {
|
|
23
|
+
'max' => { result: 'passed' },
|
|
24
|
+
'polytrix' => { result: 'pending' },
|
|
25
|
+
'john doe' => { result: 'skipped' }
|
|
26
|
+
}
|
|
27
27
|
).status
|
|
28
28
|
end
|
|
29
29
|
it 'reports the passed status' do
|
|
@@ -33,11 +33,11 @@ module Polytrix
|
|
|
33
33
|
context 'mix pending/skipped' do
|
|
34
34
|
let(:subject) do
|
|
35
35
|
Polytrix::Result.new(
|
|
36
|
-
validations:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
validations: {
|
|
37
|
+
'max' => { result: 'pending' },
|
|
38
|
+
'polytrix' => { result: 'pending' },
|
|
39
|
+
'john doe' => { result: 'skipped' }
|
|
40
|
+
}
|
|
41
41
|
).status
|
|
42
42
|
end
|
|
43
43
|
it 'reports the pending status' do
|
|
@@ -10,17 +10,17 @@ module Polytrix
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
expect(registry.validators).to be_empty
|
|
13
|
-
registry.register(Validator.new('dummy', suite: 'java',
|
|
13
|
+
registry.register(Validator.new('dummy', suite: 'java', scenario: 'hello world', &callback))
|
|
14
14
|
validator = registry.validators.first
|
|
15
15
|
expect(validator.suite).to eql('java')
|
|
16
|
-
expect(validator.
|
|
16
|
+
expect(validator.scenario).to eql('hello world')
|
|
17
17
|
expect(validator.instance_variable_get('@callback')).to eql(callback)
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
describe '#validators_for' do
|
|
22
|
-
let(:java_hello_world_validator) { Fabricate(:validator, suite: 'java',
|
|
23
|
-
let(:java_validator) { Fabricate(:validator, suite: 'java',
|
|
22
|
+
let(:java_hello_world_validator) { Fabricate(:validator, suite: 'java', scenario: 'hello world') }
|
|
23
|
+
let(:java_validator) { Fabricate(:validator, suite: 'java', scenario: //) }
|
|
24
24
|
let(:ruby_validator) { Fabricate(:validator, suite: 'ruby') }
|
|
25
25
|
|
|
26
26
|
before do
|