trackler 2.0.1.1 → 2.0.1.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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/bin/update +4 -0
  3. data/common/exercises/minesweeper/canonical-data.json +3 -3
  4. data/fixtures/common/exercises/imbe/description.md +2 -0
  5. data/fixtures/common/exercises/imbe/metadata.yml +3 -0
  6. data/fixtures/common/exercises/no-metadata/description.md +1 -0
  7. data/fixtures/tracks/fruit/exercises/imbe/.meta/everything_in_meta_is_ignored.txt +0 -0
  8. data/fixtures/tracks/fruit/exercises/imbe/CaSe_iNSeNSiTiVe_eXaMPLe.TXT +0 -0
  9. data/fixtures/tracks/fruit/exercises/imbe/HINTS.md +1 -0
  10. data/fixtures/tracks/fruit/exercises/imbe/also_an_example.txt +1 -0
  11. data/fixtures/tracks/fruit/exercises/imbe/example.ext +1 -0
  12. data/fixtures/tracks/fruit/exercises/imbe/imbe.txt +1 -0
  13. data/lib/trackler/file_bundle.rb +27 -9
  14. data/lib/trackler/implementation.rb +7 -6
  15. data/lib/trackler/problem.rb +62 -37
  16. data/lib/trackler/version.rb +1 -1
  17. data/tracks/c/config.json +9 -0
  18. data/tracks/c/exercises/series/makefile +16 -0
  19. data/tracks/c/exercises/series/src/example.c +24 -0
  20. data/tracks/c/exercises/series/src/series.h +28 -0
  21. data/tracks/c/exercises/series/test/test_series.c +63 -0
  22. data/tracks/c/exercises/series/test/vendor/unity.c +1300 -0
  23. data/tracks/c/exercises/series/test/vendor/unity.h +274 -0
  24. data/tracks/c/exercises/series/test/vendor/unity_internals.h +701 -0
  25. data/tracks/crystal/src/generator/exercises/binary.cr +3 -3
  26. data/tracks/crystal/src/generator/exercises/forth.cr +3 -3
  27. data/tracks/crystal/src/generator/exercises/hello_world.cr +1 -1
  28. data/tracks/haskell/exercises/bob/test/Tests.hs +2 -10
  29. data/tracks/haskell/exercises/sublist/test/Tests.hs +6 -1
  30. data/tracks/java/config.json +13 -1
  31. data/tracks/java/exercises/bracket-push/build.gradle +17 -0
  32. data/tracks/java/exercises/bracket-push/src/example/java/BracketChecker.java +45 -0
  33. data/tracks/java/exercises/bracket-push/src/main/java/BracketChecker.java +5 -0
  34. data/tracks/java/exercises/bracket-push/src/test/java/BracketCheckerTest.java +102 -0
  35. data/tracks/java/exercises/robot-simulator/build.gradle +17 -0
  36. data/tracks/java/exercises/robot-simulator/src/example/java/GridPosition.java +1 -0
  37. data/tracks/java/exercises/robot-simulator/src/example/java/Orientation.java +1 -0
  38. data/tracks/java/exercises/robot-simulator/src/example/java/Robot.java +71 -0
  39. data/tracks/java/exercises/robot-simulator/src/main/java/GridPosition.java +29 -0
  40. data/tracks/java/exercises/robot-simulator/src/main/java/Orientation.java +5 -0
  41. data/tracks/java/exercises/robot-simulator/src/main/java/Robot.java +5 -0
  42. data/tracks/java/exercises/robot-simulator/src/test/java/RobotTest.java +244 -0
  43. data/tracks/java/exercises/settings.gradle +2 -0
  44. data/tracks/ocaml/exercises/say/test.ml +52 -56
  45. data/tracks/ocaml/tools/test-generator/src/codegen.ml +2 -1
  46. data/tracks/ocaml/tools/test-generator/src/special_cases.ml +10 -4
  47. data/tracks/ocaml/tools/test-generator/src/test_generator.ml +5 -0
  48. data/tracks/ocaml/tools/test-generator/templates/say/template.ml +21 -0
  49. data/tracks/ocaml/tools/test-generator/test/special_cases_test.ml +2 -2
  50. metadata +30 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0668847547af08df3e6296f50d8ee7b1acb6d86
4
- data.tar.gz: 3733aa995d8e62eaa5d97e224f39f74fbb186974
3
+ metadata.gz: 7b688c37ee3986356aaadb9bd39b4dd72524ed7f
4
+ data.tar.gz: 0023dcfdc396190c1c7ee84988a9e183d9ec1459
5
5
  SHA512:
