Tests and fixes for url_encode
This commit is contained in:
7
Makefile
7
Makefile
@@ -49,5 +49,12 @@ output/noh.o: src/noh.h | output
|
||||
|
||||
################################################################################
|
||||
|
||||
test: output/test
|
||||
output/test: test/test_path.c $(SHARED_LIB_FILES) | output
|
||||
gcc $(CFLAGS) -I./src -o output/test test/test_path.c $(SHARED_LIBS)
|
||||
|
||||
################################################################################
|
||||
|
||||
output:
|
||||
mkdir -p output
|
||||
|
||||
|
||||
6
build.sh
6
build.sh
@@ -14,6 +14,12 @@ elif [ $1 = "run" ]; then
|
||||
make server
|
||||
./output/server 5000 ./library "Testing library"
|
||||
|
||||
elif [ $1 = "test" ]; then
|
||||
echo "Running tests"
|
||||
|
||||
make test
|
||||
./output/test
|
||||
|
||||
elif [ $1 = "debug" ]; then
|
||||
echo "Debugging"
|
||||
|
||||
|
||||
23
src/noh.h
23
src/noh.h
@@ -156,9 +156,21 @@ typedef enum {
|
||||
NOH_ERROR,
|
||||
} Noh_Log_Level;
|
||||
|
||||
// Options that can alter the behavior of noh_log.
|
||||
typedef struct {
|
||||
// Whether to write a line feed at the end of a log message. Default is true.
|
||||
bool write_lf;
|
||||
|
||||
// Whether to write a line feed at the end of a log message. Default is true.
|
||||
bool write_prefix;
|
||||
} Noh_Log_Options;
|
||||
|
||||
// Writes a formatted log message to stderr with the provided log level.
|
||||
void noh_log(Noh_Log_Level level, const char *fmt, ...);
|
||||
|
||||
// Returns a pointer to the noh_log options.
|
||||
Noh_Log_Options *noh_log_get_opts();
|
||||
|
||||
///////////////////////// Dynamic array /////////////////////////
|
||||
|
||||
#define NOH_DA_INIT_CAP 256
|
||||
@@ -609,8 +621,16 @@ void noh_time_add(struct timespec *time, int seconds, long milliseconds) {
|
||||
|
||||
///////////////////////// Logging /////////////////////////
|
||||
|
||||
Noh_Log_Options *noh_log_get_opts() {
|
||||
static Noh_Log_Options opts = { .write_lf = true, .write_prefix = true, };
|
||||
return &opts;
|
||||
}
|
||||
|
||||
void noh_log(Noh_Log_Level level, const char *fmt, ...)
|
||||
{
|
||||
Noh_Log_Options *opts = noh_log_get_opts();
|
||||
|
||||
if (opts->write_prefix) {
|
||||
switch (level) {
|
||||
case NOH_INFO:
|
||||
fprintf(stderr, "[INFO] ");
|
||||
@@ -624,12 +644,13 @@ void noh_log(Noh_Log_Level level, const char *fmt, ...)
|
||||
default:
|
||||
noh_assert(false && "Invalid log level");
|
||||
}
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, "\n");
|
||||
if (opts->write_lf) fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
///////////////////////// Arena /////////////////////////
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
static inline bool byte_is_url_safe(char c) {
|
||||
return (c >= 'A' && c <= 'Z')
|
||||
|| (c >= 'a' && c <= 'z')
|
||||
|| (c >= '0' && c <+ '9')
|
||||
|| (c >= '0' && c <= '9')
|
||||
|| (c >= '(' && c <= '*')
|
||||
|| c == '!' || c == '-'
|
||||
|| c == '.' || c == '_';
|
||||
@@ -15,12 +15,12 @@ static bool needs_encoding(Noh_String string, int *unsafe_count) {
|
||||
*unsafe_count = 0;
|
||||
bool safe = true ;
|
||||
for (size_t i = 0; i < string.count; i++) {
|
||||
bool needs_encode = byte_is_url_safe(string.elems[i]);
|
||||
bool needs_encode = !byte_is_url_safe(string.elems[i]);
|
||||
if (needs_encode || string.elems[i] == ' ') safe = false;
|
||||
if (needs_encode) (*unsafe_count)++;
|
||||
}
|
||||
|
||||
return safe;
|
||||
return !safe;
|
||||
}
|
||||
|
||||
static inline char to_char_lower(int value) {
|
||||
@@ -55,6 +55,8 @@ void url_encode(Noh_String *string) {
|
||||
noh_da_append(&result, '%');
|
||||
noh_da_append(&result, to_char_lower(cur >> 4));
|
||||
noh_da_append(&result, to_char_lower(cur));
|
||||
} else {
|
||||
noh_da_append(&result, cur);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
52
test/test_path.c
Normal file
52
test/test_path.c
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "path.h"
|
||||
#include "noh.h"
|
||||
|
||||
void check_string(size_t *good, size_t *bad, const char* input, const char *expected) {
|
||||
Noh_String test = noh_string_from_cstr(input);
|
||||
Noh_String_View expected_sv = noh_sv_from_cstr(expected);
|
||||
|
||||
Noh_Log_Options *opts = noh_log_get_opts();
|
||||
|
||||
opts->write_lf = false;
|
||||
noh_log(NOH_INFO, "Testing: \"%s\"...", input);
|
||||
opts->write_lf = true;
|
||||
opts->write_prefix = false;
|
||||
|
||||
url_encode(&test);
|
||||
bool correct = noh_sv_eq(noh_sv_from_string(test), expected_sv);
|
||||
|
||||
if (!correct) {
|
||||
noh_log(NOH_ERROR, " Incorrect.");
|
||||
opts->write_prefix = true;
|
||||
noh_log(NOH_ERROR, "Expected: "Nsv_Fmt, Nsv_Arg(expected_sv));
|
||||
noh_log(NOH_ERROR, "Got : "Nsv_Fmt, Nsv_Arg(test));
|
||||
(*bad)++;
|
||||
} else {
|
||||
noh_log(NOH_INFO, " Ok.");
|
||||
opts->write_prefix = true;
|
||||
(*good)++;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
size_t good = 0;
|
||||
size_t bad = 0;
|
||||
|
||||
check_string(&good, &bad,
|
||||
"abcdefghijklmnopqrstuvwxyz1023456789ABCDEFGHIJKLMNOPQRSTUVWXYZ()*!-._",
|
||||
"abcdefghijklmnopqrstuvwxyz1023456789ABCDEFGHIJKLMNOPQRSTUVWXYZ()*!-._");
|
||||
|
||||
check_string(&good, &bad,
|
||||
"~!@#$%^&*()_+-=",
|
||||
"%7e!%40%23%24%25%5e%26*()_%2b-%3d");
|
||||
|
||||
if (bad == 0) {
|
||||
noh_log(NOH_INFO, "%zu/%zu tests passed.", good, good);
|
||||
return 0;
|
||||
} else {
|
||||
noh_log(NOH_ERROR, "%zu/%zu tests passed. %zu failures.", good, good + bad, bad);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user