From cae15d15c847faba203e40e2a327b23a1ebffb48 Mon Sep 17 00:00:00 2001
From: David Robillard <d@drobilla.net>
Date: Sun, 28 Jun 2020 19:46:47 +0200
Subject: Make Writer always write to a ByteSink

---
 test/meson.build          |  9 ++++++
 test/run_test_suite.py    |  8 +++--
 test/test_byte_sink.c     | 32 ++++++++++++++++++++
 test/test_reader_writer.c | 17 ++++++-----
 test/test_terse_write.c   |  8 +++--
 test/test_writer.c        | 75 +++++++++++++++++++++++++++--------------------
 6 files changed, 106 insertions(+), 43 deletions(-)
 create mode 100644 test/test_byte_sink.c

(limited to 'test')

diff --git a/test/meson.build b/test/meson.build
index 9724f18e..1245e29d 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -5,6 +5,7 @@ run_test_suite = find_program('run_test_suite.py')
 wrapper = meson.get_cross_property('exe_wrapper', '')
 
 unit_tests = [
+  'byte_sink',
   'caret',
   'env',
   'free_null',
@@ -83,6 +84,7 @@ if get_option('utils')
     ['-o'],
     ['-p'],
     ['-r'],
+    ['-w'],
     ['-z'],
     ['-s', '<foo> a <Bar> .'],
   ]
@@ -166,6 +168,13 @@ if get_option('utils')
        env: test_env,
        suite: 'io_errors')
 
+  test('write_bad_file', serdi,
+       args: ['-w', '/does/not/exist.ttl',
+              'file://@0@/serd.ttl'.format(meson.source_root())],
+       env: test_env,
+       should_fail: true,
+       suite: 'io_errors')
+
   # RDF test suites
 
   ## Serd-specific test suites
diff --git a/test/run_test_suite.py b/test/run_test_suite.py
index 5223060d..7a3b5e88 100755
--- a/test/run_test_suite.py
+++ b/test/run_test_suite.py
@@ -83,6 +83,8 @@ def test_thru(
             isyntax,
             "-p",
             "foo",
+            "-w",
+            out_path,
             path,
             base_uri,
         ]
@@ -98,14 +100,16 @@ def test_thru(
             osyntax,
             "-c",
             "foo",
+            "-w",
+            thru_path,
             "-a",
             out_path,
             base_uri,
         ]
     )
 
-    with open(out_path, "wb") as out:
-        subprocess.run(out_cmd, check=True, stdout=out)
+    subprocess.run(out_cmd, check=True)
+    subprocess.run(thru_cmd, check=True)
 
     with open(thru_path, "wb") as out:
         subprocess.run(thru_cmd, check=True, stdout=out)
