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.
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
+ }