implement custom output path flag and integration tests
This commit is contained in:
@@ -25,23 +25,30 @@ 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];
|
||||||
if (arg == "--help" || arg == "-h") {
|
if (arg == "--help" || arg == "-h") {
|
||||||
cout <<
|
cout <<
|
||||||
"ccolors - extract color palette from images\n\n"
|
"ccolors - extract color palette from images\n\n"
|
||||||
"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";
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user