diff --git a/test/test_byte_sink.c b/test/test_byte_sink.c
new file mode 100644
index 00000000..1982a436
--- /dev/null
+++ b/test/test_byte_sink.c
@@ -0,0 +1,32 @@
+/*
+  Copyright 2021 David Robillard <d@drobilla.net>
+
+  Permission to use, copy, modify, and/or distribute this software for any
+  purpose with or without fee is hereby granted, provided that the above
+  copyright notice and this permission notice appear in all copies.
+
+  THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#undef NDEBUG
+
+#include "serd/serd.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+int
+main(void)
+{
+  assert(!serd_byte_sink_new_filename("file.ttl", 0));
+  assert(!serd_byte_sink_new_filename("/does/not/exist.ttl", 1));
+  assert(!serd_byte_sink_new_function((SerdWriteFunc)fwrite, NULL, 0));
+
+  return 0;
+}
diff --git a/test/test_reader_writer.c b/test/test_reader_writer.c
index 3f538ada..82d67bee 100644
--- a/test/test_reader_writer.c
+++ b/test/test_reader_writer.c
@@ -178,8 +178,12 @@ test_writer(const char* const path)
   SerdWorld* world = serd_world_new();
   SerdNodes* nodes = serd_world_nodes(world);
 
-  SerdWriter* writer = serd_writer_new(
-    world, SERD_TURTLE, SERD_WRITE_LAX, env, (SerdWriteFunc)fwrite, fd);
+  SerdByteSink* byte_sink =
+    serd_byte_sink_new_function((SerdWriteFunc)fwrite, fd, 1);
+
+  SerdWriter* writer =
+    serd_writer_new(world, SERD_TURTLE, SERD_WRITE_LAX, env, byte_sink);
+
   assert(writer);
 
   serd_writer_chop_blank_prefix(writer, "tmp");
@@ -240,14 +244,13 @@ test_writer(const char* const path)
   assert(!serd_sink_write(iface, 0, s, p, hello, 0));
 
   serd_writer_free(writer);
+  serd_byte_sink_free(byte_sink);
 
   // Test buffer sink
-  SerdBuffer    buffer = {NULL, 0};
-  SerdByteSink* byte_sink =
-    serd_byte_sink_new((SerdWriteFunc)serd_buffer_sink, &buffer, 1);
+  SerdBuffer buffer = {NULL, 0};
 
-  writer = serd_writer_new(
-    world, SERD_TURTLE, 0, env, (SerdWriteFunc)serd_byte_sink_write, byte_sink);
+  byte_sink = serd_byte_sink_new_buffer(&buffer);
+  writer    = serd_writer_new(world, SERD_TURTLE, 0, env, byte_sink);
 
   const SerdNode* const base =
     serd_nodes_uri(nodes, SERD_STRING("http://example.org/base"));
diff --git a/test/test_terse_write.c b/test/test_terse_write.c
index 9a19d493..59227332 100644
--- a/test/test_terse_write.c
+++ b/test/test_terse_write.c
@@ -64,10 +64,11 @@ test(void)
 
   serd_env_set_prefix(env, SERD_STRING("rdf"), SERD_STRING(NS_RDF));
 
-  SerdWriter* writer = serd_writer_new(
-    world, SERD_TURTLE, 0, env, (SerdWriteFunc)serd_buffer_sink, &buffer);
+  SerdByteSink* const byte_sink = serd_byte_sink_new_buffer(&buffer);
+  SerdWriter* const   writer =
+    serd_writer_new(world, SERD_TURTLE, 0, env, byte_sink);
 
-  const SerdSink* sink = serd_writer_sink(writer);
+  const SerdSink* const sink = serd_writer_sink(writer);
 
   // Simple lone list
   serd_sink_write(sink, SERD_TERSE_S | SERD_LIST_S, l1, rdf_first, s1, NULL);
@@ -99,6 +100,7 @@ test(void)
 
   serd_buffer_sink_finish(&buffer);
   serd_writer_free(writer);
+  serd_byte_sink_free(byte_sink);
   serd_nodes_free(nodes);
   serd_env_free(env);
   serd_world_free(world);
diff --git a/test/test_writer.c b/test/test_writer.c
index e31119bf..df8ba520 100644
--- a/test/test_writer.c
+++ b/test/test_writer.c
@@ -27,12 +27,12 @@
 static void
 test_write_bad_event(void)
 {
-  SerdWorld*  world  = serd_world_new();
-  SerdEnv*    env    = serd_env_new(SERD_EMPTY_STRING());
-  SerdBuffer  buffer = {NULL, 0};
-  SerdWriter* writer =
-    serd_writer_new(world, SERD_TURTLE, 0u, env, serd_buffer_sink, &buffer);
+  SerdWorld*    world     = serd_world_new();
+  SerdEnv*      env       = serd_env_new(SERD_EMPTY_STRING());
+  SerdBuffer    buffer    = {NULL, 0};
+  SerdByteSink* byte_sink = serd_byte_sink_new_buffer(&buffer);
 
+  SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0u, env, byte_sink);
   assert(writer);
 
   const SerdEvent event = {(SerdEventType)42};
@@ -45,6 +45,7 @@ test_write_bad_event(void)
   serd_free(out);
 
   serd_writer_free(writer);
+  serd_byte_sink_free(byte_sink);
   serd_env_free(env);
   serd_world_free(world);
 }
@@ -52,13 +53,13 @@ test_write_bad_event(void)
 static void
 test_write_bad_prefix(void)
 {
-  SerdWorld*  world  = serd_world_new();
-  SerdNodes*  nodes  = serd_world_nodes(world);
-  SerdEnv*    env    = serd_env_new(SERD_EMPTY_STRING());
-  SerdBuffer  buffer = {NULL, 0};
-  SerdWriter* writer =
-    serd_writer_new(world, SERD_TURTLE, 0u, env, serd_buffer_sink, &buffer);
+  SerdWorld*    world     = serd_world_new();
+  SerdNodes*    nodes     = serd_world_nodes(world);
+  SerdEnv*      env       = serd_env_new(SERD_EMPTY_STRING());
+  SerdBuffer    buffer    = {NULL, 0};
+  SerdByteSink* byte_sink = serd_byte_sink_new_buffer(&buffer);
 
+  SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0u, env, byte_sink);
   assert(writer);
 
   const SerdNode* name = serd_nodes_string(nodes, SERD_STRING("eg"));
@@ -73,6 +74,7 @@ test_write_bad_prefix(void)
   serd_free(out);
 
   serd_writer_free(writer);
+  serd_byte_sink_free(byte_sink);
   serd_env_free(env);
   serd_world_free(world);
 }
@@ -80,13 +82,13 @@ test_write_bad_prefix(void)
 static void
 test_write_long_literal(void)
 {
-  SerdWorld*  world  = serd_world_new();
-  SerdNodes*  nodes  = serd_world_nodes(world);
-  SerdEnv*    env    = serd_env_new(SERD_EMPTY_STRING());
-  SerdBuffer  buffer = {NULL, 0};
-  SerdWriter* writer =
-    serd_writer_new(world, SERD_TURTLE, 0u, env, serd_buffer_sink, &buffer);
+  SerdWorld*    world     = serd_world_new();
+  SerdNodes*    nodes     = serd_world_nodes(world);
+  SerdEnv*      env       = serd_env_new(SERD_EMPTY_STRING());
+  SerdBuffer    buffer    = {NULL, 0};
+  SerdByteSink* byte_sink = serd_byte_sink_new_buffer(&buffer);
 
+  SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0u, env, byte_sink);
   assert(writer);
 
   const SerdNode* s =
@@ -99,6 +101,7 @@ test_write_long_literal(void)
   assert(!serd_sink_write(serd_writer_sink(writer), 0, s, p, o, NULL));
 
   serd_writer_free(writer);
+  serd_byte_sink_free(byte_sink);
   serd_env_free(env);
 
   char* out = serd_buffer_sink_finish(&buffer);
@@ -128,12 +131,12 @@ null_sink(const void* const buf,
 static void
 test_writer_stack_overflow(void)
 {
-  SerdWorld* world = serd_world_new();
-  SerdNodes* nodes = serd_world_nodes(world);
-  SerdEnv*   env   = serd_env_new(SERD_EMPTY_STRING());
+  SerdWorld*    world     = serd_world_new();
+  SerdNodes*    nodes     = serd_world_nodes(world);
+  SerdEnv*      env       = serd_env_new(SERD_EMPTY_STRING());
+  SerdByteSink* byte_sink = serd_byte_sink_new_function(null_sink, NULL, 1u);
 
-  SerdWriter* writer =
-    serd_writer_new(world, SERD_TURTLE, 0u, env, null_sink, NULL);
+  SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0u, env, byte_sink);
 
   const SerdSink* sink = serd_writer_sink(writer);
 
@@ -168,6 +171,7 @@ test_writer_stack_overflow(void)
   assert(st == SERD_ERR_OVERFLOW);
 
   serd_writer_free(writer);
+  serd_byte_sink_free(byte_sink);
   serd_env_free(env);
   serd_world_free(world);
 }
@@ -181,10 +185,12 @@ test_strict_write(void)
   FILE*       fd    = fopen(path, "wb");
   assert(fd);
 
-  SerdEnv*    env = serd_env_new(SERD_EMPTY_STRING());
-  SerdWriter* writer =
-    serd_writer_new(world, SERD_TURTLE, 0u, env, (SerdWriteFunc)fwrite, fd);
+  SerdEnv* env = serd_env_new(SERD_EMPTY_STRING());
+
+  SerdByteSink* byte_sink =
+    serd_byte_sink_new_function((SerdWriteFunc)fwrite, fd, 1);
 
+  SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0, env, byte_sink);
   assert(writer);
 
   const SerdSink*      sink      = serd_writer_sink(writer);
@@ -204,6 +210,7 @@ test_strict_write(void)
   assert(serd_sink_write(sink, 0, s, p, bad_uri, 0) == SERD_ERR_BAD_TEXT);
 
   serd_writer_free(writer);
+  serd_byte_sink_free(byte_sink);
   serd_env_free(env);
   fclose(fd);
   serd_world_free(world);
@@ -245,18 +252,20 @@ test_write_error(void)
 
   // Test with setting errno
 
-  SerdWriter* writer =
-    serd_writer_new(world, SERD_TURTLE, 0u, env, faulty_sink, NULL);
+  SerdByteSink* byte_sink = serd_byte_sink_new_function(faulty_sink, NULL, 1);
 
+  SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0u, env, byte_sink);
   assert(writer);
 
   SerdStatus st = serd_sink_write(serd_writer_sink(writer), 0u, s, p, o, NULL);
   assert(st == SERD_ERR_BAD_WRITE);
 
   serd_writer_free(writer);
+  serd_byte_sink_free(byte_sink);
 
   // Test without setting errno
-  writer = serd_writer_new(world, SERD_TURTLE, 0u, env, faulty_sink, world);
+  byte_sink = serd_byte_sink_new_function(faulty_sink, world, 1);
+  writer    = serd_writer_new(world, SERD_TURTLE, 0u, env, byte_sink);
 
   assert(writer);
 
@@ -264,6 +273,7 @@ test_write_error(void)
          SERD_ERR_BAD_WRITE);
 
   serd_writer_free(writer);
+  serd_byte_sink_free(byte_sink);
 
   serd_env_free(env);
   serd_world_free(world);
@@ -278,15 +288,17 @@ test_write_empty_syntax(void)
 
   const SerdNode* s =
     serd_nodes_uri(nodes, SERD_STRING("http://example.org/s"));
+
   const SerdNode* p =
     serd_nodes_uri(nodes, SERD_STRING("http://example.org/p"));
 
   const SerdNode* o = serd_nodes_curie(nodes, SERD_STRING("eg:o"));
 
-  SerdBuffer buffer = {NULL, 0};
+  SerdBuffer    buffer    = {NULL, 0};
+  SerdByteSink* byte_sink = serd_byte_sink_new_buffer(&buffer);
 
-  SerdWriter* writer = serd_writer_new(
-    world, SERD_SYNTAX_EMPTY, 0u, env, serd_buffer_sink, &buffer);
+  SerdWriter* writer =
+    serd_writer_new(world, SERD_SYNTAX_EMPTY, 0u, env, byte_sink);
 
   assert(writer);
 
@@ -298,6 +310,7 @@ test_write_empty_syntax(void)
   serd_free(out);
 
   serd_writer_free(writer);
+  serd_byte_sink_free(byte_sink);
   serd_env_free(env);
   serd_world_free(world);
 }
-- 
cgit v1.2.1