summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2015-08-01 16:42:37 (GMT)
committer Michael Drake <tlsa@netsurf-browser.org>2015-08-03 21:30:20 (GMT)
commit8449bb0c102a0ff85e3dc8d4319fac531ea5374f (patch)
treefd86edde456e9534475e364264d9128379abcddb
parentba2cea6270dc014bf2751f373404fa915d2c38b6 (diff)
downloadlibnslayout-8449bb0c102a0ff85e3dc8d4319fac531ea5374f.tar.gz
libnslayout-8449bb0c102a0ff85e3dc8d4319fac531ea5374f.tar.bz2
Add simple development testing harness.
-rw-r--r--dev/main.c31
-rw-r--r--dev/test-writing-mode.html40
-rw-r--r--test/test-loader.c305
3 files changed, 376 insertions, 0 deletions
diff --git a/dev/main.c b/dev/main.c
new file mode 100644
index 0000000..ca87816
--- a/dev/null
+++ b/dev/main.c
@@ -0,0 +1,31 @@
+/*
+ * This file is part of LibNSLayout's tests
+ * Licensed under the ISC License, http://opensource.org/licenses/ISC
+ * Copyright 2015 Michael Drake <tlsa@netsurf-browser.org>
+ */
+
+#include "../test/test-loader.c"
+
+/*
+ * cd ../ && make && make install && cd dev/ && gcc `pkg-config libnslayout --cflags` main.c `pkg-config libnslayout --libs` && ./a.out ; cd ~/dev-netsurf/workspace/libnslayout/dev
+ */
+
+
+static void lwc_iterator(lwc_string *str, void *pw)
+{
+ printf("[%3u] %.*s", str->refcnt,
+ (int)lwc_string_length(str),
+ lwc_string_data(str));
+}
+
+int main(void)
+{
+ nslayout_init();
+ test_loader("test-writing-mode.html", CSS_MEDIA_ALL, 15);
+ nslayout_fini();
+
+ printf("Reamining lwc strings:\n");
+ lwc_iterate_strings(lwc_iterator, NULL);
+
+ return EXIT_SUCCESS;
+}
diff --git a/dev/test-writing-mode.html b/dev/test-writing-mode.html
new file mode 100644
index 0000000..96c811e
--- a/dev/null
+++ b/dev/test-writing-mode.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+html {
+ -ms-writing-mode: lr-tb;
+ -webkit-writing-mode: horizontal-tb;
+ -moz-writing-mode: horizontal-tb;
+ -ms-writing-mode: horizontal-tb;
+ writing-mode: horizontal-tb;
+}
+html:hover {
+ -ms-writing-mode: tb-rl;
+ -webkit-writing-mode: vertical-rl;
+ -moz-writing-mode: vertical-rl;
+ -ms-writing-mode: vertical-rl;
+ writing-mode: vertical-rl;
+}
+h1 {
+ background: #600;
+ color: #fff;
+ width: 50%;
+ margin: 0;
+ padding: 3px;
+ border-bottom: 2px solid black;
+}
+p {
+ margin: 0;
+ padding: 3px;
+ border: 1px solid green;
+ border-left-width: 1em;
+ margin-top: 3em;
+}
+</style>
+</head>
+<body>
+<h1>Test</h1>
+<p>Here's some text to test CSS3 writing modes <a href="https://drafts.csswg.org/css-writing-modes/#abstract-layout">abstract box layout</a>!</p>
+</body>
+</html>
diff --git a/test/test-loader.c b/test/test-loader.c
new file mode 100644
index 0000000..234561d
--- a/dev/null
+++ b/test/test-loader.c
@@ -0,0 +1,305 @@
+/*
+ * This file is part of LibNSLayout's tests
+ * Licensed under the ISC License, http://opensource.org/licenses/ISC
+ * Copyright 2015 Michael Drake <tlsa@netsurf-browser.org>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <dom/dom.h>
+#include <dom/bindings/hubbub/parser.h>
+#include <libcss/libcss.h>
+
+#include <libnslayout/nslayout.h>
+
+#ifndef UNUSED
+#define UNUSED(x) (void)(x)
+#endif
+
+static nslayout_error nslayout_test_callback(
+ nslayout_layout *layout,
+ void *pw,
+ nslayout_request *req)
+{
+ UNUSED(req);
+ UNUSED(layout);
+ UNUSED(pw);
+ return NSLAYOUT_OK;
+}
+
+struct doc_load_ctx {
+ dom_hubbub_parser *parser;
+ dom_document *doc;
+ unsigned char *buffer;
+ size_t buffer_size;
+ FILE *handle;
+ css_select_ctx *css_ctx;
+ css_stylesheet *css_sheet;
+};
+
+
+static bool doc_load_start(const char *file, size_t buffer_size,
+ struct doc_load_ctx *load_ctx)
+{
+ dom_hubbub_parser_params params;
+ dom_hubbub_error error;
+ size_t chunk_length;
+
+ params.enc = NULL;
+ params.fix_enc = true;
+ params.enable_script = false;
+ params.msg = NULL;
+ params.script = NULL;
+ params.ctx = NULL;
+ params.daf = NULL;
+
+ load_ctx->buffer = malloc(buffer_size);
+ if (load_ctx->buffer == NULL) {
+ return false;
+ }
+
+ load_ctx->buffer_size = buffer_size;
+
+ /* Create Hubbub parser */
+ error = dom_hubbub_parser_create(&params, &load_ctx->parser,
+ &load_ctx->doc);
+ if (error != DOM_HUBBUB_OK) {
+ free(load_ctx->buffer);
+ return false;
+ }
+
+ /* Open input file */
+ load_ctx->handle = fopen(file, "rb");
+ if (load_ctx->handle == NULL) {
+ dom_hubbub_parser_destroy(load_ctx->parser);
+ free(load_ctx->buffer);
+ return false;
+ }
+
+ /* Parse input file in chunks */
+ chunk_length = buffer_size;
+ chunk_length = fread(load_ctx->buffer, 1, load_ctx->buffer_size,
+ load_ctx->handle);
+ error = dom_hubbub_parser_parse_chunk(load_ctx->parser,
+ load_ctx->buffer, chunk_length);
+ if (error != DOM_HUBBUB_OK) {
+ dom_hubbub_parser_destroy(load_ctx->parser);
+ printf("Parsing errors occur\n");
+ return false;
+ }
+
+ return true;
+}
+
+
+static bool doc_load_next(struct doc_load_ctx *load_ctx, bool *complete)
+{
+ dom_hubbub_error error;
+ int chunk_length;
+
+ /* Parse input file in chunks */
+ chunk_length = fread(load_ctx->buffer, 1, load_ctx->buffer_size,
+ load_ctx->handle);
+ if (chunk_length != 0) {
+ error = dom_hubbub_parser_parse_chunk(load_ctx->parser,
+ load_ctx->buffer, chunk_length);
+ if (error != DOM_HUBBUB_OK) {
+ dom_hubbub_parser_destroy(load_ctx->parser);
+ printf("Parsing errors occur\n");
+ return false;
+ }
+ *complete = false;
+ return true;
+ }
+
+ *complete = true;
+
+ /* Done parsing file */
+ error = dom_hubbub_parser_completed(load_ctx->parser);
+ if (error != DOM_HUBBUB_OK) {
+ dom_hubbub_parser_destroy(load_ctx->parser);
+ printf("Parsing error when construct DOM\n");
+ return false;
+ }
+
+ /* Finished with parser */
+ dom_hubbub_parser_destroy(load_ctx->parser);
+
+ /* Close input file */
+ if (fclose(load_ctx->handle) != 0) {
+ printf("Can't close test input file\n");
+ return false;
+ }
+
+ return true;
+}
+
+
+static css_error resolve_url(void *pw, const char *base,
+ lwc_string *rel, lwc_string **abs)
+{
+ UNUSED(pw);
+ UNUSED(base);
+
+ /* No join implementation; just copy rel to abs for now. */
+ *abs = lwc_string_ref(rel);
+
+ return CSS_OK;
+}
+
+
+static bool test_loader_css_fini(struct doc_load_ctx *load_ctx)
+{
+ css_error css_err = CSS_OK;
+
+ if (load_ctx->css_ctx != NULL) {
+ css_err = css_select_ctx_destroy(load_ctx->css_ctx);
+ if (css_err != CSS_OK) {
+ printf("ERROR: css_select_ctx_destroy\n");
+ }
+ }
+ if (load_ctx->css_sheet != NULL) {
+ css_err = css_stylesheet_destroy(load_ctx->css_sheet);
+ if (css_err != CSS_OK) {
+ printf("ERROR: css_stylesheet_destroy\n");
+ }
+ }
+
+ return (css_err == CSS_OK);
+}
+
+
+static bool test_loader_css_init(struct doc_load_ctx *load_ctx)
+{
+ css_error css_err;
+ css_stylesheet_params params;
+ const char *ua_style =
+ "div, p, h1, h2, h3, h4, h5 {display:block}";
+
+ params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
+ params.level = CSS_LEVEL_21;
+ params.charset = "UTF-8";
+ params.url = "foo";
+ params.title = "foo";
+ params.allow_quirks = false;
+ params.inline_style = false;
+ params.resolve = resolve_url;
+ params.resolve_pw = NULL;
+ params.import = NULL;
+ params.import_pw = NULL;
+ params.color = NULL;
+ params.color_pw = NULL;
+ params.font = NULL;
+ params.font_pw = NULL;
+
+ /* create a stylesheet */
+ css_err = css_stylesheet_create(&params, &load_ctx->css_sheet);
+ if (css_err != CSS_OK) {
+ printf("ERROR: css_stylesheet_create\n");
+ goto fail;
+ }
+
+ css_err = css_stylesheet_append_data(load_ctx->css_sheet,
+ (const uint8_t *) ua_style, sizeof ua_style);
+ if (css_err != CSS_OK && css_err != CSS_NEEDDATA) {
+ printf("ERROR: css_stylesheet_append_data\n");
+ goto fail;
+ }
+ css_err = css_stylesheet_data_done(load_ctx->css_sheet);
+ if (css_err != CSS_OK) {
+ printf("ERROR: css_stylesheet_data_done\n");
+ goto fail;
+ }
+
+ /* Create a selection context (with no sheets added) */
+ css_err = css_select_ctx_create(&load_ctx->css_ctx);
+ if (css_err != CSS_OK) {
+ printf("ERROR: css_select_ctx_create\n");
+ goto fail;
+ }
+
+ css_err = css_select_ctx_append_sheet(load_ctx->css_ctx,
+ load_ctx->css_sheet, CSS_ORIGIN_UA, CSS_MEDIA_ALL);
+ if (css_err != CSS_OK) {
+ printf("ERROR: css_select_ctx_append_sheet\n");
+ goto fail;
+ }
+
+ return true;
+
+fail:
+ test_loader_css_fini(load_ctx);
+
+ return false;
+}
+
+
+static bool test_loader(const char *document_path,
+ css_media_type media,
+ size_t chunk_size)
+{
+ nslayout_layout *layout = NULL;
+ nslayout_error error;
+ struct doc_load_ctx load_ctx;
+ bool complete = false;
+ bool ret = false;
+
+ printf("Test loader\n");
+
+ load_ctx.parser = NULL;
+ load_ctx.doc = NULL;
+ load_ctx.buffer = NULL;
+ load_ctx.buffer_size = 0;
+ load_ctx.handle = NULL;
+ load_ctx.css_sheet = NULL;
+ load_ctx.css_ctx = NULL;
+
+ printf("Starting load\n");
+ if (!doc_load_start(document_path, chunk_size, &load_ctx)) {
+ printf("ERROR: doc_load_start\n");
+ goto fail;
+ }
+
+ printf("Creating style context\n");
+ if (!test_loader_css_init(&load_ctx)) {
+ printf("ERROR: create_style_context\n");
+ goto fail;
+ }
+
+ printf("Creating nsl layout\n");
+ error = nslayout_layout_create(load_ctx.doc,
+ load_ctx.css_ctx,
+ &media,
+ nslayout_test_callback,
+ NULL,
+ &layout);
+ if (error != NSLAYOUT_OK) {
+ goto fail;
+ }
+
+ while (!complete) {
+ printf("Loading a chunk of the document\n");
+ if (!doc_load_next(&load_ctx, &complete)) {
+ printf("ERROR: doc_load_next\n");
+ goto fail;
+ }
+ }
+
+ printf("Destroying layout\n");
+ error = nslayout_layout_destroy(layout);
+ layout = NULL;
+
+ ret = (error == NSLAYOUT_OK);
+fail:
+ if (layout != NULL) {
+ nslayout_layout_destroy(layout);
+ }
+ test_loader_css_fini(&load_ctx);
+ dom_node_unref(load_ctx.doc);
+ free(load_ctx.buffer);
+
+ return ret;
+}
+