master ohmu/fastfetch-openbsd / tests / size.c
ohmu  ·  2026-10-15
  1#include "common/size.h"
  2#include "common/textModifier.h"
  3#include "fastfetch.h"
  4
  5#include <stdint.h>
  6#include <stdio.h>
  7#include <stdlib.h>
  8
  9static void verify(uint64_t bytes, const char* expected, int lineNo) {
 10    FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate();
 11    ffSizeAppendNum(bytes, &result);
 12
 13    if (!ffStrbufEqualS(&result, expected)) {
 14        fprintf(stderr, FASTFETCH_TEXT_MODIFIER_ERROR "[%d] ffSizeAppendNum(%llu): expected \"%s\", got \"%s\"\n" FASTFETCH_TEXT_MODIFIER_RESET,
 15            lineNo, (unsigned long long) bytes, expected, result.chars);
 16        exit(1);
 17    }
 18}
 19
 20#define VERIFY_SIZE(bytes, expected) verify((bytes), (expected), __LINE__)
 21
 22int main(void) {
 23    // Use the real defaults rather than a hand built config, so a changed default is caught here too
 24    ffOptionsInitDisplay(&instance.config.display);
 25    FFOptionsDisplay* options = &instance.config.display;
 26
 27    // IEC (the default): 1024 based, with the `KiB` style suffixes
 28    {
 29        VERIFY_SIZE(0, "0 B");
 30        VERIFY_SIZE(1, "1 B");
 31        VERIFY_SIZE(999, "999 B");
 32        VERIFY_SIZE(1023, "1023 B"); // one byte short of the first prefix
 33        VERIFY_SIZE(1024, "1.00 KiB");
 34        VERIFY_SIZE(1025, "1.00 KiB"); // below the rounding precision
 35        VERIFY_SIZE(1536, "1.50 KiB");
 36        VERIFY_SIZE(1024ULL * 1024, "1.00 MiB");
 37        VERIFY_SIZE(1024ULL * 1024 * 1024, "1.00 GiB");
 38        VERIFY_SIZE(1024ULL * 1024 * 1024 * 1024, "1.00 TiB");
 39        VERIFY_SIZE(1024ULL * 1024 * 1024 * 1024 * 1024, "1.00 PiB");
 40        VERIFY_SIZE(1024ULL * 1024 * 1024 * 1024 * 1024 * 1024, "1.00 EiB");
 41
 42        // The largest 64 bit value is 16 EiB; `ZiB` and `YiB` are listed but can never be reached
 43        // through an IEC conversion of a `uint64_t`.
 44        VERIFY_SIZE(UINT64_MAX, "16.00 EiB");
 45    }
 46
 47    // SI: 1000 based, with the `kB` style suffixes
 48    {
 49        options->sizeBinaryPrefix = FF_SIZE_BINARY_PREFIX_TYPE_SI;
 50
 51        VERIFY_SIZE(0, "0 B");
 52        VERIFY_SIZE(999, "999 B");
 53        VERIFY_SIZE(1000, "1.00 kB");
 54        VERIFY_SIZE(1500, "1.50 kB");
 55        VERIFY_SIZE(1000000, "1.00 MB");
 56        VERIFY_SIZE(1000000000ULL, "1.00 GB");
 57        VERIFY_SIZE(1000000000000ULL, "1.00 TB");
 58        VERIFY_SIZE(1000000000000000ULL, "1.00 PB");
 59        VERIFY_SIZE(1000000000000000000ULL, "1.00 EB");
 60        VERIFY_SIZE(UINT64_MAX, "18.45 EB");
 61    }
 62
 63    // JEDEC: 1024 based, but with the `KB` style suffixes. The suffix list stops at `TB`, so the
 64    // loop has to stop there as well instead of reading past the end.
 65    {
 66        options->sizeBinaryPrefix = FF_SIZE_BINARY_PREFIX_TYPE_JEDEC;
 67
 68        VERIFY_SIZE(1023, "1023 B");
 69        VERIFY_SIZE(1024, "1.00 KB");
 70        VERIFY_SIZE(1024ULL * 1024, "1.00 MB");
 71        VERIFY_SIZE(1024ULL * 1024 * 1024, "1.00 GB");
 72        VERIFY_SIZE(1024ULL * 1024 * 1024 * 1024, "1.00 TB");
 73        VERIFY_SIZE(1024ULL * 1024 * 1024 * 1024 * 1024, "1024.00 TB"); // no `PB` in JEDEC
 74        VERIFY_SIZE(UINT64_MAX, "16777216.00 TB");
 75    }
 76
 77    options->sizeBinaryPrefix = FF_SIZE_BINARY_PREFIX_TYPE_IEC;
 78
 79    // sizeNdigits: the number of digits after the decimal point. It applies only once a prefix is
 80    // used -- a plain byte count is always printed as an integer.
 81    {
 82        options->sizeNdigits = 0;
 83        VERIFY_SIZE(1024, "1 KiB");
 84        VERIFY_SIZE(1536, "2 KiB"); // rounded, not truncated
 85        VERIFY_SIZE(512, "512 B");
 86        VERIFY_SIZE(1023, "1023 B");
 87
 88        options->sizeNdigits = 4;
 89        VERIFY_SIZE(1024, "1.0000 KiB");
 90        VERIFY_SIZE(1536, "1.5000 KiB");
 91        VERIFY_SIZE(512, "512 B"); // still an integer
 92        VERIFY_SIZE(0, "0 B");
 93
 94        options->sizeNdigits = 2;
 95    }
 96
 97    // sizeMaxPrefix: the index of the largest suffix that may be used. `0` disables the conversion
 98    // entirely.
 99    {
100        options->sizeMaxPrefix = 0;
101        VERIFY_SIZE(0, "0 B");
102        VERIFY_SIZE(1024, "1024 B");
103        VERIFY_SIZE(UINT64_MAX, "18446744073709551615 B");
104
105        options->sizeMaxPrefix = 1;
106        VERIFY_SIZE(1024, "1.00 KiB");
107        VERIFY_SIZE(1024ULL * 1024, "1024.00 KiB");
108        VERIFY_SIZE(1024ULL * 1024 * 1024, "1048576.00 KiB");
109
110        options->sizeMaxPrefix = 8;
111    }
112
113    // sizeSpaceBeforeUnit: only `never` removes the space, `default` and `always` both keep it
114    {
115        options->sizeSpaceBeforeUnit = FF_SPACE_BEFORE_UNIT_NEVER;
116        VERIFY_SIZE(0, "0B");
117        VERIFY_SIZE(1024, "1.00KiB");
118        VERIFY_SIZE(1536, "1.50KiB");
119
120        options->sizeSpaceBeforeUnit = FF_SPACE_BEFORE_UNIT_ALWAYS;
121        VERIFY_SIZE(0, "0 B");
122        VERIFY_SIZE(1024, "1.00 KiB");
123
124        options->sizeSpaceBeforeUnit = FF_SPACE_BEFORE_UNIT_DEFAULT;
125        VERIFY_SIZE(1024, "1.00 KiB");
126    }
127
128    // The result is appended to the buffer instead of replacing it
129    {
130        FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateS("Size: ");
131        ffSizeAppendNum(1024, &result);
132        if (!ffStrbufEqualS(&result, "Size: 1.00 KiB")) {
133            fprintf(stderr, FASTFETCH_TEXT_MODIFIER_ERROR "[%d] ffSizeAppendNum did not append: got \"%s\"\n" FASTFETCH_TEXT_MODIFIER_RESET, __LINE__, result.chars);
134            exit(1);
135        }
136    }
137
138    ffOptionsDestroyDisplay(options);
139
140    puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET);
141    return 0;
142}