diff options
-rw-r--r-- | .gitlab-ci.yml | 91 | ||||
-rw-r--r-- | .gitlab-ci/README.md | 38 | ||||
-rw-r--r-- | .gitlab-ci/fedora.Dockerfile | 49 | ||||
-rwxr-xr-x | .gitlab-ci/meson-junit-report.py | 112 | ||||
-rwxr-xr-x | .gitlab-ci/run-docker.sh | 135 | ||||
-rwxr-xr-x | .gitlab-ci/run-tests.sh | 29 | ||||
-rw-r--r-- | docs/meson.build | 5 | ||||
-rw-r--r-- | meson.build | 1 | ||||
-rw-r--r-- | tests/markup-parse.c | 10 | ||||
-rw-r--r-- | tests/meson.build | 16 | ||||
-rw-r--r-- | tests/test-break.c | 21 | ||||
-rw-r--r-- | tests/test-font.c | 34 | ||||
-rw-r--r-- | tests/test-itemize.c | 20 | ||||
-rw-r--r-- | tests/test-layout.c | 13 | ||||
-rw-r--r-- | tests/test-pangocairo-threads.c | 38 | ||||
-rw-r--r-- | tests/test-shape.c | 3 | ||||
-rw-r--r-- | tests/testboundaries.c | 111 | ||||
-rw-r--r-- | tests/testboundaries_ucd.c | 80 | ||||
-rw-r--r-- | tests/testscript.c | 40 |
19 files changed, 576 insertions, 270 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d7a8e629..ee379f24 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,44 +1,35 @@ -image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/base:latest - stages: - build + - docs + - deploy -#gnome-runtime-linux: -# stage: build -# before_script: -# - > -# dnf install -y \ -# glibc-langpack-en \ -# gcc \ -# gcc-c++ \ -# meson \ -# redhat-rpm-config \ -# glib2-devel \ -# harfbuzz-devel \ -# fribidi-devel \ -# cairo-devel \ -# libthai-devel \ -# gobject-introspection-devel \ -# cairo-gobject-devel \ -# abattis-cantarell-fonts \ -# google-droid-sans-fonts \ -# thai-scalable-waree-fonts \ -# desktop-file-utils \ -# diffutils -# script: -# - meson _build -# - ninja -C _build -# - meson test -C_build --suite pango -# - _build/utils/pango-list --verbose > _build/fontlist.txt -# - _build/tests/test-font -p /pango/font/metrics --verbose -# - _build/utils/pango-view --no-display --output _build/hello.png utils/HELLO.txt -# artifacts: -# name: "%CI_JOB_NAME%-%CI_COMMIT_REF_NAME%" -# when: always -# paths: -# - _build/meson-logs -# - _build/hello.png -# - _build/fontlist.txt +# Common variables +variables: + COMMON_MESON_FLAGS: "--fatal-meson-warnings --werror" + MESON_TEST_TIMEOUT_MULTIPLIER: 2 + +linux-fedora: + image: registry.gitlab.gnome.org/gnome/pango/fedora:v1 + stage: build + variables: + EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both" + script: + - meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} + _build + - meson _build + - ninja -C _build + - .gitlab-ci/run-tests.sh _build + artifacts: + when: always + reports: + junit: + - "${CI_PROJECT_DIR}/_build/report.xml" + name: "gtk-${CI_COMMIT_REF_NAME}" + paths: + - "${CI_PROJECT_DIR}/_build/meson-logs" + - "${CI_PROJECT_DIR}/_build/report.xml" + - "${CI_PROJECT_DIR}/_build/hello.png" + - "${CI_PROJECT_DIR}/_build/fontlist.txt" msys2-mingw64: stage: build @@ -59,3 +50,27 @@ msys2-mingw64: - _build/meson-logs - _build/hello.png - _build/fontlist.txt + +reference: + image: registry.gitlab.gnome.org/gnome/pango/fedora:v1 + stage: docs + variables: + EXTRA_MESON_FLAGS: "" + script: + - meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} -Dgtk_doc=true _build + - ninja -C _build pango-doc + - mkdir -p _reference/ + - mv _build/docs/html/ _reference/ + artifacts: + paths: + - _reference + +pages: + stage: deploy + script: + - mv _reference/ public/ + artifacts: + paths: + - public + only: + - master diff --git a/.gitlab-ci/README.md b/.gitlab-ci/README.md new file mode 100644 index 00000000..a5c7736d --- /dev/null +++ b/.gitlab-ci/README.md @@ -0,0 +1,38 @@ +## Pango CI infrastructure + +Pango uses different CI images depending on platform and jobs. + +The CI images are Docker containers, generated either using `docker` or +`podman`, and pushed to the GitLab [container registry][registry]. + +Each Docker image has a tag composed of two parts: + + - `${image}`: the base image for a given platform, like "fedora" or + "debian-stable" + - `${number}`: an incremental version number, or `latest` + +See the [container registry][registry] for the available images for each +branch, as well as their available versions. + +### Checklist for Updating a CI image + + - [ ] Update the `${image}.Dockerfile` file with the dependencies + - [ ] Run `./run-docker.sh build --base ${image} --base-version ${number}` + - [ ] Run `./run-docker.sh push --base ${image} --base-version ${number}` + once the Docker image is built; you may need to log in by using + `docker login` or `podman login` + - [ ] Update the `image` keys in the `.gitlab-ci.yml` file with the new + image tag + - [ ] Open a merge request with your changes and let it run + +### Checklist for Adding a new CI image + + - [ ] Write a new `${image}.Dockerfile` with the instructions to set up + a build environment + - [ ] Add the `pip3 install meson` incantation + - [ ] Run `./run-docker.sh build --base ${image} --base-version ${number}` + - [ ] Run `./run-docker.sh push --base ${image} --base-version ${number}` + - [ ] Add the new job to `.gitlab-ci.yml` referencing the image + - [ ] Open a merge request with your changes and let it run + +[registry]: https://gitlab.gnome.org/GNOME/pango/container_registry diff --git a/.gitlab-ci/fedora.Dockerfile b/.gitlab-ci/fedora.Dockerfile new file mode 100644 index 00000000..c1aadc93 --- /dev/null +++ b/.gitlab-ci/fedora.Dockerfile @@ -0,0 +1,49 @@ +FROM fedora:31 + +RUN dnf -y install \ + abattis-cantarell-fonts \ + cairo-devel \ + cairo-gobject-devel \ + ccache \ + clang \ + clang-analyzer \ + desktop-file-utils \ + diffutils \ + fribidi-devel \ + gcc \ + gcc-c++ \ + gettext \ + git \ + glib2-devel \ + glib2-static \ + glibc-devel \ + glibc-headers \ + glibc-langpack-en \ + gobject-introspection-devel \ + google-droid-sans-fonts \ + gtk-doc \ + harfbuzz-devel \ + hicolor-icon-theme \ + itstool \ + lcov \ + libthai-devel \ + ninja-build \ + python3 \ + python3-jinja2 \ + python3-pip \ + python3-pygments \ + python3-wheel \ + redhat-rpm-config \ + thai-scalable-waree-fonts \ + && dnf clean all + +RUN pip3 install meson==0.53.1 + +ARG HOST_USER_ID=5555 +ENV HOST_USER_ID ${HOST_USER_ID} +RUN useradd -u $HOST_USER_ID -ms /bin/bash user + +USER user +WORKDIR /home/user + +ENV LANG C.UTF-8 diff --git a/.gitlab-ci/meson-junit-report.py b/.gitlab-ci/meson-junit-report.py new file mode 100755 index 00000000..fc96efba --- /dev/null +++ b/.gitlab-ci/meson-junit-report.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 + +# Turns a Meson testlog.json file into a JUnit XML report +# +# Copyright 2019 GNOME Foundation +# +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# Original author: Emmanuele Bassi + +import argparse +import datetime +import json +import os +import sys +import xml.etree.ElementTree as ET + +aparser = argparse.ArgumentParser(description='Turns a Meson test log into a JUnit report') +aparser.add_argument('--project-name', metavar='NAME', + help='The project name', + default='unknown') +aparser.add_argument('--job-id', metavar='ID', + help='The job ID for the report', + default='Unknown') +aparser.add_argument('--branch', metavar='NAME', + help='Branch of the project being tested', + default='master') +aparser.add_argument('--output', metavar='FILE', + help='The output file, stdout by default', + type=argparse.FileType('w', encoding='UTF-8'), + default=sys.stdout) +aparser.add_argument('infile', metavar='FILE', + help='The input testlog.json, stdin by default', + type=argparse.FileType('r', encoding='UTF-8'), + default=sys.stdin) + +args = aparser.parse_args() + +outfile = args.output + +testsuites = ET.Element('testsuites') +testsuites.set('id', '{}/{}'.format(args.job_id, args.branch)) +testsuites.set('package', args.project_name) +testsuites.set('timestamp', datetime.datetime.utcnow().isoformat(timespec='minutes')) + +suites = {} +for line in args.infile: + data = json.loads(line) + unit_name = data['name'] + suite_name = args.project_name + project_name = args.project_name + + duration = data['duration'] + return_code = data['returncode'] + result = data['result'] + log = data['stdout'] + + unit = { + 'suite': suite_name, + 'name': unit_name, + 'duration': duration, + 'returncode': return_code, + 'result': result, + 'stdout': log, + } + + units = suites.setdefault(suite_name, []) + units.append(unit) + +for name, units in suites.items(): + print('Processing suite {} (units: {})'.format(name, len(units))) + + def if_failed(unit): + if unit['result'] in ['FAIL', 'UNEXPECTEDPASS', 'TIMEOUT']: + return True + return False + + def if_succeded(unit): + if unit['result'] in ['OK', 'EXPECTEDFAIL', 'SKIP']: + return True + return False + + successes = list(filter(if_succeded, units)) + failures = list(filter(if_failed, units)) + print(' - {}: {} pass, {} fail'.format(name, len(successes), len(failures))) + + testsuite = ET.SubElement(testsuites, 'testsuite') + testsuite.set('name', '{}/{}'.format(args.project_name, name)) + testsuite.set('tests', str(len(units))) + testsuite.set('errors', str(len(failures))) + testsuite.set('failures', str(len(failures))) + + for unit in successes: + testcase = ET.SubElement(testsuite, 'testcase') + testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite'])) + testcase.set('name', unit['name']) + testcase.set('time', str(unit['duration'])) + + for unit in failures: + testcase = ET.SubElement(testsuite, 'testcase') + testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite'])) + testcase.set('name', unit['name']) + testcase.set('time', str(unit['duration'])) + + failure = ET.SubElement(testcase, 'failure') + failure.set('classname', '{}/{}'.format(args.project_name, unit['suite'])) + failure.set('name', unit['name']) + failure.set('type', 'error') + failure.text = unit['stdout'] + +output = ET.tostring(testsuites, encoding='unicode') +outfile.write(output) diff --git a/.gitlab-ci/run-docker.sh b/.gitlab-ci/run-docker.sh new file mode 100755 index 00000000..06c4f63d --- /dev/null +++ b/.gitlab-ci/run-docker.sh @@ -0,0 +1,135 @@ +#!/bin/bash + +read_arg() { + # $1 = arg name + # $2 = arg value + # $3 = arg parameter + local rematch='^[^=]*=(.*)$' + if [[ $2 =~ $rematch ]]; then + read "$1" <<< "${BASH_REMATCH[1]}" + else + read "$1" <<< "$3" + # There is no way to shift our callers args, so + # return 1 to indicate they should do it instead. + return 1 + fi +} + +set -e + +build=0 +run=0 +push=0 +list=0 +print_help=0 +no_login=0 + +while (($# > 0)); do + case "${1%%=*}" in + build) build=1;; + run) run=1;; + push) push=1;; + list) list=1;; + help) print_help=1;; + --base|-b) read_arg base "$@" || shift;; + --base-version) read_arg base_version "$@" || shift;; + --no-login) no_login=1;; + *) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;; + esac + shift +done + +if [ $print_help == 1 ]; then + echo "$0 - Build and run Docker images" + echo "" + echo "Usage: $0 <command> [options] [basename]" + echo "" + echo "Available commands" + echo "" + echo " build --base=<BASENAME> - Build Docker image <BASENAME>.Dockerfile" + echo " run --base=<BASENAME> - Run Docker image <BASENAME>" + echo " push --base=<BASENAME> - Push Docker image <BASENAME> to the registry" + echo " list - List available images" + echo " help - This help message" + echo "" + exit 0 +fi + +cd "$(dirname "$0")" + +if [ $list == 1 ]; then + echo "Available Docker images:" + for f in *.Dockerfile; do + filename=$( basename -- "$f" ) + basename="${filename%.*}" + + echo -e " \e[1;39m$basename\e[0m" + done + exit 0 +fi + +# All commands after this require --base to be set +if [ -z $base ]; then + echo "Usage: $0 <command>" + exit 1 +fi + +if [ ! -f "$base.Dockerfile" ]; then + echo -e "\e[1;31mERROR\e[0m: Dockerfile for '$base' not found" + exit 1 +fi + +if [ -z $base_version ]; then + base_version="latest" +else + base_version="v$base_version" +fi + +if [ ! -x "$(command -v docker)" ] || [ docker --help |& grep -q podman ]; then + # Docker is actually implemented by podman, and its OCI output + # is incompatible with some of the dockerd instances on GitLab + # CI runners. + echo "Using: Podman" + format="--format docker" + CMD="podman" +else + echo "Using: Docker" + format="" + CMD="sudo socker" +fi + +REGISTRY="registry.gitlab.gnome.org" +TAG="${REGISTRY}/gnome/pango/${base}:${base_version}" + +if [ $build == 1 ]; then + echo -e "\e[1;32mBUILDING\e[0m: ${base} as ${TAG}" + ${CMD} build \ + ${format} \ + --build-arg HOST_USER_ID="$UID" \ + --tag "${TAG}" \ + --file "${base}.Dockerfile" . + exit $? +fi + +if [ $push == 1 ]; then + echo -e "\e[1;32mPUSHING\e[0m: ${base} as ${TAG}" + + if [ $no_login == 0 ]; then + ${CMD} login ${REGISTRY} + fi + + ${CMD} push ${TAG} + exit $? +fi + +if [ $run == 1 ]; then + echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}" + ${CMD} run \ + --rm \ + --volume "$(pwd)/..:/home/user/app" \ + --workdir "/home/user/app" \ + --tty \ + --interactive "${TAG}" \ + bash + exit $? +fi diff --git a/.gitlab-ci/run-tests.sh b/.gitlab-ci/run-tests.sh new file mode 100755 index 00000000..cca589b4 --- /dev/null +++ b/.gitlab-ci/run-tests.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set +x +set +e + +srcdir=$( pwd ) +builddir=$1 + +meson test -C ${builddir} \ + --print-errorlogs \ + --suite=pango + +# Store the exit code for the CI run, but always +# generate the reports +exit_code=$? + +cd ${builddir} + +./utils/pango-list --verbose > fontlist.txt +./tests/test-font -p /pango/font/metrics --verbose +./utils/pango-view --no-display --output hello.png ${srcdir}/utils/HELLO.txt + +$srcdir/.gitlab-ci/meson-junit-report.py \ + --project-name=pango \ + --job-id="${CI_JOB_NAME}" \ + --output=report.xml \ + meson-logs/testlog.json + +exit $exit_code diff --git a/docs/meson.build b/docs/meson.build index a99448af..e847a34f 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -55,7 +55,7 @@ if build_pangoft2 docdeps += libpangoft2_dep endif -if xft_dep.found() +if xft_dep.found() and fontconfig_dep.found() docdeps += libpangoxft_dep endif @@ -72,8 +72,7 @@ docpath = join_paths(pango_datadir, 'gtk-doc', 'html') gnome.gtkdoc('pango', main_xml: 'pango-docs.sgml', src_dir: [ - join_paths(meson.source_root(), 'pango'), - join_paths(meson.build_root(), 'pango'), + pango_inc, ], dependencies: docdeps, gobject_typesfile: configure_file(input: 'pango.types.in', diff --git a/meson.build b/meson.build index e8cb1cef..a0d2ecc4 100644 --- a/meson.build +++ b/meson.build @@ -541,6 +541,7 @@ pkgconfig = import('pkgconfig') configure_file(output: 'config.h', configuration: pango_conf) root_inc = include_directories('.') +pango_inc = include_directories('pango') subdir('pango') subdir('utils') diff --git a/tests/markup-parse.c b/tests/markup-parse.c index dff0ccc4..5f1454a1 100644 --- a/tests/markup-parse.c +++ b/tests/markup-parse.c @@ -48,12 +48,8 @@ test_file (const gchar *filename, GString *string) char *str; int start, end; - if (!g_file_get_contents (filename, &contents, &length, &error)) - { - fprintf (stderr, "%s\n", error->message); - g_error_free (error); - return; - } + g_file_get_contents (filename, &contents, &length, &error); + g_assert_no_error (error); ret = pango_parse_markup (contents, length, 0, &attrs, &text, NULL, &error); g_free (contents); @@ -152,7 +148,7 @@ main (int argc, char *argv[]) string = g_string_sized_new (0); test_file (argv[1], string); - g_print ("%s", string->str); + g_test_message ("%s", string->str); return 0; } diff --git a/tests/meson.build b/tests/meson.build index 4ffffa4c..9b78fbfd 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -10,11 +10,10 @@ if host_system == 'windows' test_cflags += '-DHAVE_WIN32' endif -test_env = [ - 'srcdir=@0@'.format(meson.current_source_dir()), - 'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()), - 'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()), -] +test_env = environment() +test_env.set('srcdir', meson.current_source_dir()) +test_env.set('G_TEST_SRCDIR', meson.current_source_dir()) +test_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) tests = [ [ 'test-coverage' ], @@ -177,5 +176,10 @@ foreach t: tests install: get_option('install-tests'), install_dir: installed_test_bindir) - test(name, bin, env: test_env) + test(name, bin, + args: ['-k', '--tap'], + env: test_env, + suite: 'pango', + protocol: 'tap', + ) endforeach diff --git a/tests/test-break.c b/tests/test-break.c index 8549b678..f4faaab3 100644 --- a/tests/test-break.c +++ b/tests/test-break.c @@ -51,12 +51,8 @@ test_file (const gchar *filename, GString *string) PangoAttrList *attributes; PangoLayout *layout; - if (!g_file_get_contents (filename, &contents, &length, &error)) - { - fprintf (stderr, "%s\n", error->message); - g_error_free (error); - return; - } + g_file_get_contents (filename, &contents, &length, &error); + g_assert_no_error (error); test = contents; @@ -68,12 +64,8 @@ test_file (const gchar *filename, GString *string) len = g_utf8_strlen (test, -1) + 1; attrs = g_new (PangoLogAttr, len); - if (!pango_parse_markup (test, -1, 0, &attributes, &text, NULL, &error)) - { - fprintf (stderr, "%s\n", error->message); - g_error_free (error); - return; - } + pango_parse_markup (test, -1, 0, &attributes, &text, NULL, &error); + g_assert_no_error (error); layout = pango_layout_new (context); pango_layout_set_text (layout, text, length); @@ -260,7 +252,8 @@ test_break (gconstpointer d) if (diff && diff[0]) { - g_printerr ("Contents don't match expected contents:\n%s", diff); + g_test_message ("Contents don't match expected contents"); + g_test_message ("%s", diff); g_test_fail (); g_free (diff); } @@ -291,7 +284,7 @@ main (int argc, char *argv[]) string = g_string_sized_new (0); test_file (argv[1], string); - printf ("%s", string->str); + g_test_message ("%s", string->str); return 0; } diff --git a/tests/test-font.c b/tests/test-font.c index 5ef6cc39..486504f9 100644 --- a/tests/test-font.c +++ b/tests/test-font.c @@ -133,25 +133,21 @@ test_metrics (void) metrics = pango_context_get_metrics (context, desc, pango_language_get_default ()); - g_test_message ("%s metrics\n" - "\tascent %d\n" - "\tdescent %d\n" - "\theight %d\n" - "\tchar width %d\n" - "\tdigit width %d\n" - "\tunderline position %d\n" - "\tunderline thickness %d\n" - "\tstrikethrough position %d\n" - "\tstrikethrough thickness %d\n", - str, - pango_font_metrics_get_ascent (metrics), - pango_font_metrics_get_descent (metrics), - pango_font_metrics_get_height (metrics), - pango_font_metrics_get_approximate_char_width (metrics), - pango_font_metrics_get_approximate_digit_width (metrics), - pango_font_metrics_get_underline_position (metrics), - pango_font_metrics_get_underline_thickness (metrics), - pango_font_metrics_get_strikethrough_position (metrics), + g_test_message ("%s metrics", str); + g_test_message ("\tascent: %d", pango_font_metrics_get_ascent (metrics)); + g_test_message ("\tdescent: %d", pango_font_metrics_get_descent (metrics)); + g_test_message ("\theight: %d", pango_font_metrics_get_height (metrics)); + g_test_message ("\tchar width: %d", + pango_font_metrics_get_approximate_char_width (metrics)); + g_test_message ("\tdigit width: %d", + pango_font_metrics_get_approximate_digit_width (metrics)); + g_test_message ("\tunderline position: %d", + pango_font_metrics_get_underline_position (metrics)); + g_test_message ("\tunderline thickness: %d", + pango_font_metrics_get_underline_thickness (metrics)); + g_test_message ("\tstrikethrough position: %d", + pango_font_metrics_get_strikethrough_position (metrics)); + g_test_message ("\tstrikethrough thickness: %d", pango_font_metrics_get_strikethrough_thickness (metrics)); pango_font_metrics_unref (metrics); diff --git a/tests/test-itemize.c b/tests/test-itemize.c index d66c40d1..167e4e80 100644 --- a/tests/test-itemize.c +++ b/tests/test-itemize.c @@ -118,12 +118,8 @@ test_file (const gchar *filename, GString *string) GList *items, *l; const char *sep = ""; - if (!g_file_get_contents (filename, &contents, &length, &error)) - { - fprintf (stderr, "%s\n", error->message); - g_error_free (error); - return; - } + g_file_get_contents (filename, &contents, &length, &error); + g_assert_no_error (error); test = contents; @@ -131,13 +127,8 @@ test_file (const gchar *filename, GString *string) while (test[0] == '#') test = strchr (test, '\n') + 1; - - if (!pango_parse_markup (test, -1, 0, &attrs, &text, NULL, &error)) - { - fprintf (stderr, "%s\n", error->message); - g_error_free (error); - return; - } + pango_parse_markup (test, -1, 0, &attrs, &text, NULL, &error); + g_assert_no_error (error); s1 = g_string_new ("Items: "); s2 = g_string_new ("Font: "); @@ -257,7 +248,8 @@ test_itemize (gconstpointer d) if (diff && diff[0]) { - g_printerr ("Contents don't match expected contents:\n%s", diff); + g_test_message ("Contents don't match expected contents"); + g_test_message ("%s", diff); g_test_fail (); g_free (diff); } diff --git a/tests/test-layout.c b/tests/test-layout.c index cbbffd2c..2fc78240 100644 --- a/tests/test-layout.c +++ b/tests/test-layout.c @@ -238,12 +238,8 @@ test_file (const gchar *filename, GString *string) PangoWrapMode wrap = PANGO_WRAP_WORD; PangoFontDescription *desc; - if (!g_file_get_contents (filename, &contents, &length, &error)) - { - fprintf (stderr, "%s\n", error->message); - g_error_free (error); - return; - } + g_file_get_contents (filename, &contents, &length, &error); + g_assert_no_error (error); p = strchr (contents, '\n'); g_assert (p); @@ -319,7 +315,8 @@ test_layout (gconstpointer d) if (diff && diff[0]) { - g_printerr ("Contents don't match expected contents:\n%s", diff); + g_test_message ("Contents don't match expected contents"); + g_test_message ("%s", diff); g_test_fail (); g_free (diff); } @@ -350,7 +347,7 @@ main (int argc, char *argv[]) string = g_string_sized_new (0); test_file (argv[1], string); - g_print ("%s", string->str); + g_test_message ("%s", string->str); return 0; } diff --git a/tests/test-pangocairo-threads.c b/tests/test-pangocairo-threads.c index cdbd2419..ea97fc17 100644 --- a/tests/test-pangocairo-threads.c +++ b/tests/test-pangocairo-threads.c @@ -8,6 +8,7 @@ const char *text = "Hamburgerfonts\nวิวิวิวิวิวิ\nبهداد"; int num_iters = 50; +int num_threads = 5; GMutex mutex; @@ -65,18 +66,12 @@ thread_func (gpointer data) return 0; } -int -main (int argc, char **argv) +static void +pangocairo_threads (void) { - int num_threads = 5; - int i; GPtrArray *threads = g_ptr_array_new (); GPtrArray *surfaces = g_ptr_array_new (); - - if (argc > 1) - num_threads = atoi (argv[1]); - if (argc > 2) - num_iters = atoi (argv[2]); + int i; g_mutex_lock (&mutex); @@ -98,7 +93,7 @@ main (int argc, char **argv) for (i = 0; i < num_threads; i++) g_thread_join (g_ptr_array_index (threads, i)); - g_ptr_array_free (threads, TRUE); + g_ptr_array_unref (threads); /* Now, draw a reference image and check results. */ { @@ -123,10 +118,11 @@ main (int argc, char **argv) unsigned char *data = cairo_image_surface_get_data (surface); if (memcmp (ref_data, data, len)) { - fprintf (stderr, "image for thread %d different from reference image.\n", i); + g_test_message ("image for thread %d different from reference image", i); cairo_surface_write_to_png (ref_surface, "test-pangocairo-threads-reference.png"); cairo_surface_write_to_png (surface, "test-pangocairo-threads-failed.png"); - return 1; + g_test_fail (); + break; } cairo_surface_destroy (surface); } @@ -134,9 +130,23 @@ main (int argc, char **argv) cairo_surface_destroy (ref_surface); } - g_ptr_array_free (surfaces, TRUE); + g_ptr_array_unref (surfaces); pango_cairo_font_map_set_default (NULL); - return 0; +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + if (argc > 1) + num_threads = atoi (argv[1]); + if (argc > 2) + num_iters = atoi (argv[2]); + + g_test_add_func ("/pangocairo/threads", pangocairo_threads); + + return g_test_run (); } diff --git a/tests/test-shape.c b/tests/test-shape.c index 6c1ae296..c2488dbf 100644 --- a/tests/test-shape.c +++ b/tests/test-shape.c @@ -319,7 +319,8 @@ test_shape (gconstpointer d) if (diff && diff[0]) { - g_printerr ("Contents don't match expected contents:\n%s", diff); + g_test_message ("Contents don't match expected contents"); + g_test_message ("%s", diff); g_test_fail (); g_free (diff); } diff --git a/tests/testboundaries.c b/tests/testboundaries.c index 75da772e..2390bb28 100644 --- a/tests/testboundaries.c +++ b/tests/testboundaries.c @@ -46,27 +46,6 @@ static gunichar current_wc = 0; static const char *line_start = NULL; static const char *line_end = NULL; -static void fail (const char *format, ...) G_GNUC_PRINTF (1, 2) G_GNUC_NORETURN; -static void fail (const char *format, ...) -{ - char *str; - char *line_text; - - va_list args; - - va_start (args, format); - str = g_strdup_vprintf (format, args); - va_end (args); - - line_text = g_strndup (line_start, line_end - line_start); - - fprintf (stderr, "line %d offset %d char is " CHFORMAT ": %s\n (line is '%s')\n", line, offset, current_wc, str, line_text); - g_free (str); - g_free (line_text); - - exit (1); -} - typedef void (* CharForeachFunc) (gunichar wc, gunichar prev_wc, gunichar next_wc, @@ -175,28 +154,36 @@ check_line_char (gunichar wc, { if (prev_wc == '\r') { - if (attr->is_line_break) - fail ("line break between \\r and \\n"); + g_test_message ("Do not line break between \\r and \\n"); + g_assert_false (attr->is_line_break); } - if (next_attr && !next_attr->is_line_break) - fail ("no line break after \\n"); + if (next_attr != NULL) + { + g_test_message ("Line break after \\n"); + g_assert_true (next_attr->is_line_break); + } } - if (attr->is_line_break && prev_wc == 0) - fail ("first char in string should not be marked as a line break"); + if (attr->is_line_break) + { + g_test_message ("first char in string should not be marked as a line break"); + g_assert_false (prev_wc == 0); + } if (break_type == G_UNICODE_BREAK_SPACE) { - if (attr->is_line_break && prev_attr != NULL && - !attr->is_mandatory_break && - !(next_wc && g_unichar_break_type (next_wc) == G_UNICODE_BREAK_COMBINING_MARK)) - fail ("can't break lines before a space unless a mandatory break char precedes it or a combining mark follows; prev char was " CHFORMAT, prev_wc); + g_test_message ("can't break lines before a space unless a mandatory break char precedes it or a combining mark follows; prev char was: " CHFORMAT, prev_wc); + g_assert_false (attr->is_line_break && prev_attr != NULL && + !attr->is_mandatory_break && + !(next_wc && g_unichar_break_type (next_wc) == G_UNICODE_BREAK_COMBINING_MARK)); } - if (attr->is_mandatory_break && !attr->is_line_break) - fail ("mandatory breaks must also be marked as regular breaks"); - + if (attr->is_mandatory_break) + { + g_test_message ("mandatory breaks must also be marked as regular breaks"); + g_assert_true (attr->is_line_break); + } /* FIXME use the break tables from break.c to automatically @@ -204,23 +191,23 @@ check_line_char (gunichar wc, * be that hard to do. */ - if (break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION && - prev_break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION && - attr->is_line_break && - !attr->is_mandatory_break) - fail ("can't break between two open punctuation chars"); - - if (break_type == G_UNICODE_BREAK_CLOSE_PUNCTUATION && - prev_break_type == G_UNICODE_BREAK_CLOSE_PUNCTUATION && - attr->is_line_break && - !attr->is_mandatory_break) - fail ("can't break between two close punctuation chars"); - - if (break_type == G_UNICODE_BREAK_QUOTATION && - prev_break_type == G_UNICODE_BREAK_ALPHABETIC && - attr->is_line_break && - !attr->is_mandatory_break) - fail ("can't break letter-quotemark sequence"); + g_test_message ("can't break between two open punctuation chars"); + g_assert_false (break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION && + prev_break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION && + attr->is_line_break && + !attr->is_mandatory_break); + + g_test_message ("can't break between two close punctuation chars"); + g_assert_false (break_type == G_UNICODE_BREAK_CLOSE_PUNCTUATION && + prev_break_type == G_UNICODE_BREAK_CLOSE_PUNCTUATION && + attr->is_line_break && + !attr->is_mandatory_break); + + g_test_message ("can't break letter-quotemark sequence"); + g_assert_false (break_type == G_UNICODE_BREAK_QUOTATION && + prev_break_type == G_UNICODE_BREAK_ALPHABETIC && + attr->is_line_break && + !attr->is_mandatory_break); } static void @@ -290,8 +277,7 @@ check_invariants (const char *text) int len; PangoLogAttr *attrs; - if (!g_utf8_validate (text, -1, NULL)) - fail ("Invalid UTF-8 in test text"); + g_assert_true (g_utf8_validate (text, -1, NULL)); len = g_utf8_strlen (text, -1); attrs = g_new0 (PangoLogAttr, len + 1); @@ -318,24 +304,20 @@ check_invariants (const char *text) static void test_boundaries (void) { - gchar *text; - const gchar *filename; -#if GLIB_CHECK_VERSION(2, 37, 2) + const char *filename; + GError *error = NULL; + char *text; + filename = g_test_get_filename (G_TEST_DIST, "boundaries.utf8", NULL); -#else - filename = SRCDIR "/boundaries.utf8"; -#endif - g_print ("sample file: %s\n", filename); + g_test_message ("sample file: %s\n", filename); - if (!g_file_get_contents (filename, &text, NULL, NULL)) - fail ("Couldn't open sample text file"); + g_file_get_contents (filename, &text, NULL, &error); + g_assert_no_error (error); check_invariants (text); g_free (text); - - printf ("testboundaries passed\n"); } int @@ -347,4 +329,3 @@ main (int argc, char *argv[]) return g_test_run (); } - diff --git a/tests/testboundaries_ucd.c b/tests/testboundaries_ucd.c index 53f7b4cb..ee5617bc 100644 --- a/tests/testboundaries_ucd.c +++ b/tests/testboundaries_ucd.c @@ -230,32 +230,28 @@ do_test (const gchar *filename, error = NULL; channel = g_io_channel_new_file (filename, "r", &error); - if (!channel) + if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) { - if (error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT) - { - g_print ("%s not found. Skipping test.\n", filename); - goto done; - } - else - { - g_printerr ("%s: %s\n", filename, error->message); - exit (1); - } + g_test_skip ("Test file not found"); + return; } - g_print ("Testing %s.\n", filename); + + g_assert_no_error (error); + + g_test_message ("Filename: %s", filename); i = 1; for (;;) { error = NULL; status = g_io_channel_read_line (channel, &line, &length, &terminator_pos, &error); + g_assert_no_error (error); switch (status) { case G_IO_STATUS_ERROR: - g_printerr ("%s: %s\n", filename, error->message); - exit (1); + failed = TRUE; + goto done; case G_IO_STATUS_EOF: goto done; @@ -268,11 +264,8 @@ do_test (const gchar *filename, break; } - if (! parse_line (line, bits, &string, &expected_attrs, &num_attrs)) - { - g_printerr ("%s: error parsing line %d: %s\n", filename, i, line); - exit (1); - } + g_test_message ("Parsing line: %s", line); + g_assert_true (parse_line (line, bits, &string, &expected_attrs, &num_attrs)); if (num_attrs > 0) { @@ -293,11 +286,10 @@ do_test (const gchar *filename, comments = ""; } - g_printerr ("%s: line %d failed\n" - " expected: %s\n" - " returned: %s\n" - " comments: %s\n\n", - filename, i, line, str, comments); + g_test_message ("%s: line %d failed", filename, i); + g_test_message (" expected: %s", line); + g_test_message (" returned: %s", str); + g_test_message (" comments: %s", comments); g_free (str); failed = TRUE; @@ -316,20 +308,16 @@ done: if (error) g_error_free (error); - g_assert (!failed); + g_assert_true (!failed); } static void test_grapheme_break (void) { - const gchar *filename; + const char *filename; AttrBits bits; -#if GLIB_CHECK_VERSION(2, 37, 2) filename = g_test_get_filename (G_TEST_DIST, "GraphemeBreakTest.txt", NULL); -#else - filename = SRCDIR "/GraphemeBreakTest.txt"; -#endif bits.bits = 0; bits.attr.is_cursor_position = 1; do_test (filename, bits); @@ -338,14 +326,10 @@ test_grapheme_break (void) static void test_emoji_break (void) { - const gchar *filename; + const char *filename; AttrBits bits; -#if GLIB_CHECK_VERSION(2, 37, 2) filename = g_test_get_filename (G_TEST_DIST, "EmojiBreakTest.txt", NULL); -#else - filename = SRCDIR "/EmojiBreakTest.txt"; -#endif bits.bits = 0; bits.attr.is_cursor_position = 1; do_test (filename, bits); @@ -354,14 +338,10 @@ test_emoji_break (void) static void test_char_break (void) { - const gchar *filename; + const char *filename; AttrBits bits; -#if GLIB_CHECK_VERSION(2, 37, 2) filename = g_test_get_filename (G_TEST_DIST, "CharBreakTest.txt", NULL); -#else - filename = SRCDIR "/CharBreakTest.txt"; -#endif bits.bits = 0; bits.attr.is_char_break = 1; do_test (filename, bits); @@ -370,14 +350,10 @@ test_char_break (void) static void test_word_break (void) { - const gchar *filename; + const char *filename; AttrBits bits; -#if GLIB_CHECK_VERSION(2, 37, 2) filename = g_test_get_filename (G_TEST_DIST, "WordBreakTest.txt", NULL); -#else - filename = SRCDIR "/WordBreakTest.txt"; -#endif bits.bits = 0; bits.attr.is_word_boundary = 1; do_test (filename, bits); @@ -386,14 +362,10 @@ test_word_break (void) static void test_sentence_break (void) { - const gchar *filename; + const char *filename; AttrBits bits; -#if GLIB_CHECK_VERSION(2, 37, 2) filename = g_test_get_filename (G_TEST_DIST, "SentenceBreakTest.txt", NULL); -#else - filename = SRCDIR "/SentenceBreakTest.txt"; -#endif bits.bits = 0; bits.attr.is_sentence_boundary = 1; do_test (filename, bits); @@ -402,17 +374,15 @@ test_sentence_break (void) static void test_line_break (void) { - const gchar *filename; + const char *filename; AttrBits bits; -#if GLIB_CHECK_VERSION(2, 37, 2) + filename = g_test_get_filename (G_TEST_DIST, "LineBreakTest.txt", NULL); -#else - filename = SRCDIR "/LineBreakTest.txt"; -#endif bits.bits = 0; bits.attr.is_line_break = 1; bits.attr.is_mandatory_break = 1; + do_test (filename, bits); } diff --git a/tests/testscript.c b/tests/testscript.c index aa610b44..33e8ad2e 100644 --- a/tests/testscript.c +++ b/tests/testscript.c @@ -60,18 +60,6 @@ #include "pango/pango-script.h" -#undef VERBOSE - -#define ASSERT(stmt) G_STMT_START { \ - if (stmt) { } \ - else \ - { \ - g_warning ("%s:%d (%s): assertion '%s' failed", \ - __FILE__, __LINE__, G_STRFUNC, #stmt); \ - exit (1); \ - } \ -} G_STMT_END - typedef struct { const char *run_text_escaped; @@ -170,9 +158,7 @@ test_script_iter (void) iter = pango_script_iter_new (all->str, -1); -#ifdef VERBOSE - g_print ("Total length: %d\n", all->len); -#endif + g_test_message ("Total length: %" G_GSIZE_FORMAT "\n", all->len); pos = all->str; for (i = 0; i < G_N_ELEMENTS(test_data); i++) @@ -181,16 +167,18 @@ test_script_iter (void) gboolean result; pango_script_iter_get_range (iter, &start, &end, &script); -#ifdef VERBOSE - g_print ("Range: %d-%d: %d\n", start - all->str, end - all->str, script); -#endif - ASSERT (start == pos); - ASSERT (end == next_pos); - ASSERT (script == test_data[i].run_code); + g_test_message ("Range: %d-%d: %d\n", + (int) (start - all->str), + (int) (end - all->str), + script); + + g_assert_true (start == pos); + g_assert_true (end == next_pos); + g_assert_true (script == test_data[i].run_code); result = pango_script_iter_next (iter); - ASSERT (result == (i != G_N_ELEMENTS (test_data) - 1)); + g_assert_true (result == (i != G_N_ELEMENTS (test_data) - 1)); pos = next_pos; } @@ -204,10 +192,10 @@ test_script_iter (void) pango_script_iter_get_range (iter, &start, &end, &script); - ASSERT (start == all->str); - ASSERT (end == all->str); - ASSERT (script == PANGO_SCRIPT_COMMON); - ASSERT (!pango_script_iter_next (iter)); + g_assert_true (start == all->str); + g_assert_true (end == all->str); + g_assert_true (script == PANGO_SCRIPT_COMMON); + g_assert_true (!pango_script_iter_next (iter)); pango_script_iter_free (iter); |