summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gmail.com>2020-04-14 12:53:12 +0000
committerEmmanuele Bassi <ebassi@gmail.com>2020-04-14 12:53:12 +0000
commit72f8c87507d6edbd1f918c0415eb8b5c4b80f130 (patch)
treea141e973ea4508263c4c164f258d112c220e7d20
parent2a773323f1f7b5510ee0de7a1ea0ac8bec0e05d4 (diff)
parent7b66f9604ddb4743276f38b6a17f10bf4d446583 (diff)
downloadpango-72f8c87507d6edbd1f918c0415eb8b5c4b80f130.tar.gz
Merge branch 'ci-improved' into 'master'
Improve the Pango CI pipeline on Linux See merge request GNOME/pango!183
-rw-r--r--.gitlab-ci.yml91
-rw-r--r--.gitlab-ci/README.md38
-rw-r--r--.gitlab-ci/fedora.Dockerfile49
-rwxr-xr-x.gitlab-ci/meson-junit-report.py112
-rwxr-xr-x.gitlab-ci/run-docker.sh135
-rwxr-xr-x.gitlab-ci/run-tests.sh29
-rw-r--r--docs/meson.build5
-rw-r--r--meson.build1
-rw-r--r--tests/markup-parse.c10
-rw-r--r--tests/meson.build16
-rw-r--r--tests/test-break.c21
-rw-r--r--tests/test-font.c34
-rw-r--r--tests/test-itemize.c20
-rw-r--r--tests/test-layout.c13
-rw-r--r--tests/test-pangocairo-threads.c38
-rw-r--r--tests/test-shape.c3
-rw-r--r--tests/testboundaries.c111
-rw-r--r--tests/testboundaries_ucd.c80
-rw-r--r--tests/testscript.c40
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 d4cff2af..dc634c8a 100644
--- a/meson.build
+++ b/meson.build
@@ -539,6 +539,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);