All files

src/stdlib/testing_commands.panack

Green: covered; red: known zero; amber: unavailable. Blank lines are outside the executable-start-line denominator.

    1 import "testing.panack"
    2 import "process.panack"
    3 
    4 // Callers select the exact executable and resource bounds; there is no shell
    5 // or PATH search unless the caller explicitly invokes a shell.
    6 record TestCommand {
    7   executable: Path,
    8   arguments: [Str],
    9   stdin: Bytes,
   10   working_directory: Path,
   11   environment: [Str],
   12   timeout: Duration,
   13   output_limit: Nat
   14 }
   15 
   16 pure test_command_output(name: Str, actual: ProcessOutput,
   17                          expected: ProcessOutput): TestResult {
   18   if actual.exit_code != expected.exit_code {
   19     wanted = expected.exit_code
   20     got = actual.exit_code
   21     test_expect(name, false, "expected exit ${wanted}, got ${got}")
   22   } else {
   23     if actual.signal != expected.signal {
   24       wanted = expected.signal
   25       got = actual.signal
   26       test_expect(name, false, "expected signal ${wanted}, got ${got}")
   27     } else {
   28       if actual.stdout != expected.stdout {
   29         test_expect(name, false, "stdout differed")
   30       } else {
   31         if actual.stderr != expected.stderr {
   32           test_expect(name, false, "stderr differed")
   33         } else {
   34           test_expect(name, true, "")
   35         }
   36       }
   37     }
   38   }
   39 }
   40 
   41 pure test_command_result(name: Str, actual: Result[ProcessOutput,HostError],
   42                          expected: ProcessOutput): TestResult {
   43   match actual {
   44     Ok(output) => test_command_output(name, output, expected),
   45     Error(error) => {
   46       code = error.code
   47       test_expect(name, false, "command failed: ${code}")
   48     }
   49   }
   50 }
   51 
   52 test_run_command(name: Str, command: TestCommand,
   53                  expected: ProcessOutput): TestResult {
   54   test_command_result(name, process_run(command.executable, command.arguments,
   55     command.stdin, command.working_directory, command.environment,
   56     command.timeout, command.output_limit), expected)
   57 }
   58 
   59 test_expect_command_error(name: Str, command: TestCommand,
   60                           expected_code: Str): TestResult {
   61   match process_run(command.executable, command.arguments, command.stdin,
   62                     command.working_directory, command.environment,
   63                     command.timeout, command.output_limit) {
   64     Ok(output) => test_expect(name, false, "expected host error ${expected_code}, command completed"),
   65     Error(error) => {
   66       code = error.code
   67       test_expect(name, code == expected_code, "expected host error ${expected_code}, got ${code}")
   68     }
   69   }
   70 }
   71 

Functions

[
  {
    "id": "declaration/3",
    "name": "test_command_output",
    "line": 16,
    "state": "zero",
    "entries": "0"
  },
  {
    "id": "declaration/4",
    "name": "test_command_result",
    "line": 41,
    "state": "zero",
    "entries": "0"
  },
  {
    "id": "declaration/5",
    "name": "test_run_command",
    "line": 52,
    "state": "zero",
    "entries": "0"
  },
  {
    "id": "declaration/6",
    "name": "test_expect_command_error",
    "line": 59,
    "state": "zero",
    "entries": "0"
  }
]

Source branch outcomes

[
  {
    "id": "declaration/3/tail/decision/true",
    "outcome": "true",
    "line": 18,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/3/tail/decision/false",
    "outcome": "false",
    "line": 18,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/3/tail/false/tail/decision/true",
    "outcome": "true",
    "line": 23,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/3/tail/false/tail/decision/false",
    "outcome": "false",
    "line": 23,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/3/tail/false/tail/false/tail/decision/true",
    "outcome": "true",
    "line": 28,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/3/tail/false/tail/false/tail/decision/false",
    "outcome": "false",
    "line": 28,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/3/tail/false/tail/false/tail/false/tail/decision/true",
    "outcome": "true",
    "line": 31,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/3/tail/false/tail/false/tail/false/tail/decision/false",
    "outcome": "false",
    "line": 31,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/4/tail/arm/0",
    "outcome": "Ok",
    "line": 44,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/4/tail/arm/1",
    "outcome": "Error",
    "line": 45,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/6/tail/arm/0",
    "outcome": "Ok",
    "line": 64,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/6/tail/arm/1",
    "outcome": "Error",
    "line": 65,
    "state": "zero",
    "hits": "0"
  }
]

Reviewed declaration exclusions

[
  {
    "id": "declaration/0",
    "reason": "import",
    "line": 1
  },
  {
    "id": "declaration/1",
    "reason": "import",
    "line": 2
  },
  {
    "id": "declaration/2",
    "reason": "record-declaration",
    "line": 6
  }
]