trackler 2.2.1.52 → 2.2.1.53
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/leap/canonical-data.json +2 -2
- data/tracks/cfml/tasks/FormatConfig.cfc +6 -4
- data/tracks/cfml/tasks/GenerateReadme.cfc +197 -0
- data/tracks/cfml/tasks/ScaffoldExercise.cfc +6 -0
- data/tracks/csharp/config.json +1 -1
- data/tracks/delphi/exercises/leap/uLeapTests.pas +1 -1
- data/tracks/fsharp/exercises/clock/Clock.fs +1 -1
- data/tracks/fsharp/exercises/clock/ClockTest.fs +239 -61
- data/tracks/fsharp/exercises/clock/Example.fs +3 -3
- data/tracks/fsharp/exercises/dominoes/DominoesTest.fs +29 -26
- data/tracks/fsharp/exercises/largest-series-product/LargestSeriesProductTest.fs +30 -15
- data/tracks/fsharp/exercises/leap/LeapTest.fs +2 -2
- data/tracks/fsharp/exercises/rectangles/Example.fs +1 -1
- data/tracks/fsharp/exercises/rectangles/Rectangles.fs +1 -1
- data/tracks/fsharp/exercises/rectangles/RectanglesTest.fs +66 -43
- data/tracks/fsharp/generators/Generators.fs +85 -1
- data/tracks/java/scripts/canonical_data_check.sh +8 -0
- data/tracks/kotlin/.gitignore +1 -0
- data/tracks/kotlin/exercises/acronym/.meta/version +1 -0
- data/tracks/kotlin/exercises/acronym/src/test/kotlin/AcronymTest.kt +9 -10
- data/tracks/kotlin/exercises/all-your-base/.meta/version +1 -1
- data/tracks/kotlin/exercises/all-your-base/src/test/kotlin/BaseConverterTest.kt +20 -20
- data/tracks/kotlin/exercises/allergies/.meta/version +1 -0
- data/tracks/kotlin/exercises/allergies/src/test/kotlin/AllergiesTest.kt +19 -72
- data/tracks/kotlin/exercises/anagram/.meta/src/reference/kotlin/Anagram.kt +7 -4
- data/tracks/kotlin/exercises/anagram/.meta/version +1 -0
- data/tracks/kotlin/exercises/anagram/src/test/kotlin/AnagramTest.kt +76 -29
- data/tracks/kotlin/exercises/atbash-cipher/.meta/version +1 -0
- data/tracks/kotlin/exercises/atbash-cipher/src/test/kotlin/AtbashTest.kt +6 -3
- data/tracks/kotlin/exercises/beer-song/.meta/version +1 -0
- data/tracks/kotlin/exercises/beer-song/src/test/kotlin/BeerSongTest.kt +21 -46
- data/tracks/kotlin/exercises/binary-search/.meta/version +1 -0
- data/tracks/kotlin/exercises/binary-search/src/test/kotlin/BinarySearchTest.kt +30 -19
- data/tracks/kotlin/exercises/bob/.meta/src/reference/kotlin/Bob.kt +8 -7
- data/tracks/kotlin/exercises/bob/.meta/version +1 -0
- data/tracks/kotlin/exercises/bob/src/test/kotlin/BobTest.kt +57 -15
- data/tracks/kotlin/exercises/bracket-push/.meta/version +1 -0
- data/tracks/kotlin/exercises/bracket-push/src/test/kotlin/BracketPushTest.kt +3 -1
- data/tracks/kotlin/exercises/collatz-conjecture/.meta/version +1 -1
- data/tracks/kotlin/exercises/difference-of-squares/.meta/version +1 -0
- data/tracks/kotlin/exercises/difference-of-squares/src/test/kotlin/SquaresTest.kt +10 -23
- data/tracks/kotlin/exercises/etl/.meta/src/reference/kotlin/ETL.kt +7 -1
- data/tracks/kotlin/exercises/etl/.meta/version +1 -0
- data/tracks/kotlin/exercises/etl/src/test/kotlin/ETLTest.kt +10 -10
- data/tracks/kotlin/exercises/flatten-array/.meta/version +1 -0
- data/tracks/kotlin/exercises/flatten-array/src/test/kotlin/FlattenerTest.kt +8 -16
- data/tracks/kotlin/exercises/gigasecond/.meta/version +1 -0
- data/tracks/kotlin/exercises/gigasecond/src/test/kotlin/GigasecondTest.kt +1 -1
- data/tracks/kotlin/exercises/hamming/.meta/src/reference/kotlin/Hamming.kt +1 -1
- data/tracks/kotlin/exercises/hamming/.meta/version +1 -1
- data/tracks/kotlin/exercises/hamming/src/test/kotlin/HammingTest.kt +4 -4
- data/tracks/kotlin/exercises/hello-world/.meta/version +1 -0
- data/tracks/kotlin/exercises/hello-world/src/test/kotlin/HelloWorldTest.kt +1 -1
- data/tracks/kotlin/exercises/isogram/.meta/version +1 -0
- data/tracks/kotlin/exercises/isogram/src/test/kotlin/IsogramTest.kt +5 -8
- data/tracks/kotlin/exercises/largest-series-product/.meta/src/reference/kotlin/Series.kt +2 -3
- data/tracks/kotlin/exercises/largest-series-product/.meta/version +1 -0
- data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesTest.kt +97 -0
- data/tracks/kotlin/exercises/leap/.meta/version +1 -0
- data/tracks/kotlin/exercises/leap/src/test/kotlin/LeapTest.kt +8 -26
- data/tracks/kotlin/exercises/list-ops/.meta/version +1 -1
- data/tracks/kotlin/exercises/luhn/.meta/version +1 -0
- data/tracks/kotlin/exercises/luhn/src/test/kotlin/LuhnTest.kt +0 -3
- data/tracks/kotlin/exercises/nth-prime/.meta/version +1 -0
- data/tracks/kotlin/exercises/nth-prime/src/test/kotlin/PrimeTest.kt +0 -2
- data/tracks/kotlin/exercises/nucleotide-count/.meta/src/reference/kotlin/{DNA.kt → Dna.kt} +3 -8
- data/tracks/kotlin/exercises/nucleotide-count/.meta/version +1 -0
- data/tracks/kotlin/exercises/nucleotide-count/src/test/kotlin/DnaTest.kt +48 -0
- data/tracks/kotlin/exercises/pangram/.meta/src/reference/kotlin/{Pangrams.kt → Pangram.kt} +1 -1
- data/tracks/kotlin/exercises/pangram/.meta/version +1 -1
- data/tracks/kotlin/exercises/pangram/src/test/kotlin/PangramTest.kt +15 -9
- data/tracks/kotlin/exercises/pascals-triangle/.meta/version +1 -0
- data/tracks/kotlin/exercises/pascals-triangle/src/test/kotlin/PascalsTriangleTest.kt +32 -14
- data/tracks/kotlin/exercises/perfect-numbers/.meta/src/reference/kotlin/NaturalNumber.kt +1 -1
- data/tracks/kotlin/exercises/perfect-numbers/.meta/version +1 -0
- data/tracks/kotlin/exercises/perfect-numbers/src/test/kotlin/{PerfectNumbersTest.kt → NaturalNumberTest.kt} +25 -7
- data/tracks/kotlin/exercises/phone-number/.meta/src/reference/kotlin/PhoneNumber.kt +15 -7
- data/tracks/kotlin/exercises/phone-number/.meta/version +1 -0
- data/tracks/kotlin/exercises/phone-number/src/test/kotlin/PhoneNumberTest.kt +46 -29
- data/tracks/kotlin/exercises/pig-latin/.meta/src/reference/kotlin/PigLatin.kt +2 -2
- data/tracks/kotlin/exercises/pig-latin/.meta/version +1 -0
- data/tracks/kotlin/exercises/pig-latin/src/test/kotlin/PigLatinTest.kt +21 -10
- data/tracks/kotlin/exercises/raindrops/.meta/version +1 -0
- data/tracks/kotlin/exercises/raindrops/src/test/kotlin/RaindropsTest.kt +19 -26
- data/tracks/kotlin/exercises/react/.meta/version +1 -0
- data/tracks/kotlin/exercises/react/src/test/kotlin/ReactTest.kt +11 -4
- data/tracks/kotlin/exercises/robot-simulator/.meta/version +1 -1
- data/tracks/kotlin/exercises/roman-numerals/.meta/version +1 -0
- data/tracks/kotlin/exercises/roman-numerals/src/test/kotlin/RomanNumeralTest.kt +1 -2
- data/tracks/kotlin/exercises/rotational-cipher/.meta/version +1 -1
- data/tracks/kotlin/exercises/rotational-cipher/src/test/kotlin/RotationalCipherTest.kt +7 -7
- data/tracks/kotlin/exercises/scrabble-score/.meta/src/reference/kotlin/{Scrabble.kt → ScrabbleScore.kt} +1 -1
- data/tracks/kotlin/exercises/scrabble-score/.meta/version +1 -0
- data/tracks/kotlin/exercises/scrabble-score/src/test/kotlin/ScrabbleScoreTest.kt +9 -7
- data/tracks/kotlin/exercises/sieve/.meta/version +1 -0
- data/tracks/kotlin/exercises/sieve/src/test/kotlin/SieveTest.kt +8 -0
- data/tracks/kotlin/exercises/space-age/.meta/version +1 -0
- data/tracks/kotlin/exercises/space-age/src/test/kotlin/SpaceAgeTest.kt +1 -16
- data/tracks/kotlin/exercises/sum-of-multiples/.meta/version +1 -0
- data/tracks/kotlin/exercises/sum-of-multiples/src/test/kotlin/SumOfMultiplesTest.kt +7 -7
- data/tracks/kotlin/exercises/triangle/.meta/version +1 -0
- data/tracks/kotlin/exercises/two-fer/.meta/version +1 -0
- data/tracks/kotlin/exercises/two-fer/src/test/kotlin/TwoferTest.kt +0 -1
- data/tracks/kotlin/exercises/word-count/.meta/src/reference/kotlin/WordCount.kt +6 -2
- data/tracks/kotlin/exercises/word-count/.meta/version +1 -0
- data/tracks/kotlin/exercises/word-count/src/test/kotlin/WordCountTest.kt +31 -9
- data/tracks/kotlin/scripts/canonical_data_check.sh +8 -0
- data/tracks/perl6/exercises/leap/leap.t +2 -2
- data/tracks/php/config.json +16 -0
- data/tracks/php/exercises/crypto-square/crypto-square_test.php +50 -0
- data/tracks/php/exercises/crypto-square/example.php +32 -0
- data/tracks/php/exercises/meetup/README.md +21 -0
- data/tracks/php/exercises/meetup/example.php +19 -0
- data/tracks/php/exercises/meetup/meetup_test.php +577 -0
- data/tracks/python/README.md +7 -5
- data/tracks/python/config.json +36 -27
- data/tracks/python/docs/TESTS.md +36 -12
- data/tracks/python/exercises/complex-numbers/complex_numbers_test.py +1 -1
- data/tracks/python/exercises/diffie-hellman/.meta/hints.md +16 -0
- data/tracks/python/exercises/diffie-hellman/README.md +15 -2
- data/tracks/python/exercises/error-handling/README.md +23 -0
- data/tracks/python/exercises/error-handling/error_handling.py +14 -0
- data/tracks/python/exercises/error-handling/error_handling_test.py +66 -0
- data/tracks/python/exercises/error-handling/example.py +21 -0
- data/tracks/python/exercises/forth/forth_test.py +1 -1
- data/tracks/python/exercises/isogram/isogram_test.py +5 -3
- data/tracks/python/exercises/leap/leap_test.py +2 -2
- data/tracks/python/exercises/rotational-cipher/rotational_cipher_test.py +4 -4
- data/tracks/python/exercises/simple-cipher/.meta/hints.md +16 -0
- data/tracks/python/exercises/simple-cipher/README.md +17 -0
- data/tracks/python/exercises/sum-of-multiples/sum_of_multiples_test.py +4 -1
- data/tracks/python/exercises/twelve-days/example.py +3 -3
- data/tracks/python/exercises/twelve-days/twelve_days.py +2 -2
- metadata +53 -9
- data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesInvalidInputTest.kt +0 -30
- data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesValidInputTest.kt +0 -34
- data/tracks/kotlin/exercises/nucleotide-count/src/test/kotlin/NucleotideTest.kt +0 -87
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 95152d34553c950841be6dbe52afef273a56ab43
|
4
|
+
data.tar.gz: 4d2c405d864d1c9fef3295f2cc30b316fdbc30f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebdadfa92b814621a979f0dbdb8060f3d1a952e000a93cea60b4a71cef0435ca67723bfd2ec5f8ad109acd826b3024d7890283cbad44f2fda01e065f8f6b805b
|
7
|
+
data.tar.gz: d8fa0417ab4cc2173f02b5fa5aa90975d5b62cdc8a2c1f8d965fbdfe458b05371273ad47ffb337eb3855d4a331f33a873568a3197513e05480e285c09ef2ee9b
|
data/lib/trackler/version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"exercise": "leap",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.2.0",
|
4
4
|
"cases": [
|
5
5
|
{
|
6
6
|
"description": "year not divisible by 4: common year",
|
@@ -11,7 +11,7 @@
|
|
11
11
|
{
|
12
12
|
"description": "year divisible by 4, not divisible by 100: leap year",
|
13
13
|
"property": "leapYear",
|
14
|
-
"input":
|
14
|
+
"input": 1996,
|
15
15
|
"expected": true
|
16
16
|
},
|
17
17
|
{
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* This is a simple task runner that formats the JSON config file. This should only be neccessary if
|
2
|
+
* This is a simple task runner that formats the JSON config file. This should only be neccessary if you've edited it by
|
3
3
|
* hand and want to get it back into the proper format as far as spacing and indentation goes. This follows the same format as `configlet fmt`
|
4
4
|
*/
|
5
5
|
component {
|
@@ -9,17 +9,19 @@ component {
|
|
9
9
|
var repoRootPath = expandPath( getDirectoryFromPath( getCurrentTemplatePath() ) & '../' );
|
10
10
|
// Read in the current JSON config file
|
11
11
|
var configJSONRaw = fileRead( repoRootPath & '/config.json' );
|
12
|
-
var configJSON = deserializeJSON( configJSONRaw );
|
13
12
|
|
14
|
-
|
13
|
+
// Format JSON file to spec
|
14
|
+
var newConfigJSONRaw = formatterUtil.formatJSON( json=configJSONRaw, indent=' ' , lineEnding=chr( 10 ), spaceAfterColon=true );
|
15
15
|
|
16
|
+
// Only save if it's different to avoid touching the file needlessly
|
16
17
|
if( newConfigJSONRaw != configJSONRaw ) {
|
18
|
+
|
17
19
|
// Write it back out with the proper formatting styles applied
|
18
20
|
fileWrite( repoRootPath & '/config.json', newConfigJSONRaw );
|
19
21
|
|
20
22
|
print.greenLine( 'Config file [#repoRootPath#config.json] formatted!' );
|
21
23
|
} else {
|
22
|
-
print.whiteLine( 'Config file [#repoRootPath#config.json] is already formatted!' );
|
24
|
+
print.whiteLine( 'Config file [#repoRootPath#config.json] is already formatted! No Chanages needed.' );
|
23
25
|
}
|
24
26
|
}
|
25
27
|
|
@@ -0,0 +1,197 @@
|
|
1
|
+
/**
|
2
|
+
* Generate README.md files for exercises
|
3
|
+
*/
|
4
|
+
component {
|
5
|
+
|
6
|
+
/**
|
7
|
+
* Run the task to generate read me files
|
8
|
+
*/
|
9
|
+
function run(
|
10
|
+
slug,
|
11
|
+
boolean all=false,
|
12
|
+
boolean force=false
|
13
|
+
){
|
14
|
+
|
15
|
+
/* Init global variables */
|
16
|
+
repoRootPath = expandPath( getDirectoryFromPath( getCurrentTemplatePath() ) & '../' );
|
17
|
+
problemSpecsPath = expandPath( getDirectoryFromPath( getCurrentTemplatePath() ) & '../../problem-specifications' );
|
18
|
+
trackReadmeInsert= fileRead( repoRootPath & "docs/EXERCISE_README_INSERT.md" );
|
19
|
+
overwriteExistingFiles = arguments.force;
|
20
|
+
|
21
|
+
if( !directoryExists( problemSpecsPath ) ){
|
22
|
+
error( 'Cannot find [problem-specifications] repo. It needs to be git cloned to [#problemSpecsPath#]' );
|
23
|
+
}
|
24
|
+
|
25
|
+
if( all ) {
|
26
|
+
|
27
|
+
// Get an array of all the excercise names
|
28
|
+
var exercises = directoryList( expandPath( getDirectoryFromPath( getCurrentTemplatePath() ) & '../exercises' ) )
|
29
|
+
.map( function( path ) {
|
30
|
+
return path.listLast( '/\' );
|
31
|
+
} );
|
32
|
+
|
33
|
+
} else {
|
34
|
+
|
35
|
+
// Acquire slug
|
36
|
+
if( isNull( arguments.slug ) ) {
|
37
|
+
arguments.slug = ask( 'Exercise slug as defined by Excercism. Ex: "hello-world": ' );
|
38
|
+
}
|
39
|
+
var exercises = [ slug ];
|
40
|
+
|
41
|
+
}
|
42
|
+
|
43
|
+
exercises.each( function( slug ) {
|
44
|
+
|
45
|
+
generateReadme( arguments.slug );
|
46
|
+
|
47
|
+
} ); // End exercises.each()
|
48
|
+
|
49
|
+
}
|
50
|
+
|
51
|
+
private function generateReadme( required string slug ) {
|
52
|
+
|
53
|
+
var readmeContent = "";
|
54
|
+
var readMeFile = repoRootPath & "/exercises/" & arguments.slug & "/README.md";
|
55
|
+
|
56
|
+
if ( !fileExists(readMeFile) || overwriteExistingFiles) {
|
57
|
+
|
58
|
+
var spec = getSpec( arguments.slug );
|
59
|
+
|
60
|
+
readmeContent = "## #spec.name#" & chr( 10 ) & chr( 10 );
|
61
|
+
readmeContent = readmeContent & spec.description & chr( 10 );
|
62
|
+
readmeContent = readmeContent & getHints( arguments.slug ) & chr( 10 );
|
63
|
+
readmeContent = readmeContent & trackReadmeInsert & chr( 10 );
|
64
|
+
readmeContent = readmeContent & spec.credits & chr( 10 );
|
65
|
+
readmeContent = readmeContent & "#### Submitting Incomplete Solutions#chr( 10 )#It's possible to submit an incomplete solution so you can see how others have completed the exercise.#chr( 10 )#";
|
66
|
+
|
67
|
+
/* Write the file */
|
68
|
+
fileWrite( readMeFile , readmeContent );
|
69
|
+
|
70
|
+
print.greenLine( 'Readme generated!' )
|
71
|
+
.indentedYellowLine( readMeFile )
|
72
|
+
.toConsole();
|
73
|
+
}
|
74
|
+
else {
|
75
|
+
print.redLine("README.md already exists! Use the overwrite=true to overwrite the file.")
|
76
|
+
.indentedYellowLine( readMeFile )
|
77
|
+
.toConsole();
|
78
|
+
}
|
79
|
+
|
80
|
+
}
|
81
|
+
|
82
|
+
/**
|
83
|
+
*
|
84
|
+
* Get the optional .meta/hint.md content
|
85
|
+
*
|
86
|
+
*/
|
87
|
+
private function getHints( required string slug ) {
|
88
|
+
|
89
|
+
var hintsFilePath = repoRootPath & "/exercises/" & arguments.slug & "/.meta/hints.md";
|
90
|
+
var hints = fileExists( hintsFilePath ) ? fileRead( hintsFilePath ) : "";
|
91
|
+
|
92
|
+
return hints;
|
93
|
+
}
|
94
|
+
|
95
|
+
private function getSpec( required string slug ) {
|
96
|
+
|
97
|
+
var spec = getExerciseMetadata( arguments.slug );
|
98
|
+
|
99
|
+
/* Use title from metadata.yml if provided else we must use the slug */
|
100
|
+
if ( len( spec.title )) {
|
101
|
+
spec.name = spec.title;
|
102
|
+
}
|
103
|
+
else {
|
104
|
+
spec.name = titleCaseSlug( arguments.slug );
|
105
|
+
}
|
106
|
+
|
107
|
+
spec.credits = getCredits( spec );
|
108
|
+
spec.description = getDescription( arguments.slug );
|
109
|
+
|
110
|
+
return spec;
|
111
|
+
}
|
112
|
+
|
113
|
+
/**
|
114
|
+
*
|
115
|
+
* Get the exercise description
|
116
|
+
*
|
117
|
+
*/
|
118
|
+
private function getDescription( required string slug ) {
|
119
|
+
|
120
|
+
var descriptionFilePath = problemSpecsPath & "/exercises/" & arguments.slug & "/description.md";
|
121
|
+
|
122
|
+
return fileExists( descriptionFilePath ) ? trim( fileRead( descriptionFilePath ) ) : "";
|
123
|
+
}
|
124
|
+
|
125
|
+
/**
|
126
|
+
*
|
127
|
+
* Get the content for exercise credits
|
128
|
+
*
|
129
|
+
*/
|
130
|
+
private function getCredits( required struct spec ) {
|
131
|
+
|
132
|
+
if ( spec.source_url == "" ) {
|
133
|
+
var credits = spec.source;
|
134
|
+
}
|
135
|
+
else if ( spec.source == "") {
|
136
|
+
var credits = "[#spec.source_url#](#spec.source_url#)";
|
137
|
+
}
|
138
|
+
else {
|
139
|
+
var credits = "#spec.source# [#spec.source_url#](#spec.source_url#)";
|
140
|
+
}
|
141
|
+
|
142
|
+
if ( len( credits ) ) {
|
143
|
+
credits = "#### Source" & chr( 10 ) & chr( 10 ) & credits & chr( 10 );
|
144
|
+
}
|
145
|
+
|
146
|
+
return credits;
|
147
|
+
}
|
148
|
+
|
149
|
+
/**
|
150
|
+
*
|
151
|
+
* Convert exercise slug to a title
|
152
|
+
*
|
153
|
+
*/
|
154
|
+
private function titleCaseSlug( required string slug ) {
|
155
|
+
return trim( reReplace( arguments.slug, "(\b|-)([a-zA-Z])", " \u\2", "all" ) );
|
156
|
+
}
|
157
|
+
|
158
|
+
/**
|
159
|
+
*
|
160
|
+
* Get exercise metadata from metadata.yml in the problem-specifications
|
161
|
+
*
|
162
|
+
*/
|
163
|
+
private struct function getExerciseMetadata( required string slug ) {
|
164
|
+
|
165
|
+
var metadataFilePath = problemSpecsPath & "/exercises/" & arguments.slug & "/metadata.yml";
|
166
|
+
var content = fileRead(metadataFilePath);
|
167
|
+
var metadata = {};
|
168
|
+
|
169
|
+
/* Get the title if provided in metadata.yml */
|
170
|
+
metadata.title = parseMetadata( "title", content );
|
171
|
+
|
172
|
+
/* Get the source of the exercise if provided in metadata.yml */
|
173
|
+
metadata.source = parseMetadata( "source", content );
|
174
|
+
|
175
|
+
/* Get the source url if provided in metadata.yml */
|
176
|
+
metadata.source_url = parseMetadata( "source_url", content );
|
177
|
+
|
178
|
+
return metadata;
|
179
|
+
}
|
180
|
+
|
181
|
+
/**
|
182
|
+
*
|
183
|
+
* Parse metadata from metadata.yml content
|
184
|
+
*
|
185
|
+
*/
|
186
|
+
private string function parseMetadata( required string key, required string content ) {
|
187
|
+
var result = "";
|
188
|
+
|
189
|
+
var matches = reFindNoCase( "#arguments.key#: ""(.*?)""", content, 1, true );
|
190
|
+
if ( matches.pos.len() == 2 ) {
|
191
|
+
result = mid( content, matches.pos[2], matches.len[2]);
|
192
|
+
}
|
193
|
+
|
194
|
+
return result;
|
195
|
+
}
|
196
|
+
|
197
|
+
}
|
@@ -79,6 +79,12 @@ component {
|
|
79
79
|
.params( 'GenerateTests', 'run', slug )
|
80
80
|
.inWorkingDirectory( repoRootPath & '/tasks' )
|
81
81
|
.run();
|
82
|
+
|
83
|
+
// Generate README.md
|
84
|
+
command( 'task run' )
|
85
|
+
.params( 'GenerateReadme', 'run', slug )
|
86
|
+
.inWorkingDirectory( repoRootPath & '/tasks' )
|
87
|
+
.run();
|
82
88
|
|
83
89
|
}
|
84
90
|
|
data/tracks/csharp/config.json
CHANGED
@@ -36,7 +36,7 @@ end;
|
|
36
36
|
|
37
37
|
procedure YearTest.year_divisible_by_4_not_divisible_by_100_leap_year;
|
38
38
|
begin
|
39
|
-
assert.IsTrue(TYear.IsLeap(
|
39
|
+
assert.IsTrue(TYear.IsLeap(1996), 'Expected ''true'', 1996 is a leap year.');
|
40
40
|
end;
|
41
41
|
|
42
42
|
procedure YearTest.year_divisible_by_100_not_divisible_by_400_common_year;
|
@@ -1,96 +1,274 @@
|
|
1
|
+
// This file was auto-generated based on version 1.0.1 of the canonical data.
|
2
|
+
|
1
3
|
module ClockTest
|
2
4
|
|
3
|
-
open System
|
4
|
-
open Xunit
|
5
5
|
open FsUnit.Xunit
|
6
|
+
open Xunit
|
7
|
+
|
6
8
|
open Clock
|
7
9
|
|
8
10
|
[<Fact>]
|
9
|
-
let ``
|
10
|
-
let clock =
|
11
|
+
let ``On the hour`` () =
|
12
|
+
let clock = create 8 0
|
11
13
|
display clock |> should equal "08:00"
|
12
14
|
|
13
|
-
[<Fact(Skip = "Remove to run test")>]
|
14
|
-
let ``
|
15
|
-
let clock =
|
16
|
-
display clock |> should equal "09:00"
|
17
|
-
|
18
|
-
[<Fact(Skip = "Remove to run test")>]
|
19
|
-
let ``Can print single-digit minutes`` () =
|
20
|
-
let clock = mkClock 11 9
|
15
|
+
[<Fact(Skip = "Remove to run test")>]
|
16
|
+
let ``Past the hour`` () =
|
17
|
+
let clock = create 11 9
|
21
18
|
display clock |> should equal "11:09"
|
22
19
|
|
23
20
|
[<Fact(Skip = "Remove to run test")>]
|
24
|
-
let ``
|
25
|
-
let clock =
|
26
|
-
display clock |> should equal "
|
21
|
+
let ``Midnight is zero hours`` () =
|
22
|
+
let clock = create 24 0
|
23
|
+
display clock |> should equal "00:00"
|
27
24
|
|
28
25
|
[<Fact(Skip = "Remove to run test")>]
|
29
|
-
let ``
|
30
|
-
let clock =
|
31
|
-
|
32
|
-
display added |> should equal "10:03"
|
26
|
+
let ``Hour rolls over`` () =
|
27
|
+
let clock = create 25 0
|
28
|
+
display clock |> should equal "01:00"
|
33
29
|
|
34
30
|
[<Fact(Skip = "Remove to run test")>]
|
35
|
-
let ``
|
36
|
-
let clock =
|
37
|
-
|
38
|
-
display added |> should equal "11:03"
|
31
|
+
let ``Hour rolls over continuously`` () =
|
32
|
+
let clock = create 100 0
|
33
|
+
display clock |> should equal "04:00"
|
39
34
|
|
40
35
|
[<Fact(Skip = "Remove to run test")>]
|
41
|
-
let ``
|
42
|
-
let clock =
|
43
|
-
|
44
|
-
display added |> should equal "10:24"
|
36
|
+
let ``Sixty minutes is next hour`` () =
|
37
|
+
let clock = create 1 60
|
38
|
+
display clock |> should equal "02:00"
|
45
39
|
|
46
40
|
[<Fact(Skip = "Remove to run test")>]
|
47
|
-
let ``
|
48
|
-
let clock =
|
49
|
-
|
50
|
-
display subtracted |> should equal "10:00"
|
41
|
+
let ``Minutes roll over`` () =
|
42
|
+
let clock = create 0 160
|
43
|
+
display clock |> should equal "02:40"
|
51
44
|
|
52
45
|
[<Fact(Skip = "Remove to run test")>]
|
53
|
-
let ``
|
54
|
-
let clock =
|
55
|
-
|
56
|
-
display subtracted |> should equal "09:33"
|
46
|
+
let ``Minutes roll over continuously`` () =
|
47
|
+
let clock = create 0 1723
|
48
|
+
display clock |> should equal "04:43"
|
57
49
|
|
58
50
|
[<Fact(Skip = "Remove to run test")>]
|
59
|
-
let ``
|
60
|
-
let clock =
|
61
|
-
|
62
|
-
display subtracted |> should equal "08:53"
|
51
|
+
let ``Hour and minutes roll over`` () =
|
52
|
+
let clock = create 25 160
|
53
|
+
display clock |> should equal "03:40"
|
63
54
|
|
64
55
|
[<Fact(Skip = "Remove to run test")>]
|
65
|
-
let ``
|
66
|
-
let clock =
|
67
|
-
|
68
|
-
display added |> should equal "00:01"
|
56
|
+
let ``Hour and minutes roll over continuously`` () =
|
57
|
+
let clock = create 201 3001
|
58
|
+
display clock |> should equal "11:01"
|
69
59
|
|
70
60
|
[<Fact(Skip = "Remove to run test")>]
|
71
|
-
let ``
|
72
|
-
let clock =
|
73
|
-
|
74
|
-
display subtracted |> should equal "23:59"
|
61
|
+
let ``Hour and minutes roll over to exactly midnight`` () =
|
62
|
+
let clock = create 72 8640
|
63
|
+
display clock |> should equal "00:00"
|
75
64
|
|
76
65
|
[<Fact(Skip = "Remove to run test")>]
|
77
|
-
let ``
|
78
|
-
let clock =
|
79
|
-
display clock |> should equal "
|
66
|
+
let ``Negative hour`` () =
|
67
|
+
let clock = create -1 15
|
68
|
+
display clock |> should equal "23:15"
|
80
69
|
|
81
70
|
[<Fact(Skip = "Remove to run test")>]
|
82
|
-
let ``
|
83
|
-
let clock =
|
84
|
-
display clock |> should equal "
|
71
|
+
let ``Negative hour rolls over`` () =
|
72
|
+
let clock = create -25 0
|
73
|
+
display clock |> should equal "23:00"
|
74
|
+
|
75
|
+
[<Fact(Skip = "Remove to run test")>]
|
76
|
+
let ``Negative hour rolls over continuously`` () =
|
77
|
+
let clock = create -91 0
|
78
|
+
display clock |> should equal "05:00"
|
79
|
+
|
80
|
+
[<Fact(Skip = "Remove to run test")>]
|
81
|
+
let ``Negative minutes`` () =
|
82
|
+
let clock = create 1 -40
|
83
|
+
display clock |> should equal "00:20"
|
84
|
+
|
85
|
+
[<Fact(Skip = "Remove to run test")>]
|
86
|
+
let ``Negative minutes roll over`` () =
|
87
|
+
let clock = create 1 -160
|
88
|
+
display clock |> should equal "22:20"
|
89
|
+
|
90
|
+
[<Fact(Skip = "Remove to run test")>]
|
91
|
+
let ``Negative minutes roll over continuously`` () =
|
92
|
+
let clock = create 1 -4820
|
93
|
+
display clock |> should equal "16:40"
|
94
|
+
|
95
|
+
[<Fact(Skip = "Remove to run test")>]
|
96
|
+
let ``Negative hour and minutes both roll over`` () =
|
97
|
+
let clock = create -25 -160
|
98
|
+
display clock |> should equal "20:20"
|
99
|
+
|
100
|
+
[<Fact(Skip = "Remove to run test")>]
|
101
|
+
let ``Negative hour and minutes both roll over continuously`` () =
|
102
|
+
let clock = create -121 -5810
|
103
|
+
display clock |> should equal "22:10"
|
104
|
+
|
105
|
+
[<Fact(Skip = "Remove to run test")>]
|
106
|
+
let ``Add minutes`` () =
|
107
|
+
let clock = create 10 0
|
108
|
+
add 3 clock |> display |> should equal "10:03"
|
109
|
+
|
110
|
+
[<Fact(Skip = "Remove to run test")>]
|
111
|
+
let ``Add no minutes`` () =
|
112
|
+
let clock = create 6 41
|
113
|
+
add 0 clock |> display |> should equal "06:41"
|
114
|
+
|
115
|
+
[<Fact(Skip = "Remove to run test")>]
|
116
|
+
let ``Add to next hour`` () =
|
117
|
+
let clock = create 0 45
|
118
|
+
add 40 clock |> display |> should equal "01:25"
|
119
|
+
|
120
|
+
[<Fact(Skip = "Remove to run test")>]
|
121
|
+
let ``Add more than one hour`` () =
|
122
|
+
let clock = create 10 0
|
123
|
+
add 61 clock |> display |> should equal "11:01"
|
124
|
+
|
125
|
+
[<Fact(Skip = "Remove to run test")>]
|
126
|
+
let ``Add more than two hours with carry`` () =
|
127
|
+
let clock = create 0 45
|
128
|
+
add 160 clock |> display |> should equal "03:25"
|
129
|
+
|
130
|
+
[<Fact(Skip = "Remove to run test")>]
|
131
|
+
let ``Add across midnight`` () =
|
132
|
+
let clock = create 23 59
|
133
|
+
add 2 clock |> display |> should equal "00:01"
|
134
|
+
|
135
|
+
[<Fact(Skip = "Remove to run test")>]
|
136
|
+
let ``Add more than one day (1500 min = 25 hrs)`` () =
|
137
|
+
let clock = create 5 32
|
138
|
+
add 1500 clock |> display |> should equal "06:32"
|
139
|
+
|
140
|
+
[<Fact(Skip = "Remove to run test")>]
|
141
|
+
let ``Add more than two days`` () =
|
142
|
+
let clock = create 1 1
|
143
|
+
add 3500 clock |> display |> should equal "11:21"
|
144
|
+
|
145
|
+
[<Fact(Skip = "Remove to run test")>]
|
146
|
+
let ``Subtract minutes`` () =
|
147
|
+
let clock = create 10 3
|
148
|
+
add -3 clock |> display |> should equal "10:00"
|
149
|
+
|
150
|
+
[<Fact(Skip = "Remove to run test")>]
|
151
|
+
let ``Subtract to previous hour`` () =
|
152
|
+
let clock = create 10 3
|
153
|
+
add -30 clock |> display |> should equal "09:33"
|
154
|
+
|
155
|
+
[<Fact(Skip = "Remove to run test")>]
|
156
|
+
let ``Subtract more than an hour`` () =
|
157
|
+
let clock = create 10 3
|
158
|
+
add -70 clock |> display |> should equal "08:53"
|
159
|
+
|
160
|
+
[<Fact(Skip = "Remove to run test")>]
|
161
|
+
let ``Subtract across midnight`` () =
|
162
|
+
let clock = create 0 3
|
163
|
+
add -4 clock |> display |> should equal "23:59"
|
164
|
+
|
165
|
+
[<Fact(Skip = "Remove to run test")>]
|
166
|
+
let ``Subtract more than two hours`` () =
|
167
|
+
let clock = create 0 0
|
168
|
+
add -160 clock |> display |> should equal "21:20"
|
169
|
+
|
170
|
+
[<Fact(Skip = "Remove to run test")>]
|
171
|
+
let ``Subtract more than two hours with borrow`` () =
|
172
|
+
let clock = create 6 15
|
173
|
+
add -160 clock |> display |> should equal "03:35"
|
174
|
+
|
175
|
+
[<Fact(Skip = "Remove to run test")>]
|
176
|
+
let ``Subtract more than one day (1500 min = 25 hrs)`` () =
|
177
|
+
let clock = create 5 32
|
178
|
+
add -1500 clock |> display |> should equal "04:32"
|
179
|
+
|
180
|
+
[<Fact(Skip = "Remove to run test")>]
|
181
|
+
let ``Subtract more than two days`` () =
|
182
|
+
let clock = create 2 20
|
183
|
+
add -3000 clock |> display |> should equal "00:20"
|
184
|
+
|
185
|
+
[<Fact(Skip = "Remove to run test")>]
|
186
|
+
let ``Clocks with same time`` () =
|
187
|
+
let clock1 = create 15 37
|
188
|
+
let clock2 = create 15 37
|
189
|
+
clock1 = clock2 |> should equal true
|
190
|
+
|
191
|
+
[<Fact(Skip = "Remove to run test")>]
|
192
|
+
let ``Clocks a minute apart`` () =
|
193
|
+
let clock1 = create 15 36
|
194
|
+
let clock2 = create 15 37
|
195
|
+
clock1 = clock2 |> should equal false
|
196
|
+
|
197
|
+
[<Fact(Skip = "Remove to run test")>]
|
198
|
+
let ``Clocks an hour apart`` () =
|
199
|
+
let clock1 = create 14 37
|
200
|
+
let clock2 = create 15 37
|
201
|
+
clock1 = clock2 |> should equal false
|
85
202
|
|
86
203
|
[<Fact(Skip = "Remove to run test")>]
|
87
|
-
let ``Clocks with
|
88
|
-
let clock1 =
|
89
|
-
let clock2 =
|
90
|
-
clock1 |> should equal
|
204
|
+
let ``Clocks with hour overflow`` () =
|
205
|
+
let clock1 = create 10 37
|
206
|
+
let clock2 = create 34 37
|
207
|
+
clock1 = clock2 |> should equal true
|
91
208
|
|
92
209
|
[<Fact(Skip = "Remove to run test")>]
|
93
|
-
let ``
|
94
|
-
let clock1 =
|
95
|
-
let clock2 =
|
96
|
-
clock1 |> should equal
|
210
|
+
let ``Clocks with hour overflow by several days`` () =
|
211
|
+
let clock1 = create 3 11
|
212
|
+
let clock2 = create 99 11
|
213
|
+
clock1 = clock2 |> should equal true
|
214
|
+
|
215
|
+
[<Fact(Skip = "Remove to run test")>]
|
216
|
+
let ``Clocks with negative hour`` () =
|
217
|
+
let clock1 = create 22 40
|
218
|
+
let clock2 = create -2 40
|
219
|
+
clock1 = clock2 |> should equal true
|
220
|
+
|
221
|
+
[<Fact(Skip = "Remove to run test")>]
|
222
|
+
let ``Clocks with negative hour that wraps`` () =
|
223
|
+
let clock1 = create 17 3
|
224
|
+
let clock2 = create -31 3
|
225
|
+
clock1 = clock2 |> should equal true
|
226
|
+
|
227
|
+
[<Fact(Skip = "Remove to run test")>]
|
228
|
+
let ``Clocks with negative hour that wraps multiple times`` () =
|
229
|
+
let clock1 = create 13 49
|
230
|
+
let clock2 = create -83 49
|
231
|
+
clock1 = clock2 |> should equal true
|
232
|
+
|
233
|
+
[<Fact(Skip = "Remove to run test")>]
|
234
|
+
let ``Clocks with minute overflow`` () =
|
235
|
+
let clock1 = create 0 1
|
236
|
+
let clock2 = create 0 1441
|
237
|
+
clock1 = clock2 |> should equal true
|
238
|
+
|
239
|
+
[<Fact(Skip = "Remove to run test")>]
|
240
|
+
let ``Clocks with minute overflow by several days`` () =
|
241
|
+
let clock1 = create 2 2
|
242
|
+
let clock2 = create 2 4322
|
243
|
+
clock1 = clock2 |> should equal true
|
244
|
+
|
245
|
+
[<Fact(Skip = "Remove to run test")>]
|
246
|
+
let ``Clocks with negative minute`` () =
|
247
|
+
let clock1 = create 2 40
|
248
|
+
let clock2 = create 3 -20
|
249
|
+
clock1 = clock2 |> should equal true
|
250
|
+
|
251
|
+
[<Fact(Skip = "Remove to run test")>]
|
252
|
+
let ``Clocks with negative minute that wraps`` () =
|
253
|
+
let clock1 = create 4 10
|
254
|
+
let clock2 = create 5 -1490
|
255
|
+
clock1 = clock2 |> should equal true
|
256
|
+
|
257
|
+
[<Fact(Skip = "Remove to run test")>]
|
258
|
+
let ``Clocks with negative minute that wraps multiple times`` () =
|
259
|
+
let clock1 = create 6 15
|
260
|
+
let clock2 = create 6 -4305
|
261
|
+
clock1 = clock2 |> should equal true
|
262
|
+
|
263
|
+
[<Fact(Skip = "Remove to run test")>]
|
264
|
+
let ``Clocks with negative hours and minutes`` () =
|
265
|
+
let clock1 = create 7 32
|
266
|
+
let clock2 = create -12 -268
|
267
|
+
clock1 = clock2 |> should equal true
|
268
|
+
|
269
|
+
[<Fact(Skip = "Remove to run test")>]
|
270
|
+
let ``Clocks with negative hours and minutes that wrap`` () =
|
271
|
+
let clock1 = create 18 7
|
272
|
+
let clock2 = create -54 -11513
|
273
|
+
clock1 = clock2 |> should equal true
|
274
|
+
|