aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/man/serd-pipe.19
-rw-r--r--test/meson.build15
-rwxr-xr-xtest/run_suite.py24
-rw-r--r--test/serd_test_util/__init__.py4
-rwxr-xr-xtest/test_base.py21
-rwxr-xr-xtest/test_stdin.py2
-rw-r--r--tools/serd-pipe.c16
7 files changed, 71 insertions, 20 deletions
diff --git a/doc/man/serd-pipe.1 b/doc/man/serd-pipe.1
index 32482c73..d335450f 100644
--- a/doc/man/serd-pipe.1
+++ b/doc/man/serd-pipe.1
@@ -9,6 +9,7 @@
.Sh SYNOPSIS
.Nm serd-pipe
.Op Fl abefhlqtv
+.Op Fl B Ar base
.Op Fl c Ar prefix
.Op Fl i Ar syntax
.Op Fl k Ar bytes
@@ -17,7 +18,6 @@
.Op Fl r Ar root
.Op Fl s Ar string
.Ar input
-.Op Ar base_uri
.Sh DESCRIPTION
.Nm
is a fast command-line utility for streaming and processing RDF data.
@@ -35,6 +35,13 @@ or transform URIs and blank node IDs.
.Pp
The options are as follows:
.Bl -tag -width 3n
+.It Fl B Ar base
+Input base URI.
+Relative URI references in the input will be resolved against this.
+When the input is a file,
+the URI of the file is automatically used as the base URI.
+This option can be used to override that,
+or to provide a base URI for input from stdin or a string.
.It Fl a
Write ASCII output.
If this is enabled, all non-ASCII characters will be escaped, even if the output syntax allows them to be written in UTF-8.
diff --git a/test/meson.build b/test/meson.build
index 2178ce1f..3af7cd15 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -16,6 +16,7 @@ simple_script_paths = [
'../scripts/check_formatting.py',
'serd_test_util/__init__.py',
'run_suite.py',
+ 'test_base.py',
'test_empty.py',
'test_quiet.py',
'test_stdin.py',
@@ -172,6 +173,8 @@ endif
simple_command_tests = {
'pipe': {
'bad': [
+ ['-B', 'nonuriorpath'],
+ ['-B'],
['-c'],
['-fi'],
['-i', 'turtle'],
@@ -223,6 +226,18 @@ if is_variable('serd_pipe')
test('none', serd_pipe, env: test_env, should_fail: true, suite: cmd_suite)
+ # Base URI options
+
+ test(
+ 'base',
+ files('test_base.py'),
+ args: pipe_script_args,
+ env: test_env,
+ suite: cmd_suite,
+ )
+
+ # Log
+
test(
'quiet',
files('test_quiet.py'),
diff --git a/test/run_suite.py b/test/run_suite.py
index fdda0625..ffc616a3 100755
--- a/test/run_suite.py
+++ b/test/run_suite.py
@@ -37,11 +37,11 @@ TEST_TYPES = [
]
-def run_eval_test(base_uri, command, in_path, good_path, out_path):
+def run_eval_test(command, in_path, good_path, out_path):
"""Run a positive eval test and return whether the output matches."""
syntax = util.syntax_from_path(out_path)
- command = command + ["-o", syntax, in_path, base_uri]
+ command = command + ["-o", syntax, in_path]
with subprocess.Popen(command, stdout=PIPE, encoding="utf-8") as proc:
out = list(proc.stdout)
@@ -50,21 +50,21 @@ def run_eval_test(base_uri, command, in_path, good_path, out_path):
return util.lines_equal(list(good), out, good_path, out_path)
-def run_positive_test(base_uri, command, in_path):
+def run_positive_test(command, in_path):
"""Run a positive syntax test and ensure no errors occur."""
- command = command + [in_path, base_uri]
+ command = command + [in_path]
subprocess.check_call(command, encoding="utf-8", stdout=DEVNULL)
return True
-def run_negative_test(base_uri, command, in_path):
+def run_negative_test(command, in_path):
"""Run a negative syntax test and return whether the error was detected."""
if not os.path.exists(in_path):
raise RuntimeError("Input file missing: " + in_path)
- command = command + [in_path, base_uri]
+ command = command + [in_path]
proc = subprocess.run(command, check=False, stderr=PIPE, stdout=DEVNULL)
if proc.returncode == 0:
@@ -82,21 +82,21 @@ def run_entry(args, entry, command, out_dir, suite_dir):
"""Run a single test entry from the manifest."""
in_path = util.file_path(suite_dir, entry[NS_MF + "action"][0])
- base = args.base_uri + os.path.basename(in_path)
+ command = command + ["-B", args.base_uri + os.path.basename(in_path)]
negative = "Negative" in entry[NS_RDF + "type"][0]
if negative and not args.lax:
- return run_negative_test(base, command, in_path)
+ return run_negative_test(command, in_path)
if NS_MF + "result" not in entry:
- return run_positive_test(base, command, in_path)
+ return run_positive_test(command, in_path)
good_path = util.file_path(suite_dir, entry[NS_MF + "result"][0])
if args.reverse:
in_path, good_path = good_path, in_path
out_path = os.path.join(out_dir, os.path.basename(good_path))
- return run_eval_test(base, command, in_path, good_path, out_path)
+ return run_eval_test(command, in_path, good_path, out_path)
def run_suite(args, command, out_dir):
@@ -104,7 +104,9 @@ def run_suite(args, command, out_dir):
# Load manifest model
top = os.path.dirname(args.manifest)
- model, instances = util.load_rdf(args.manifest, args.base_uri, command)
+ model, instances = util.load_rdf(
+ command + ["-B", args.base_uri], args.manifest
+ )
# Run all the listed tests that have known types
command = command + args.arg
diff --git a/test/serd_test_util/__init__.py b/test/serd_test_util/__init__.py
index ac831054..f465a4b7 100644
--- a/test/serd_test_util/__init__.py
+++ b/test/serd_test_util/__init__.py
@@ -148,14 +148,14 @@ def earl_assertion(test, passed, asserter):
)
-def load_rdf(filename, base_uri, command_prefix):
+def load_rdf(command_prefix, filename):
"""Load an RDF file as dictionaries via serd-pipe (only supports URIs)."""
rdf_type = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
model = {}
instances = {}
- cmd = command_prefix + [filename, base_uri]
+ cmd = command_prefix + [filename]
proc = subprocess.run(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True
)
diff --git a/test/test_base.py b/test/test_base.py
new file mode 100755
index 00000000..b63bb135
--- /dev/null
+++ b/test/test_base.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python3
+
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: ISC
+
+"""Test reading from stdin with serd-pipe."""
+
+# pylint: disable=consider-using-f-string
+
+import serd_test_util as util
+
+args = util.wrapper_args(__doc__)
+command = [args.tool, "-B", "http://example.org", "-i", "turtle", "-"]
+
+IN_DOC = "<s> <p> <o> ."
+OUT_DOC = "<{0}s> <{0}p> <{0}o> .".format("http://example.org/")
+
+lines = util.command_output(args.wrapper, command, IN_DOC).splitlines(True)
+
+assert len(lines) == 1
+assert lines[0].strip() == OUT_DOC
diff --git a/test/test_stdin.py b/test/test_stdin.py
index 9975c547..9ffd19ff 100755
--- a/test/test_stdin.py
+++ b/test/test_stdin.py
@@ -10,7 +10,7 @@
import serd_test_util as util
args = util.wrapper_args(__doc__)
-command = [args.tool, "-i", "ntriples", "-", "http://example.org"]
+command = [args.tool, "-i", "ntriples", "-B", "http://example.org", "-"]
DOC = "<{0}s> <{0}p> <{0}o> .".format("http://example.org/")
diff --git a/tools/serd-pipe.c b/tools/serd-pipe.c
index 26a4a26a..a5f2a1b2 100644
--- a/tools/serd-pipe.c
+++ b/tools/serd-pipe.c
@@ -33,6 +33,7 @@ print_usage(const char* const name, const bool error)
static const char* const description =
"Read and write RDF syntax.\n"
"Use - for INPUT to read from standard input.\n\n"
+ " -B BASE_URI Base URI.\n"
" -a Write ASCII output.\n"
" -b Write output in blocks for performance.\n"
" -c PREFIX Chop PREFIX from matching blank node IDs.\n"
@@ -52,7 +53,7 @@ print_usage(const char* const name, const bool error)
FILE* const os = error ? stderr : stdout;
fprintf(os, "%s", error ? "\n" : "");
- fprintf(os, "Usage: %s [OPTION]... INPUT [BASE_URI]\n", name);
+ fprintf(os, "Usage: %s [OPTION]... INPUT\n", name);
fprintf(os, "%s", description);
return error ? 1 : 0;
}
@@ -77,6 +78,7 @@ main(int argc, char** argv)
{
const char* const prog = argv[0];
+ SerdNode* base = NULL;
SerdSyntax input_syntax = SERD_SYNTAX_EMPTY;
SerdSyntax output_syntax = SERD_SYNTAX_EMPTY;
SerdReaderFlags reader_flags = 0;
@@ -131,6 +133,13 @@ main(int argc, char** argv)
} else if (opt == 's') {
from_string = true;
break;
+ } else if (argv[a][1] == 'B') {
+ if (++a == argc) {
+ return missing_arg(prog, 'B');
+ }
+
+ base = serd_new_uri(serd_string(argv[a]));
+ break;
} else if (opt == 'c') {
if (argv[a][o + 1] || ++a == argc) {
return missing_arg(prog, 'c');
@@ -212,10 +221,7 @@ main(int argc, char** argv)
output_syntax = input_has_graphs ? SERD_NQUADS : SERD_NTRIPLES;
}
- SerdNode* base = NULL;
- if (a < argc) { // Base URI given on command line
- base = serd_new_uri(serd_string(argv[a]));
- } else if (!from_string && !from_stdin) { // Use input file URI
+ if (!base && !from_string && !from_stdin) { // Use input file URI
base = serd_new_file_uri(serd_string(input), serd_empty_string());
}