6
- metadata.gz: f80278c35da0397606227fd884ec94a4e5b325e0983da69bd82a6b8039e776729d1b696357f3efe56b9c809e599219a6568cf50a705881582d64c696a018fef8
7
- data.tar.gz: 176cdc2e4a3b5a58ff89a07a9261215e293723b963af269a3cc02858be676e622a1e3adc7c646c2ae5a04d812b4c57b0a1cbf089f7b86106284ba5fe63ede4d7
6
+ metadata.gz: c723690b00d103e004d70e3b1436ce5fb406e2ad06dd4d18e120f16578c3b31164430936bc3f5127e2431426be5a2e814923b98cfca95af03247ef64044708aa
7
+ data.tar.gz: a45271733dc3dc85ba092a50293cf267acdd14343cecffa9fac2cbf980be3b9b7b8c26e29f90c5b3fc499faef4ad4f2a5671070ab03c827cb2ba88d4393e9488
data/bin/update CHANGED
@@ -1,5 +1,9 @@
1
1
  #!/bin/bash
2
2
 
3
+ git checkout master
4
+ git fetch origin master
5
+ git reset --hard origin/master
6
+
3
7
  git submodule foreach git pull origin master
4
8
 
5
9
  rake && bin/verify-configs && bin/verify-metadata
@@ -56,9 +56,9 @@
56
56
  {
57
57
  "description": "space surrounded by mines",
58
58
  "input": [
59
- " ",
60
- " 8 ",
61
- " "
59
+ "***",
60
+ "* *",
61
+ "***"
62
62
  ],
63
63
  "expected": [
64
64
  "***",
@@ -0,0 +1,2 @@
1
+ Garcinia livingstonei (imbe) is a species of Garcinia, native to a broad area of tropical Africa.
2
+
@@ -0,0 +1,3 @@
1
+ ---
2
+ blurb: "This is imbe."
3
+ source: "Africa."
@@ -0,0 +1 @@
1
+ This exercise should have no metadata.yml file.
@@ -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.
@@ -1,18 +1,19 @@
1
1
  require 'zip'
2
2
 
3
3
  module Trackler
4
- # FileBundle is a zippech archive of a directory.
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
- attr_reader :dir, :ignore_patterns
7
- def initialize(dir, ignore_patterns=[])
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(dir))
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
- Pathname.glob("#{dir}/**/*", File::FNM_DOTMATCH).reject {|file|
24
- file.directory? ||
25
- ignore_patterns.any? { |pattern| file.to_s =~ pattern }
26
- }.sort
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(dir, IGNORE)
21
+ @file_bundle = FileBundle.new(track_directory, IGNORE)
21
22
  end
22
23
 
23
24
  def exists?
24
- File.exist?(dir)
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(dir).to_s, File.read(path)]
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 dir
59
- @dir ||= track_dir.join(exercise_dir)
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(dir, 'HINTS.md')
109
+ read File.join(track_directory, 'HINTS.md')
109
110
  end
110
111
 
111
112
  def read(f)
@@ -10,78 +10,103 @@ module Trackler
10
10
  end
11
11
 
12
12
  def exists?
13
- !!md && !!yaml
13
+ !!description && !!metadata
14
14
  end
15
15
 
16
16
  def name
17
- @name ||= slug.split('-').map(&:capitalize).join(' ')
17
+ slug.split('-').map(&:capitalize).join(' ')
18
18
  end
19
19
 
20
20
  def description
21
- @description ||= File.read(filepath(md))
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
- body = source.empty? ? "" : "%s" % source
26
- url = source_url.empty? ? "" : "[%s](%s)" % [source_url, source_url]
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
- repo_url(md)
41
+ description_url
36
42
  end
37
43
 
38
44
  def json_url
39
- repo_url(json) if !!json
45
+ canonical_data_url
40
46
  end
41
47
 
42
48
  def yaml_url
43
- repo_url(yaml)
49
+ metadata_url
44
50
  end
51
+ # End deprecated methods
52
+ ######
45
53
 
46
- %w(blurb source source_url).each do |name|
47
- define_method name do
48
- metadata[name].to_s.strip
49
- end
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 json
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 yaml
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 md
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/%s" % path
93
+ "https://github.com/exercism/x-common/blob/master/#{path}" unless path.nil?
77
94
  end
78
95
 
79
- def filepath(f)
80
- File.join(root, "common", f)
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 metadata
84
- @metadata ||= YAML.load(File.read(filepath(yaml)))
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
@@ -1,3 +1,3 @@
1
1
  module Trackler
2
- VERSION = "2.0.1.1"
2
+ VERSION = "2.0.1.2"
3
3
  end
@@ -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
+ }