GCC Code Coverage Report


src/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
34 / 35, 1 excl
97.1%
Branches:
9 / 10, 18 excl
90.0%
Functions:
6 / 6
100.0%

exception/cli-error.spice
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 // Std imports
4 import "std/text/stringstream";
5
6 public type CliErrorType enum {
7 INCOMPATIBLE_OPTIONS,
8 NON_ZERO_EXIT_CODE,
9 FEATURE_NOT_SUPPORTED_FOR_TARGET,
10 FEATURE_NOT_SUPPORTED_WHEN_DOCKERIZED,
11 INVALID_BUILD_MODE,
12 INVALID_OUTPUT_CONTAINER,
13 INVALID_SANITIZER,
14 INVALID_BACKEND,
15 INVALID_DEBUG_INFO_LEVEL
16 }
17
18 /**
19 * Custom exception for errors, occurring when linking the output executable
20 */
21 9 public type CliError struct {
22 String errorMessage
23 }
24
25 /**
26 * @param errorType Type of the error
27 * @param message Error message suffix
28 */
29 18 public p CliError.ctor(const CliErrorType errorType, const string message) {
30 18 StringStream msg;
31 18 msg << "[Error|CLI] " << this.getMessagePrefix(errorType) << ": " << message;
32 18 this.errorMessage = msg.str();
33 18 }
34
35 /**
36 * Get the message for this particular error instance
37 *
38 * @return Error message
39 */
40 18 public f<const String&> CliError.getMessage() {
41 18 return this.errorMessage;
42 }
43
44 /**
45 * Get the prefix of the error message for a particular error
46 *
47 * @param errorType Type of the error
48 * @return Prefix string for the error type
49 */
50 18 f<string> CliError.getMessagePrefix(const CliErrorType errorType) {
51
9/10
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 2 times.
18 switch errorType {
52 5 case CliErrorType::INCOMPATIBLE_OPTIONS: { return "Incompatible options"; }
53 1 case CliErrorType::NON_ZERO_EXIT_CODE: { return "Non-zero exit code"; }
54 1 case CliErrorType::FEATURE_NOT_SUPPORTED_FOR_TARGET: { return "Feature is not supported for this target"; }
55 1 case CliErrorType::FEATURE_NOT_SUPPORTED_WHEN_DOCKERIZED: { return "Feature not supported when dockerized"; }
56 2 case CliErrorType::INVALID_BUILD_MODE: { return "Invalid build mode"; }
57 2 case CliErrorType::INVALID_OUTPUT_CONTAINER: { return "Invalid output container"; }
58 2 case CliErrorType::INVALID_SANITIZER: { return "Invalid sanitizer"; }
59 2 case CliErrorType::INVALID_BACKEND: { return "Invalid backend"; }
60 2 case CliErrorType::INVALID_DEBUG_INFO_LEVEL: { return "Invalid debug info level"; }
61 − default: { panic(Error("Unknown error")); } // LCOV_EXCL_LINE
62 }
63 ✗ }
64
65 // ─── tests ────────────────────────────────────────────────────────────────────
66
67 9 f<bool> hasMessage(const CliErrorType errorType, const string message, const string expectedMessage) {
68 9 const CliError cliError = CliError(errorType, message);
69 18 return cliError.getMessage() == expectedMessage;
70 9 }
71
72 // The driver reports cli errors by exiting the process, which a builtin test cannot observe. So the messages of the rejected cli
73 // arguments are checked here, at the level of the error itself
74 1 #[test]
75 f<bool> testCliErrorMessages() {
76 // Invalid enum values
77 1 assert hasMessage(CliErrorType::INVALID_BUILD_MODE, "unknown", "[Error|CLI] Invalid build mode: unknown");
78 1 assert hasMessage(CliErrorType::INVALID_SANITIZER, "unknown", "[Error|CLI] Invalid sanitizer: unknown");
79 1 assert hasMessage(CliErrorType::INVALID_OUTPUT_CONTAINER, "unknown", "[Error|CLI] Invalid output container: unknown");
80 1 assert hasMessage(CliErrorType::INVALID_BACKEND, "unknown", "[Error|CLI] Invalid backend: unknown");
81 1 assert hasMessage(CliErrorType::INVALID_DEBUG_INFO_LEVEL, "unknown", "[Error|CLI] Invalid debug info level: unknown");
82
83 // Incompatible options and unsupported features
84 1 assert hasMessage(CliErrorType::INCOMPATIBLE_OPTIONS, "Cannot link statically if compiling shared library", "[Error|CLI] Incompatible options: Cannot link statically if compiling shared library");
85 1 assert hasMessage(CliErrorType::FEATURE_NOT_SUPPORTED_FOR_TARGET, "Memory sanitizer is only supported for Linux targets", "[Error|CLI] Feature is not supported for this target: Memory sanitizer is only supported for Linux targets");
86 1 assert hasMessage(CliErrorType::FEATURE_NOT_SUPPORTED_WHEN_DOCKERIZED, "message", "[Error|CLI] Feature not supported when dockerized: message");
87 1 assert hasMessage(CliErrorType::NON_ZERO_EXIT_CODE, "1", "[Error|CLI] Non-zero exit code: 1");
88 1 return true;
89 }
90