From 14e2dd2546dacee10f24a87aa8918107072fe43e Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Mon, 3 May 2021 13:23:51 +0200 Subject: [PATCH] tests(sync/tracks): add basic tests (#304) This adds basic tests for `findTrackExercises`, which is the main exported proc from `src/sync/tracks.nim`. Later, we can refactor to avoid the string comparison. --- tests/all_tests.nim | 1 + tests/test_tracks.nim | 85 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 tests/test_tracks.nim diff --git a/tests/all_tests.nim b/tests/all_tests.nim index aca202bf..0cee2bb0 100644 --- a/tests/all_tests.nim +++ b/tests/all_tests.nim @@ -2,5 +2,6 @@ import "."/[ test_binary, test_lint, test_probspecs, + test_tracks, test_uuid, ] diff --git a/tests/test_tracks.nim b/tests/test_tracks.nim new file mode 100644 index 00000000..d6be86af --- /dev/null +++ b/tests/test_tracks.nim @@ -0,0 +1,85 @@ +# This file implements tests for `src/tracks.nim` +import std/[os, osproc, parseutils, sets, strformat, unittest] +import "."/[cli, sync/tracks] + +func oneLine(s: string): string = + ## Returns the string `s`, but: + ## - replaces each newline character with a single space. + ## - strips all per-line leading whitespace. + ## - strips trailing whitespace. + result = newStringOfCap(s.len) + var i = 0 + var line: string + while i < s.len: + i += s.skipWhitespace(i) + i += s.parseUntil(line, '\n', i) + result.add line + result.add " " + # Remove final two space characters. + result.setLen(result.len - 2) + +proc main = + suite "findTrackExercises": + const trackDir = ".test_tracks_nim_track_repo" + removeDir(trackDir) + let cmd = &"git clone --quiet https://github.com/exercism/nim.git {trackDir}" + if execCmd(cmd) != 0: + stderr.writeLine "Error: failed to clone the track repo" + quit(1) + + const gitHash = "6e909c9e5338cd567c20224069df00e031fb2efa" + if execCmd(&"git -C {trackDir} checkout --quiet {gitHash}") != 0: + stderr.writeLine "Error: could not checkout a specific commit" + quit(1) + + let conf = Conf( + action: initAction(actSync), + trackDir: trackDir, + ) + let trackExercises = findTrackExercises(conf) + + test "returns the expected number of exercises": + check: + trackExercises.len == 68 + + # Here, just test against the string representation of each object (as we + # don't want to export more types from `tracks.nim` just for testing). + # This is one way of testing the public interface rather than implementation + # details. + test "returns the expected object for `hello-world`": + const expectedHelloWorld = """ + (slug: "hello-world", + tests: (included: {"af9ffe10-dc13-42d8-a742-e7bdafac449d"}, + excluded: {}), + repoExercise: (dir: "")) + """.oneLine() + + check: + trackExercises[0].`$` == expectedHelloWorld + + test "returns the expected object for `two-fer`": + const expectedTwoFer = """ + (slug: "two-fer", + tests: (included: {"1cf3e15a-a3d7-4a87-aeb3-ba1b43bc8dce", + "3549048d-1a6e-4653-9a79-b0bda163e8d5", + "b4c6dbb8-b4fb-42c2-bafd-10785abe7709"}, + excluded: {}), + repoExercise: (dir: "")) + """.oneLine() + check: + trackExercises[1].`$` == expectedTwoFer + + # Try to remove the track directory, but allow the tests to pass if there + # was an error removing it. + # This resolves a CI failure on Windows. + # "The process cannot access the file because it is being used by another + # process." + try: + sleep(1000) + removeDir(trackDir) + except CatchableError: + stderr.writeLine &"Error: could not remove the directory: {trackDir}" + stderr.writeLine getCurrentExceptionMsg() + +main() +{.used.}