trackler 2.0.6.1 → 2.0.6.2
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/lib/trackler/version.rb +1 -1
- data/tracks/go/exercises/word-count/cases_test.go +23 -4
- data/tracks/go/exercises/word-count/example.go +6 -2
- data/tracks/go/exercises/word-count/word_count.go +1 -1
- data/tracks/go/exercises/word-count/word_count_test.go +1 -1
- data/tracks/pony/.travis.yml +16 -4
- data/tracks/pony/bin/install-deps +12 -0
- data/tracks/pony/bin/test-exercises +22 -0
- data/tracks/ruby/Gemfile +1 -0
- data/tracks/ruby/Rakefile +1 -1
- data/tracks/ruby/bin/generate +4 -29
- data/tracks/ruby/exercises/all-your-base/.meta/.version +1 -0
- data/tracks/ruby/exercises/all-your-base/all_your_base_test.rb +50 -60
- data/tracks/ruby/exercises/all-your-base/example.rb +13 -8
- data/tracks/ruby/exercises/all-your-base/example.tt +17 -0
- data/tracks/ruby/lib/all_your_base_cases.rb +109 -0
- data/tracks/ruby/lib/generator.rb +21 -100
- data/tracks/ruby/lib/generator/command_line.rb +119 -0
- data/tracks/ruby/lib/generator/files.rb +58 -0
- data/tracks/ruby/lib/generator/files/metadata_files.rb +22 -0
- data/tracks/ruby/lib/generator/files/track_files.rb +83 -0
- data/tracks/ruby/lib/generator/git_command.rb +8 -0
- data/tracks/ruby/lib/generator/repository.rb +62 -0
- data/tracks/ruby/lib/generator/template_values.rb +47 -0
- data/tracks/ruby/lib/helper.rb +5 -2
- data/tracks/ruby/test/fixtures/metadata/exercises/alpha/canonical-data.json +8 -9
- data/tracks/ruby/test/fixtures/{exercises → xruby/exercises}/alpha/.meta/.version +0 -0
- data/tracks/ruby/test/fixtures/{exercises → xruby/exercises}/alpha/example.rb +0 -0
- data/tracks/ruby/test/fixtures/xruby/exercises/alpha/example.tt +20 -0
- data/tracks/ruby/test/fixtures/xruby/lib/alpha_cases.rb +20 -0
- data/tracks/ruby/test/fixtures/xruby/lib/beta_cases.rb +0 -0
- data/tracks/ruby/test/generator/command_line_test.rb +83 -0
- data/tracks/ruby/test/generator/files/metadata_files_test.rb +25 -0
- data/tracks/ruby/test/generator/files/track_files_test.rb +117 -0
- data/tracks/ruby/test/generator/files_test.rb +63 -0
- data/tracks/ruby/test/generator/git_command_test.rb +9 -0
- data/tracks/ruby/test/generator/repository_test.rb +98 -0
- data/tracks/ruby/test/generator/template_values_test.rb +59 -0
- data/tracks/ruby/test/generator_test.rb +19 -63
- data/tracks/ruby/test/test_helper.rb +8 -5
- metadata +26 -6
- data/tracks/ruby/test/fixtures/exercises/alpha/alpha_test.rb +0 -1
- data/tracks/ruby/test/fixtures/exercises/alpha/example.tt +0 -1
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Generator
|
4
|
+
module Files
|
5
|
+
module GeneratorCases
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def available(track_path)
|
9
|
+
generator_glob = File.join(track_path, 'lib', '*_cases.rb')
|
10
|
+
Dir[generator_glob].sort.map { |filename| exercise_name(filename) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def filename(exercise_name)
|
14
|
+
"#{exercise_name.tr('-','_')}_cases"
|
15
|
+
end
|
16
|
+
|
17
|
+
def proc_name(exercise_name)
|
18
|
+
filename(exercise_name).split('_').map(&:capitalize).join
|
19
|
+
end
|
20
|
+
|
21
|
+
def exercise_name(filename)
|
22
|
+
%r{([^/]*)_cases\.rb$}.match(filename).captures[0].tr('_','-')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module TrackFiles
|
27
|
+
include Exercise
|
28
|
+
|
29
|
+
def tests_version
|
30
|
+
TestsVersionFile.new(filename: File.join(exercise_path, '.meta', '.version'))
|
31
|
+
end
|
32
|
+
|
33
|
+
def example_solution
|
34
|
+
ExampleSolutionFile.new(filename: File.join(exercise_path, 'example.rb'))
|
35
|
+
end
|
36
|
+
|
37
|
+
def minitest_tests
|
38
|
+
MinitestTestsFile.new(filename: File.join(exercise_path, minitest_tests_filename))
|
39
|
+
end
|
40
|
+
|
41
|
+
def tests_template
|
42
|
+
TestsTemplateFile.new(filename: File.join(exercise_path, 'example.tt'))
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def exercise_path
|
48
|
+
File.join(paths.track, 'exercises', exercise_name)
|
49
|
+
end
|
50
|
+
|
51
|
+
def minitest_tests_filename
|
52
|
+
"#{exercise_name.gsub(/[ -]/, '_')}_test.rb"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class TestsVersionFile < Writable
|
57
|
+
def to_i
|
58
|
+
to_s.to_i
|
59
|
+
end
|
60
|
+
|
61
|
+
def increment
|
62
|
+
save(to_i + 1)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class ExampleSolutionFile < Writable
|
67
|
+
def update_version(version)
|
68
|
+
content = to_s.gsub(/VERSION = \d+/, "VERSION = #{version}")
|
69
|
+
save(content)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class MinitestTestsFile < Writable
|
74
|
+
def generate(template:,values:)
|
75
|
+
content = ERB.new(template, nil, '<>').result values.get_binding
|
76
|
+
save(content)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class TestsTemplateFile < Readable
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module Generator
|
4
|
+
class Repository
|
5
|
+
include Files::TrackFiles
|
6
|
+
include Files::MetadataFiles
|
7
|
+
include TemplateValuesFactory
|
8
|
+
|
9
|
+
def initialize(paths:, exercise_name:)
|
10
|
+
@paths = paths
|
11
|
+
@exercise_name = exercise_name
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :paths, :exercise_name
|
15
|
+
|
16
|
+
def version
|
17
|
+
tests_version.to_i
|
18
|
+
end
|
19
|
+
|
20
|
+
def update_tests_version
|
21
|
+
tests_version.increment
|
22
|
+
end
|
23
|
+
|
24
|
+
def update_example_solution
|
25
|
+
example_solution.update_version(version)
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_tests_file
|
29
|
+
minitest_tests.generate(
|
30
|
+
template: tests_template.to_s,
|
31
|
+
values: template_values
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# A repository that also logs its progress.
|
37
|
+
class LoggingRepository < Repository
|
38
|
+
def initialize(paths:, exercise_name:, logger:)
|
39
|
+
super(paths: paths, exercise_name: exercise_name)
|
40
|
+
@logger = logger
|
41
|
+
end
|
42
|
+
|
43
|
+
def update_tests_version
|
44
|
+
super
|
45
|
+
@logger.info "Incremented tests version to #{version}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def update_example_solution
|
49
|
+
super
|
50
|
+
@logger.info "Updated version in example solution to #{version}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_tests_file
|
54
|
+
super
|
55
|
+
@logger.info "Generated tests for #{exercise_name}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# This exists to give us a clue as to what we are delegating to.
|
60
|
+
class RepositoryDelegator < SimpleDelegator
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Generator
|
2
|
+
# Contains methods accessible to the ERB template
|
3
|
+
class TemplateValues
|
4
|
+
attr_reader :sha1, :version, :test_cases
|
5
|
+
|
6
|
+
def initialize(sha1:, version:, test_cases:)
|
7
|
+
@sha1 = sha1
|
8
|
+
@version = version
|
9
|
+
@test_cases = test_cases
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_binding
|
13
|
+
binding
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module TemplateValuesFactory
|
18
|
+
def template_values
|
19
|
+
# These are needed by the 'ExerciseCases' classes
|
20
|
+
# TODO: move these into the individual classes
|
21
|
+
require 'ostruct'
|
22
|
+
require 'json'
|
23
|
+
require cases_require_name
|
24
|
+
|
25
|
+
# Compensate for the version.next that appears in template files.
|
26
|
+
# TODO: remove the .next from the template files and remove compensation
|
27
|
+
compensated_version = version - 1
|
28
|
+
|
29
|
+
TemplateValues.new(
|
30
|
+
# TODO: rename sha1 to abbreviated_commit_hash
|
31
|
+
sha1: canonical_data.abbreviated_commit_hash,
|
32
|
+
version: compensated_version,
|
33
|
+
test_cases: test_cases_proc.call(canonical_data.to_s)
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def cases_require_name
|
40
|
+
Files::GeneratorCases.filename(exercise_name)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_cases_proc
|
44
|
+
Object.const_get(Files::GeneratorCases.proc_name(exercise_name))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/tracks/ruby/lib/helper.rb
CHANGED
@@ -1,2 +1,5 @@
|
|
1
|
-
|
2
|
-
XRUBY_LIB = File.
|
1
|
+
XRUBY_ROOT = File.join(File.dirname(__FILE__), '..').freeze
|
2
|
+
XRUBY_LIB = File.join(XRUBY_ROOT, 'lib').freeze
|
3
|
+
METADATA_REPOSITORY_PATH = File.join(XRUBY_ROOT, '..', 'x-common').freeze
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift(XRUBY_LIB)
|
@@ -1,11 +1,10 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
}
|
2
|
+
"description": "Test canonical data",
|
3
|
+
"cases": [
|
4
|
+
{
|
5
|
+
"description": "add 2 numbers",
|
6
|
+
"input": [1,1],
|
7
|
+
"expected": 2
|
8
|
+
}
|
9
|
+
]
|
11
10
|
}
|
File without changes
|
File without changes
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'minitest/autorun'
|
5
|
+
require_relative 'alpha'
|
6
|
+
|
7
|
+
# Common test data version: <%= sha1 %>
|
8
|
+
class AlphaTest < Minitest::Test<% test_cases.each do |test_case| %>
|
9
|
+
def <%= test_case.name %>
|
10
|
+
<%= test_case.skip %>
|
11
|
+
string = '<%= test_case.input %>'
|
12
|
+
<%= test_case.assertion %> Alpha.something?(string)
|
13
|
+
end
|
14
|
+
<% end %>
|
15
|
+
<%= IO.read(XRUBY_LIB + '/bookkeeping.md') %>
|
16
|
+
def test_bookkeeping
|
17
|
+
skip
|
18
|
+
assert_equal <%= version.next %>, BookKeeping::VERSION
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class AlphaCase < OpenStruct
|
2
|
+
|
3
|
+
def name
|
4
|
+
format('test_%s', description.downcase.gsub(/[ -]/,'_'))
|
5
|
+
end
|
6
|
+
|
7
|
+
def assertion
|
8
|
+
expected ? 'assert' : 'refute'
|
9
|
+
end
|
10
|
+
|
11
|
+
def skip
|
12
|
+
index.zero? ? '# skip' : 'skip'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
AlphaCases = proc do |data|
|
17
|
+
JSON.parse(data)['cases'].map.with_index do |row, i|
|
18
|
+
AlphaCase.new(row.merge('index' => i))
|
19
|
+
end
|
20
|
+
end
|
File without changes
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
module Generator
|
4
|
+
class CommandLineTest < Minitest::Test
|
5
|
+
FixturePaths = Paths.new(
|
6
|
+
metadata: 'test/fixtures/metadata',
|
7
|
+
track: 'test/fixtures/xruby'
|
8
|
+
)
|
9
|
+
|
10
|
+
def test_parse
|
11
|
+
expected_stderr = 'Exercise name required'
|
12
|
+
assert_output(/Usage:/, /#{expected_stderr}/) do
|
13
|
+
refute CommandLine.new(FixturePaths).parse([])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_invalid_metadata_repository_outputs_message_to_stderr
|
18
|
+
paths = Paths.new(metadata: 'test/fixtures/nonexistent', track: nil)
|
19
|
+
expected_stderr = <<-MESSAGE.gsub(/^ {6}/,'')
|
20
|
+
'x-common' repository not found.
|
21
|
+
Try running the command:
|
22
|
+
git clone https://github.com/exercism/x-common.git "test/fixtures/nonexistent"
|
23
|
+
MESSAGE
|
24
|
+
assert_output nil, /#{expected_stderr}/ do
|
25
|
+
refute CommandLine.new(paths).parse([])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_usage_help
|
30
|
+
args = %w(-h)
|
31
|
+
assert_output(/Usage:/, nil) do
|
32
|
+
refute CommandLine.new(FixturePaths).parse(args)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_usage_help_with_exercise
|
37
|
+
args = %w(-h beta)
|
38
|
+
assert_output(/Usage:/, nil) do
|
39
|
+
refute CommandLine.new(FixturePaths).parse(args)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_usage_help_includes_available_generators
|
44
|
+
args = %w(-h)
|
45
|
+
fake_generators = %w(some fake generator names also-hyphen-ated)
|
46
|
+
Files::GeneratorCases.stub :available, fake_generators do
|
47
|
+
assert_output(/#{fake_generators.sort.join(' ')}/, nil) do
|
48
|
+
refute CommandLine.new(FixturePaths).parse(args)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_validate_missing_generator
|
54
|
+
args = %w(nonexistent)
|
55
|
+
Files::GeneratorCases.stub :available, [] do
|
56
|
+
assert_output(nil, /A generator does not currently exist fo/) do
|
57
|
+
refute CommandLine.new(FixturePaths).parse(args)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_default_options
|
63
|
+
args = %w(beta)
|
64
|
+
Files::GeneratorCases.stub :available, %w(beta) do
|
65
|
+
assert_instance_of UpdateVersionAndGenerateTests, CommandLine.new(FixturePaths).parse(args)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_frozen_option
|
70
|
+
args = %w(-f beta)
|
71
|
+
Files::GeneratorCases.stub :available, %w(beta) do
|
72
|
+
assert_instance_of GenerateTests, CommandLine.new(FixturePaths).parse(args)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_verbose_option
|
77
|
+
args = %w(-v beta)
|
78
|
+
Files::GeneratorCases.stub :available, %w(beta) do
|
79
|
+
assert_instance_of UpdateVersionAndGenerateTests, CommandLine.new(FixturePaths).parse(args)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative '../../test_helper.rb'
|
2
|
+
module Generator
|
3
|
+
module Files
|
4
|
+
class MetadataFilesTest < Minitest::Test
|
5
|
+
FixturePaths = Paths.new(
|
6
|
+
metadata: 'test/fixtures/metadata',
|
7
|
+
track: 'test/fixtures/xruby'
|
8
|
+
)
|
9
|
+
|
10
|
+
class TestMetadataFiles
|
11
|
+
def initialize
|
12
|
+
@paths = FixturePaths
|
13
|
+
@exercise_name = 'alpha'
|
14
|
+
end
|
15
|
+
attr_reader :paths, :exercise_name
|
16
|
+
include MetadataFiles
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_canonical_data
|
20
|
+
subject = TestMetadataFiles.new
|
21
|
+
assert_instance_of CanonicalDataFile, subject.canonical_data
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require_relative '../../test_helper.rb'
|
2
|
+
|
3
|
+
module Generator
|
4
|
+
module Files
|
5
|
+
class GeneratorCasesTest < Minitest::Test
|
6
|
+
def test_no_cases_found
|
7
|
+
track_path = 'test/fixtures/nonexistant'
|
8
|
+
assert_equal [], GeneratorCases.available(track_path)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_cases_found
|
12
|
+
track_path = 'test/fixtures/xruby'
|
13
|
+
assert_equal %w(alpha beta), GeneratorCases.available(track_path).sort
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_available_returns_exercise_names
|
17
|
+
track_path = 'test/fixtures/xruby'
|
18
|
+
Dir.stub :[], %w(/alpha_cases.rb hy_phen_ated_cases.rb) do
|
19
|
+
assert_equal %w(alpha hy-phen-ated), GeneratorCases.available(track_path)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_filename
|
24
|
+
exercise_name = 'two-parter'
|
25
|
+
assert_equal 'two_parter_cases', GeneratorCases.filename(exercise_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_proc_name
|
29
|
+
exercise_name = 'two-parter'
|
30
|
+
assert_equal 'TwoParterCases', GeneratorCases.proc_name(exercise_name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class TrackFilesTest < Minitest::Test
|
35
|
+
FixturePaths = Paths.new(
|
36
|
+
metadata: 'test/fixtures/metadata',
|
37
|
+
track: 'test/fixtures/xruby'
|
38
|
+
)
|
39
|
+
|
40
|
+
class TestTrackFiles
|
41
|
+
def initialize
|
42
|
+
@paths = FixturePaths
|
43
|
+
@exercise_name = 'alpha'
|
44
|
+
end
|
45
|
+
attr_reader :paths, :exercise_name
|
46
|
+
include TrackFiles
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_tests_version
|
50
|
+
subject = TestTrackFiles.new
|
51
|
+
assert_instance_of TestsVersionFile, subject.tests_version
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_example_solution
|
55
|
+
subject = TestTrackFiles.new
|
56
|
+
assert_instance_of ExampleSolutionFile, subject.example_solution
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_minitest_tests
|
60
|
+
subject = TestTrackFiles.new
|
61
|
+
assert_instance_of MinitestTestsFile, subject.minitest_tests
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_tests_template
|
65
|
+
subject = TestTrackFiles.new
|
66
|
+
assert_instance_of TestsTemplateFile, subject.tests_template
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class TestsVersionFileTest < Minitest::Test
|
71
|
+
class TestTestsVersionFile < TestsVersionFile
|
72
|
+
def save(content)
|
73
|
+
content
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_increment
|
78
|
+
subject = TestTestsVersionFile.new(filename: 'test/fixtures/xruby/exercises/alpha/.meta/.version')
|
79
|
+
assert_equal 2, subject.increment
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class ExampleSolutionFileTest < Minitest::Test
|
84
|
+
class TestExampleSolutionFile < ExampleSolutionFile
|
85
|
+
def save(content)
|
86
|
+
content
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_update_version
|
91
|
+
subject = TestExampleSolutionFile.new(filename: 'test/fixtures/xruby/exercises/alpha/example.rb')
|
92
|
+
assert_match(/VERSION = 2/, subject.update_version(2))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
class MinitestTestsFileTest < Minitest::Test
|
97
|
+
class TestMinitestTestsFile < MinitestTestsFile
|
98
|
+
def save(content)
|
99
|
+
content
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_update_version
|
104
|
+
mock_template = Minitest::Mock.new
|
105
|
+
mock_values = Minitest::Mock.new
|
106
|
+
mock_values.expect :get_binding, 'mock binding'
|
107
|
+
mock_erb = Minitest::Mock.new
|
108
|
+
mock_erb.expect :result, 'new content', ['mock binding']
|
109
|
+
|
110
|
+
subject = TestMinitestTestsFile.new(filename: 'test/fixtures/xruby/exercises/alpha/alpha_tests.rb')
|
111
|
+
ERB.stub :new, mock_erb do
|
112
|
+
assert_equal 'new content', subject.generate(template: mock_template, values: mock_values)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|