trackler 2.0.1.1 → 2.0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/update +4 -0
- data/common/exercises/minesweeper/canonical-data.json +3 -3
- data/fixtures/common/exercises/imbe/description.md +2 -0
- data/fixtures/common/exercises/imbe/metadata.yml +3 -0
- data/fixtures/common/exercises/no-metadata/description.md +1 -0
- data/fixtures/tracks/fruit/exercises/imbe/.meta/everything_in_meta_is_ignored.txt +0 -0
- data/fixtures/tracks/fruit/exercises/imbe/CaSe_iNSeNSiTiVe_eXaMPLe.TXT +0 -0
- data/fixtures/tracks/fruit/exercises/imbe/HINTS.md +1 -0
- data/fixtures/tracks/fruit/exercises/imbe/also_an_example.txt +1 -0
- data/fixtures/tracks/fruit/exercises/imbe/example.ext +1 -0
- data/fixtures/tracks/fruit/exercises/imbe/imbe.txt +1 -0
- data/lib/trackler/file_bundle.rb +27 -9
- data/lib/trackler/implementation.rb +7 -6
- data/lib/trackler/problem.rb +62 -37
- data/lib/trackler/version.rb +1 -1
- data/tracks/c/config.json +9 -0
- data/tracks/c/exercises/series/makefile +16 -0
- data/tracks/c/exercises/series/src/example.c +24 -0
- data/tracks/c/exercises/series/src/series.h +28 -0
- data/tracks/c/exercises/series/test/test_series.c +63 -0
- data/tracks/c/exercises/series/test/vendor/unity.c +1300 -0
- data/tracks/c/exercises/series/test/vendor/unity.h +274 -0
- data/tracks/c/exercises/series/test/vendor/unity_internals.h +701 -0
- data/tracks/crystal/src/generator/exercises/binary.cr +3 -3
- data/tracks/crystal/src/generator/exercises/forth.cr +3 -3
- data/tracks/crystal/src/generator/exercises/hello_world.cr +1 -1
- data/tracks/haskell/exercises/bob/test/Tests.hs +2 -10
- data/tracks/haskell/exercises/sublist/test/Tests.hs +6 -1
- data/tracks/java/config.json +13 -1
- data/tracks/java/exercises/bracket-push/build.gradle +17 -0
- data/tracks/java/exercises/bracket-push/src/example/java/BracketChecker.java +45 -0
- data/tracks/java/exercises/bracket-push/src/main/java/BracketChecker.java +5 -0
- data/tracks/java/exercises/bracket-push/src/test/java/BracketCheckerTest.java +102 -0
- data/tracks/java/exercises/robot-simulator/build.gradle +17 -0
- data/tracks/java/exercises/robot-simulator/src/example/java/GridPosition.java +1 -0
- data/tracks/java/exercises/robot-simulator/src/example/java/Orientation.java +1 -0
- data/tracks/java/exercises/robot-simulator/src/example/java/Robot.java +71 -0
- data/tracks/java/exercises/robot-simulator/src/main/java/GridPosition.java +29 -0
- data/tracks/java/exercises/robot-simulator/src/main/java/Orientation.java +5 -0
- data/tracks/java/exercises/robot-simulator/src/main/java/Robot.java +5 -0
- data/tracks/java/exercises/robot-simulator/src/test/java/RobotTest.java +244 -0
- data/tracks/java/exercises/settings.gradle +2 -0
- data/tracks/ocaml/exercises/say/test.ml +52 -56
- data/tracks/ocaml/tools/test-generator/src/codegen.ml +2 -1
- data/tracks/ocaml/tools/test-generator/src/special_cases.ml +10 -4
- data/tracks/ocaml/tools/test-generator/src/test_generator.ml +5 -0
- data/tracks/ocaml/tools/test-generator/templates/say/template.ml +21 -0
- data/tracks/ocaml/tools/test-generator/test/special_cases_test.ml +2 -2
- metadata +30 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b688c37ee3986356aaadb9bd39b4dd72524ed7f
|
4
|
+
data.tar.gz: 0023dcfdc396190c1c7ee84988a9e183d9ec1459
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c723690b00d103e004d70e3b1436ce5fb406e2ad06dd4d18e120f16578c3b31164430936bc3f5127e2431426be5a2e814923b98cfca95af03247ef64044708aa
|
7
|
+
data.tar.gz: a45271733dc3dc85ba092a50293cf267acdd14343cecffa9fac2cbf980be3b9b7b8c26e29f90c5b3fc499faef4ad4f2a5671070ab03c827cb2ba88d4393e9488
|
data/bin/update
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
This exercise should have no metadata.yml file.
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
Hints file is ignored.
|
@@ -0,0 +1 @@
|
|
1
|
+
This file is also ignored.
|
@@ -0,0 +1 @@
|
|
1
|
+
Any file containing example is ignored.
|
@@ -0,0 +1 @@
|
|
1
|
+
All files in this directory, EXCEPT for this file, should be ignored.
|
data/lib/trackler/file_bundle.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
require 'zip'
|
2
2
|
|
3
3
|
module Trackler
|
4
|
-
# FileBundle is a
|
4
|
+
# A FileBundle is a collection of files from within an exercise directory
|
5
|
+
# It contains all the files that will be provided by the `exercism fetch` command
|
6
|
+
# EXCEPT for those whose names match any of the ignore patterns.
|
5
7
|
class FileBundle
|
6
|
-
|
7
|
-
|
8
|
-
@dir = dir
|
8
|
+
def initialize(base_directory, ignore_patterns = [])
|
9
|
+
@base_directory = base_directory
|
9
10
|
@ignore_patterns = ignore_patterns
|
10
11
|
end
|
11
12
|
|
12
13
|
def zip
|
13
14
|
Zip::OutputStream.write_buffer do |io|
|
14
15
|
paths.each do |path|
|
15
|
-
io.put_next_entry(path.relative_path_from(
|
16
|
+
io.put_next_entry(path.relative_path_from(base_directory))
|
16
17
|
io.print IO.read(path)
|
17
18
|
end
|
18
19
|
yield io if block_given?
|
@@ -20,10 +21,27 @@ module Trackler
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def paths
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
all_files_below(base_directory).reject { |file| ignored? file }.sort
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :base_directory, :ignore_patterns
|
30
|
+
|
31
|
+
def all_files_below(dir)
|
32
|
+
Pathname.glob("#{dir}/**/*", File::FNM_DOTMATCH)
|
33
|
+
end
|
34
|
+
|
35
|
+
def ignored?(file)
|
36
|
+
ignored_by_name?(file) || ignored_by_type?(file)
|
37
|
+
end
|
38
|
+
|
39
|
+
def ignored_by_name?(file)
|
40
|
+
ignore_patterns.any? { |pattern| file.to_s =~ pattern }
|
41
|
+
end
|
42
|
+
|
43
|
+
def ignored_by_type?(file)
|
44
|
+
file.directory?
|
27
45
|
end
|
28
46
|
end
|
29
47
|
end
|
@@ -8,6 +8,7 @@ module Trackler
|
|
8
8
|
Regexp.new("HINTS\.md$"),
|
9
9
|
Regexp.new("example", Regexp::IGNORECASE),
|
10
10
|
Regexp.new("\/\.$"),
|
11
|
+
Regexp.new("/\.meta/")
|
11
12
|
]
|
12
13
|
|
13
14
|
attr_reader :track_id, :repo, :problem, :root, :file_bundle
|
@@ -17,16 +18,16 @@ module Trackler
|
|
17
18
|
@repo = repo
|
18
19
|
@problem = problem
|
19
20
|
@root = Pathname.new(root)
|
20
|
-
@file_bundle = FileBundle.new(
|
21
|
+
@file_bundle = FileBundle.new(track_directory, IGNORE)
|
21
22
|
end
|
22
23
|
|
23
24
|
def exists?
|
24
|
-
File.exist?(
|
25
|
+
File.exist?(track_directory)
|
25
26
|
end
|
26
27
|
|
27
28
|
def files
|
28
29
|
@files ||= Hash[file_bundle.paths.map {|path|
|
29
|
-
[path.relative_path_from(
|
30
|
+
[path.relative_path_from(track_directory).to_s, File.read(path)]
|
30
31
|
}].merge("README.md" => readme)
|
31
32
|
end
|
32
33
|
|
@@ -55,8 +56,8 @@ module Trackler
|
|
55
56
|
|
56
57
|
private
|
57
58
|
|
58
|
-
def
|
59
|
-
@
|
59
|
+
def track_directory
|
60
|
+
@track_directory ||= track_dir.join(exercise_dir)
|
60
61
|
end
|
61
62
|
|
62
63
|
def track_dir
|
@@ -105,7 +106,7 @@ It's possible to submit an incomplete solution so you can see how others have co
|
|
105
106
|
end
|
106
107
|
|
107
108
|
def implementation_hint
|
108
|
-
read File.join(
|
109
|
+
read File.join(track_directory, 'HINTS.md')
|
109
110
|
end
|
110
111
|
|
111
112
|
def read(f)
|
data/lib/trackler/problem.rb
CHANGED
@@ -10,78 +10,103 @@ module Trackler
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def exists?
|
13
|
-
!!
|
13
|
+
!!description && !!metadata
|
14
14
|
end
|
15
15
|
|
16
16
|
def name
|
17
|
-
|
17
|
+
slug.split('-').map(&:capitalize).join(' ')
|
18
18
|
end
|
19
19
|
|
20
20
|
def description
|
21
|
-
@description
|
21
|
+
return @description unless @description.nil?
|
22
|
+
filename = common_metadata_path(description_path)
|
23
|
+
if File.exists?(filename)
|
24
|
+
@description = File.read(filename)
|
25
|
+
end
|
22
26
|
end
|
23
27
|
|
24
28
|
def source_markdown
|
25
|
-
|
26
|
-
|
27
|
-
if url.empty? && body.empty?
|
28
|
-
""
|
29
|
-
else
|
30
|
-
"## Source\n\n" + [body, url].reject(&:empty?).join(" ")
|
31
|
-
end
|
29
|
+
text = [source, markdown_link(source_url)].reject(&:empty?).join(" ")
|
30
|
+
text.empty? ? text : "## Source\n\n#{text}"
|
32
31
|
end
|
33
32
|
|
33
|
+
######
|
34
|
+
# Deprecated methods
|
35
|
+
# TODO: remove external references to these methods.
|
36
|
+
# found in: x-api
|
37
|
+
# NOT in: exercism.io, cli
|
38
|
+
# Anywhere else we need to look?
|
39
|
+
# Should this output a warning or raise an error?
|
34
40
|
def md_url
|
35
|
-
|
41
|
+
description_url
|
36
42
|
end
|
37
43
|
|
38
44
|
def json_url
|
39
|
-
|
45
|
+
canonical_data_url
|
40
46
|
end
|
41
47
|
|
42
48
|
def yaml_url
|
43
|
-
|
49
|
+
metadata_url
|
44
50
|
end
|
51
|
+
# End deprecated methods
|
52
|
+
######
|
45
53
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
54
|
+
def description_url
|
55
|
+
repo_url(description_path)
|
56
|
+
end
|
57
|
+
|
58
|
+
def canonical_data_url
|
59
|
+
repo_url(canonical_data_path) if File.exists?(common_metadata_path(canonical_data_path))
|
60
|
+
end
|
61
|
+
|
62
|
+
def metadata_url
|
63
|
+
repo_url(metadata_path)
|
64
|
+
end
|
65
|
+
|
66
|
+
def blurb
|
67
|
+
metadata['blurb'].to_s.strip
|
68
|
+
end
|
69
|
+
|
70
|
+
def source
|
71
|
+
metadata['source'].to_s.strip
|
72
|
+
end
|
73
|
+
|
74
|
+
def source_url
|
75
|
+
metadata['source_url'].to_s.strip
|
50
76
|
end
|
51
77
|
|
52
78
|
private
|
53
79
|
|
54
|
-
def
|
55
|
-
|
56
|
-
"exercises/%s/canonical-data.json" % slug,
|
57
|
-
"%s.json" % slug,
|
58
|
-
].find { |path| File.exist?(filepath(path)) }
|
80
|
+
def canonical_data_path
|
81
|
+
"exercises/%s/canonical-data.json" % slug
|
59
82
|
end
|
60
83
|
|
61
|
-
def
|
62
|
-
|
63
|
-
"exercises/%s/metadata.yml" % slug,
|
64
|
-
"%s.yml" % slug,
|
65
|
-
].find { |path| File.exist?(filepath(path)) }
|
84
|
+
def metadata_path
|
85
|
+
"exercises/%s/metadata.yml" % slug
|
66
86
|
end
|
67
87
|
|
68
|
-
def
|
69
|
-
|
70
|
-
"exercises/%s/description.md" % slug,
|
71
|
-
"%s.md" % slug,
|
72
|
-
].find { |path| File.exist?(filepath(path)) }
|
88
|
+
def description_path
|
89
|
+
"exercises/%s/description.md" % slug
|
73
90
|
end
|
74
91
|
|
75
92
|
def repo_url(path)
|
76
|
-
"https://github.com/exercism/x-common/blob/master
|
93
|
+
"https://github.com/exercism/x-common/blob/master/#{path}" unless path.nil?
|
77
94
|
end
|
78
95
|
|
79
|
-
def
|
80
|
-
|
96
|
+
def metadata
|
97
|
+
return @metadata unless @metadata.nil?
|
98
|
+
filename = common_metadata_path(metadata_path)
|
99
|
+
if File.exists?(filename)
|
100
|
+
@metadata = YAML.load(File.read(filename))
|
101
|
+
end
|
81
102
|
end
|
82
103
|
|
83
|
-
def
|
84
|
-
|
104
|
+
def common_metadata_path(path)
|
105
|
+
File.join(root, "common", path)
|
106
|
+
end
|
107
|
+
|
108
|
+
def markdown_link(url)
|
109
|
+
url.empty? ? url : format("[%s](%s)", url, url)
|
85
110
|
end
|
86
111
|
end
|
87
112
|
end
|
data/lib/trackler/version.rb
CHANGED
data/tracks/c/config.json
CHANGED
@@ -180,6 +180,15 @@
|
|
180
180
|
"text formatting",
|
181
181
|
"preprocessor (x-macros in test)"
|
182
182
|
]
|
183
|
+
}, {
|
184
|
+
"difficulty": 2,
|
185
|
+
"slug": "series",
|
186
|
+
"topics": [
|
187
|
+
"control-flow (if-statements)",
|
188
|
+
"strings",
|
189
|
+
"text formatting",
|
190
|
+
"memory management"
|
191
|
+
]
|
183
192
|
}],
|
184
193
|
"deprecated": [
|
185
194
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
CFLAGS = -std=c99
|
2
|
+
CFLAGS += -Wall
|
3
|
+
CFLAGS += -Wextra
|
4
|
+
CFLAGS += -pedantic
|
5
|
+
CFLAGS += -Werror
|
6
|
+
|
7
|
+
|
8
|
+
test: tests.out
|
9
|
+
@./tests.out
|
10
|
+
|
11
|
+
clean:
|
12
|
+
rm -f *.o *.out
|
13
|
+
|
14
|
+
tests.out: test/test_series.c src/series.c src/series.h
|
15
|
+
@echo Compiling $@
|
16
|
+
@cc $(CFLAGS) src/series.c test/vendor/unity.c test/test_series.c -o tests.out
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <string.h>
|
3
|
+
#include <stdio.h>
|
4
|
+
|
5
|
+
#include "series.h"
|
6
|
+
|
7
|
+
SeriesResults_t series(char *inputText, unsigned int substringLength)
|
8
|
+
{
|
9
|
+
int substringCount = strlen(inputText) - (substringLength - 1);
|
10
|
+
SeriesResults_t results;
|
11
|
+
|
12
|
+
memset(&results, 0, sizeof(results));
|
13
|
+
if ((substringCount > 0) && (substringLength > 0)) {
|
14
|
+
results.substringCount = substringCount;
|
15
|
+
results.substring = malloc(sizeof(char *) * substringCount);
|
16
|
+
for (int index = 0; index < substringCount; index++) {
|
17
|
+
results.substring[index] =
|
18
|
+
malloc(sizeof(char) * (substringLength + 1));
|
19
|
+
sprintf(results.substring[index], "%.*s", substringLength,
|
20
|
+
&inputText[index]);
|
21
|
+
}
|
22
|
+
}
|
23
|
+
return results;
|
24
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#ifndef _SERIES_H
|
2
|
+
#define _SERIES_H
|
3
|
+
|
4
|
+
#define MAX_INPUT_TEXT_LENGTH (8)
|
5
|
+
#define MAX_SERIES_RESULTS (MAX_INPUT_TEXT_LENGTH)
|
6
|
+
#define MAX_SERIES_LENGTH (5)
|
7
|
+
|
8
|
+
// results structure
|
9
|
+
typedef struct SeriesResults {
|
10
|
+
unsigned int substringCount;
|
11
|
+
char **substring; // array of pointers of dimension substringCount
|
12
|
+
} SeriesResults_t;
|
13
|
+
|
14
|
+
// series - routine to split up input text into consecutive substrings of text of a given substringLength
|
15
|
+
//
|
16
|
+
// inputs:
|
17
|
+
// inputText - bounded to MAX_INPUT_TEXT_LENGTH
|
18
|
+
// substringLength - the desired length of substrings that are returned bounded to MAX_SERIES_LENGTH
|
19
|
+
//
|
20
|
+
// outputs:
|
21
|
+
// SeriesResult_t results - structure containing count of the substring and an array of
|
22
|
+
// pointers to the substrings.
|
23
|
+
//
|
24
|
+
// calling routine will free memory associated with each of the substrings and
|
25
|
+
// the pointers to the substrings.
|
26
|
+
SeriesResults_t series(char *inputText, unsigned int substringLength);
|
27
|
+
|
28
|
+
#endif
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include "vendor/unity.h"
|
3
|
+
#include "../src/series.h"
|
4
|
+
|
5
|
+
// helper routines to validate test results
|
6
|
+
static void testSolution(SeriesResults_t * expectedSolution,
|
7
|
+
SeriesResults_t * actualSolution)
|
8
|
+
{
|
9
|
+
// result count correct
|
10
|
+
TEST_ASSERT_EQUAL(expectedSolution->substringCount,
|
11
|
+
actualSolution->substringCount);
|
12
|
+
|
13
|
+
// test each substring...
|
14
|
+
for (unsigned int index = 0; index < expectedSolution->substringCount;
|
15
|
+
index++) {
|
16
|
+
TEST_ASSERT_EQUAL_STRING(expectedSolution->substring[index],
|
17
|
+
actualSolution->substring[index]);
|
18
|
+
free(actualSolution->substring[index]);
|
19
|
+
}
|
20
|
+
if (actualSolution->substringCount) {
|
21
|
+
free(actualSolution->substring);
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
#define EXPAND_SERIES_TEST_CASES_AS_TEST(test_name, inputText, substringLength, expectedResultCount, expectedResultSubstrings)\
|
26
|
+
void test_name(void)\
|
27
|
+
{\
|
28
|
+
char *substrings[] = expectedResultSubstrings;\
|
29
|
+
SeriesResults_t expected = {expectedResultCount, &substrings[0]};\
|
30
|
+
SeriesResults_t actual = series(inputText, substringLength);\
|
31
|
+
testSolution(&expected, &actual);\
|
32
|
+
}\
|
33
|
+
|
34
|
+
#define ASSEMBLE_STRING_ARRAY(...) __VA_ARGS__
|
35
|
+
|
36
|
+
// Test cases
|
37
|
+
#define SERIES_TEST_CASES(ENTRY) \
|
38
|
+
ENTRY(test_slices_of_one, "01234", 1, 5, { ASSEMBLE_STRING_ARRAY("0","1","2","3","4") })\
|
39
|
+
ENTRY(test_slices_of_two, "97867564", 2, 7, { ASSEMBLE_STRING_ARRAY("97","78","86","67","75","56", "64") })\
|
40
|
+
ENTRY(test_slices_of_three, "97867564", 3, 6, { ASSEMBLE_STRING_ARRAY("978","786","867","675","756","564") })\
|
41
|
+
ENTRY(test_slices_of_four, "01234", 4, 2, { ASSEMBLE_STRING_ARRAY("0123","1234") })\
|
42
|
+
ENTRY(test_slices_of_five, "01234", 5, 1, { ASSEMBLE_STRING_ARRAY("01234") })\
|
43
|
+
ENTRY(test_overly_long_slice, "012", 4, 0, { ASSEMBLE_STRING_ARRAY("") })\
|
44
|
+
ENTRY(test_overly_short_slice, "01234", 0, 0, { ASSEMBLE_STRING_ARRAY("") })\
|
45
|
+
|
46
|
+
SERIES_TEST_CASES(EXPAND_SERIES_TEST_CASES_AS_TEST)
|
47
|
+
|
48
|
+
int main(void)
|
49
|
+
{
|
50
|
+
UnityBegin("test/test_word_count.c");
|
51
|
+
|
52
|
+
RUN_TEST(test_slices_of_one);
|
53
|
+
RUN_TEST(test_slices_of_two);
|
54
|
+
RUN_TEST(test_slices_of_three);
|
55
|
+
RUN_TEST(test_slices_of_four);
|
56
|
+
RUN_TEST(test_slices_of_five);
|
57
|
+
RUN_TEST(test_overly_long_slice);
|
58
|
+
RUN_TEST(test_overly_short_slice);
|
59
|
+
|
60
|
+
UnityEnd();
|
61
|
+
|
62
|
+
return 0;
|
63
|
+
}
|