implement custom output path flag and integration tests

This commit is contained in:
2026-08-08 12:22:44 +03:00
parent f42059fc61
commit 4c48af7679
2 changed files with 47 additions and 5 deletions
+16 -4
View File
@@ -25,6 +25,7 @@ struct Bucket {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
bool quiet = false; bool quiet = false;
std::string output_path = "palette.json";
std::string imagefile; std::string imagefile;
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
std::string arg = argv[i]; std::string arg = argv[i];
@@ -34,14 +35,20 @@ int main(int argc, char *argv[]) {
"Usage:\n" "Usage:\n"
" " << argv[0] << " <image> [options]\n\n" " " << argv[0] << " <image> [options]\n\n"
"Options:\n" "Options:\n"
" -h, --help Show this help page\n" " -h, --help Show this help page\n"
" -q, --quiet Suppress terminal output (JSON is still written)\n\n" " -q, --quiet Suppress terminal output (JSON is still written)\n"
" -o, --output <file> Write JSON palette to <file> (default: palette.json)\n\n"
"Output:\n" "Output:\n"
" Prints dominant colors as HEX and terminal swatches\n" " Prints dominant colors as HEX and terminal swatches\n"
" Also writes palette.json\n"; " Also writes palette.json (or the path given with -o)\n";
return 0; return 0;
} else if (arg == "--quiet" || arg == "-q") { } else if (arg == "--quiet" || arg == "-q") {
quiet = true; quiet = true;
} else if ((arg == "--output" || arg == "-o") && i + 1 < argc) {
output_path = argv[++i];
} else if ((arg == "--output" || arg == "-o") && i + 1 >= argc) {
cout << "Option " << arg << " requires an argument.\n";
return 1;
} else if (imagefile.empty()) { } else if (imagefile.empty()) {
imagefile = arg; imagefile = arg;
} else { } else {
@@ -167,7 +174,12 @@ int main(int argc, char *argv[]) {
int paletteSize = std::min(5, (int)buckets.size()); int paletteSize = std::min(5, (int)buckets.size());
std::ofstream json("palette.json"); std::ofstream json(output_path);
if (!json) {
cout << "Cannot open output file: " << output_path << "\n";
stbi_image_free(data);
return 1;
}
json << "{\n"; json << "{\n";
json << " \"image\": \"" << imagefile << "\",\n"; json << " \"image\": \"" << imagefile << "\",\n";
+30
View File
@@ -126,6 +126,34 @@ def test_invalid_format(binary, workdir):
"missing unknown-image-format message") "missing unknown-image-format message")
def test_custom_output(binary, workdir):
img = os.path.join(workdir, "solid.png")
make_png(img, 40, 40, (100, 150, 200))
custom_json = os.path.join(workdir, "custom_palette.json")
rc, out = run(binary, img, "-o", custom_json, cwd=workdir)
assert_(rc == 0, "custom-output: expected exit 0, got %d" % rc)
assert_(os.path.exists(custom_json), "custom JSON file was not written at: %s" % custom_json)
# Default palette.json must NOT be written when -o is given with a different path.
default_json = os.path.join(workdir, "palette.json")
assert_(not os.path.exists(default_json), "default palette.json should not be written when -o is used")
with open(custom_json) as f:
data = json.load(f)
assert_(data["image"] == img, "custom palette.json image field mismatch")
palette = data["palette"]
assert_(isinstance(palette, list) and 1 <= len(palette) <= 5,
"palette must be a non-empty list of at most 5 entries")
def test_custom_output_bad_path(binary, workdir):
img = os.path.join(workdir, "solid.png")
make_png(img, 40, 40, (100, 150, 200))
bad_path = os.path.join(workdir, "nonexistent_dir", "out.json")
rc, out = run(binary, img, "-o", bad_path, cwd=workdir)
assert_(rc != 0, "bad-output-path: expected non-zero exit, got 0")
assert_(b"Cannot open output file" in out,
"missing 'Cannot open output file' error message")
def main(): def main():
if len(sys.argv) < 2: if len(sys.argv) < 2:
print("usage: %s <path-to-ccolors-binary>" % sys.argv[0], file=sys.stderr) print("usage: %s <path-to-ccolors-binary>" % sys.argv[0], file=sys.stderr)
@@ -141,6 +169,8 @@ def main():
("happy_path_jpeg", lambda d: test_happy_path_jpeg(binary, d)), ("happy_path_jpeg", lambda d: test_happy_path_jpeg(binary, d)),
("file_not_found", lambda d: test_file_not_found(binary, d)), ("file_not_found", lambda d: test_file_not_found(binary, d)),
("invalid_format", lambda d: test_invalid_format(binary, d)), ("invalid_format", lambda d: test_invalid_format(binary, d)),
("custom_output", lambda d: test_custom_output(binary, d)),
("custom_output_bad_path", lambda d: test_custom_output_bad_path(binary, d)),
] ]
failures = [] failures = []
for name, fn in tests: for name, fn in tests: