1
0
Fork 0
mirror of https://github.com/tailix/libkernaux.git synced 2025-03-31 17:25:22 -04:00

Common: generate original tests for printf

This commit is contained in:
Alex Kotov 2022-05-24 14:14:12 +03:00
parent 880fdd0ba7
commit 74128be3ff
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
6 changed files with 173 additions and 9 deletions

2
.gitignore vendored
View file

@ -118,4 +118,6 @@
/tests/test_pfa
/tests/test_pfa_assert
/tests/test_printf
/tests/test_printf_gen
/tests/test_printf_gen.c
/tests/test_units_human

View file

@ -16,6 +16,9 @@ libkernaux_a_SOURCES = \
src/assert.c \
src/libc.c
CLEANFILES = \
tests/test_printf_gen.c
if ASM_I386
libkernaux_a_SOURCES += src/asm/i386.S
endif
@ -128,6 +131,12 @@ TESTS += \
examples/snprintf \
examples/snprintf_va \
tests/test_printf
if ENABLE_TESTS_PYTHON
TESTS += tests/test_printf_gen
noinst_SCRIPTS = tests/printf_gen.py
noinst_DATA = \
tests/printf_orig.yml
endif
endif
endif
@ -264,6 +273,13 @@ tests_test_printf_SOURCES = \
$(libkernaux_a_SOURCES) \
tests/test_printf.c
tests_test_printf_gen_SOURCES = \
$(libkernaux_a_SOURCES) \
tests/test_printf_gen.c
tests_test_units_human_SOURCES = \
$(libkernaux_a_SOURCES) \
tests/test_units_human.c
tests/test_printf_gen.c: tests/printf_gen.py tests/printf_orig.yml
python3 tests/printf_gen.py

View file

@ -11,11 +11,25 @@ RSpec.describe KernAux, '.sprintf' do
it { is_expected.to eq 'Hello, World!' }
context 'using original tests' do
printf_yml = File.expand_path('../../../../../tests/printf.yml', __dir__)
printf_yml =
File.expand_path('../../../../../tests/printf_orig.yml', __dir__)
YAML.safe_load_file(printf_yml).each do |test|
expected = test['result']
args = test['args']
args = test['args'].map do |arg|
if arg.is_a? String
arg
else
arg.map do |item|
if item.is_a? Array
item[0]
else
item
end
end
end
end
it "transforms #{args.inspect} to #{expected.inspect}" do
expect(described_class.sprintf(*args)).to eq expected

63
tests/printf_gen.jinja Normal file
View file

@ -0,0 +1,63 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <kernaux/printf.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 1024
static const char *const data = "foobar";
static char buffer[BUFFER_SIZE];
static size_t buffer_index;
static void test_putchar(const char chr, void *const arg)
{
assert(arg == data);
if (buffer_index >= BUFFER_SIZE) {
printf("Buffer overflow!\n");
abort();
}
buffer[buffer_index++] = chr;
}
static void test(const char *const expected, const char *const format, ...)
{
va_list va;
int result;
memset(buffer, '\0', sizeof(buffer));
buffer_index = 0;
va_start(va, format);
result = kernaux_vprintf(test_putchar, (char*)data, format, va);
va_end(va);
assert((size_t)result == strlen(expected));
assert(strcmp(expected, buffer) == 0);
memset(buffer, '\0', sizeof(buffer));
buffer_index = 0;
va_start(va, format);
result = kernaux_vsnprintf(buffer, sizeof(buffer), format, va);
va_end(va);
assert((size_t)result == strlen(expected));
assert(strcmp(expected, buffer) == 0);
}
int main()
{
{% for case in cases %}
{% if not case.fixme %}
printf("%s\n", {{ escape_str(case.result) }});
test({{ escape_str(case.result) }}, {{ escape_str(fmt(case.args)) }}{{ values(case.args) }});
{% endif %}
{% endfor %}
return 0;
}

68
tests/printf_gen.py Normal file
View file

@ -0,0 +1,68 @@
from jinja2 import Environment, FileSystemLoader
from os import path
from yaml import SafeLoader, safe_load
CASES_ORIG_FILENAME = 'printf_orig.yml'
TEMPLATE_FILENAME = 'printf_gen.jinja'
TEST_FILENAME = 'test_printf_gen.c'
TESTS_DIRPATH = path.dirname(path.abspath(__file__))
CASES_ORIG_FILEPATH = path.join(TESTS_DIRPATH, CASES_ORIG_FILENAME)
TEST_FILEPATH = path.join(TESTS_DIRPATH, TEST_FILENAME)
def main():
cases_orig = safe_load(open(CASES_ORIG_FILEPATH))
cases = cases_orig
jinja_env = Environment(
keep_trailing_newline=True,
loader=FileSystemLoader(TESTS_DIRPATH),
)
jinja_template = jinja_env.get_template(TEMPLATE_FILENAME)
result = jinja_template.render(
cases=cases,
escape_str=escape_str,
fmt=fmt,
values=values,
)
with open(TEST_FILEPATH, 'w') as f:
f.write(result)
def escape_char(c):
return "'" + c + "'"
def escape_str(s):
return '"' + s + '"'
def fmt(args):
fmt = ''
for arg in args:
if type(arg) is list:
fmt += arg[0]
else:
fmt += arg
return fmt
def values(args):
values = ''
for arg in args:
if type(arg) is list and len(arg) >= 2:
if len(arg) >= 3:
values += ', ' + str(arg[1])
arg[1] = arg[2]
if type(arg[1]) is str:
values += ', ' + escape_str(arg[1])
elif type(arg[1]) is list:
values += ', ' + escape_char(arg[1][0])
else:
values += ', ' + str(arg[1])
return values
if __name__ == '__main__':
main()

View file

@ -67,7 +67,7 @@
- result: 'EDCB5433'
args: [['% X', 3_989_525_555]]
- result: 'x'
args: [['% c', 'x']]
args: [['% c', ['x']]]
# + flag
@ -110,7 +110,7 @@
- result: 'EDCB5433'
args: [['%+X', 3_989_525_555]]
- result: 'x'
args: [['%+c', 'x']]
args: [['%+c', ['x']]]
- result: '+'
args: [['%+.0d', 0]]
@ -199,6 +199,7 @@
args: ['Hello testing']
- result: 'Hello testing'
args: [['Hello testing%s']]
fixme: true
- result: 'Hello testing'
args: [['Hello testing%s', '']]
- result: 'Hello testing'
@ -259,7 +260,7 @@
- result: 'EDCB5433'
args: [['%1X', 3_989_525_555]]
- result: 'x'
args: [['%1c', 'x']]
args: [['%1c', ['x']]]
# width 20
@ -290,7 +291,7 @@
- result: ' EDCB5433'
args: [['%20X', 3_989_525_555]]
- result: ' x'
args: [['%20c', 'x']]
args: [['%20c', ['x']]]
# width *20
@ -321,7 +322,7 @@
- result: ' EDCB5433'
args: [['%*X', 20, 3_989_525_555]]
- result: ' x'
args: [['%*c', 20, 'x']]
args: [['%*c', 20, ['x']]]
# width -20
@ -354,7 +355,7 @@
- result: 'EDCB5433 '
args: [['%-20X', 3_989_525_555]]
- result: 'x '
args: [['%-20c', 'x']]
args: [['%-20c', ['x']]]
- result: '| 9| |9 | | 9|'
args: [['|%5d| ', 9], ['|%-2d|', 9], [' |%5d|', 9]]
- result: '| 10| |10| | 10|'
@ -393,7 +394,7 @@
- result: 'EDCB5433 '
args: [['%0-20X', 3_989_525_555]]
- result: 'x '
args: [['%0-20c', 'x']]
args: [['%0-20c', ['x']]]
# padding 20