Windows: tests: path handling

On Windows, the paths are just completely different:

- path separator uses backslashes instead of forward slashes,
- the MSVC generator is a multi-config one, which means that it will
happily put files into an extra subdirectory of
RUNTIME_OUTPUT_DIRECTORY,
- there's an extra file extensions,
- some operations have different semantics, and error messages are
different.

Rather than trying to fix all that, write a tiny test case just for
Windows.

An alternative would be to distinguish between "the test binary
directory", "directory with utests binaries" and "directory with test
plugin binaries". Also, the tests use the "binary dir" for things like
CMakeFiles (!), which is super implementation-specific.

I wanted to solve this by some custom paths, but the patch was not
pretty and it was rejected upstream. Instead, do the bare minimum which
is needed here.

On Unix, libyang plugins are not subject to RUNTIME_OUTPUT_DIRECTORY,
instead requiring LIBRARY_OUTPUT_DIRECTORY.
diff --git a/tests/utests/basic/test_context.c b/tests/utests/basic/test_context.c
index f542bc2..5b05a83 100644
--- a/tests/utests/basic/test_context.c
+++ b/tests/utests/basic/test_context.c
@@ -22,6 +22,74 @@
 #include "tree_schema_internal.h"
 #include "utests.h"
 
+#ifdef _WIN32
+static void
+slashes_to_backslashes(char *path)
+{
+    while ((path = strchr(path, '/'))) {
+        *path++ = '\\';
+    }
+}
+
+static void
+test_searchdirs(void **state)
+{
+    const char * const *list;
+    char *path1 = strdup(TESTS_BIN "/utests");
+    char *path2 = strdup(TESTS_SRC);
+
+    slashes_to_backslashes(path1);
+    slashes_to_backslashes(path2);
+
+    assert_int_equal(LY_EINVAL, ly_ctx_set_searchdir(NULL, NULL));
+    CHECK_LOG("Invalid argument ctx (ly_ctx_set_searchdir()).", NULL);
+    assert_null(ly_ctx_get_searchdirs(NULL));
+    CHECK_LOG("Invalid argument ctx (ly_ctx_get_searchdirs()).", NULL);
+    assert_int_equal(LY_EINVAL, ly_ctx_unset_searchdir(NULL, NULL));
+    CHECK_LOG("Invalid argument ctx (ly_ctx_unset_searchdir()).", NULL);
+
+    /* correct path */
+    assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, path1));
+    assert_int_equal(1, UTEST_LYCTX->search_paths.count);
+    assert_string_equal(path1, UTEST_LYCTX->search_paths.objs[0]);
+
+    /* duplicated paths */
+    assert_int_equal(LY_EEXIST, ly_ctx_set_searchdir(UTEST_LYCTX, path1));
+    assert_int_equal(1, UTEST_LYCTX->search_paths.count);
+    assert_string_equal(path1, UTEST_LYCTX->search_paths.objs[0]);
+
+    /* another path */
+    assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, path2));
+    assert_int_equal(2, UTEST_LYCTX->search_paths.count);
+    assert_string_equal(path2, UTEST_LYCTX->search_paths.objs[1]);
+
+    /* get searchpaths */
+    list = ly_ctx_get_searchdirs(UTEST_LYCTX);
+    assert_non_null(list);
+    assert_string_equal(path1, list[0]);
+    assert_string_equal(path2, list[1]);
+    assert_null(list[2]);
+
+    /* removing searchpaths */
+    /* nonexisting */
+    assert_int_equal(LY_EINVAL, ly_ctx_unset_searchdir(UTEST_LYCTX, "/nonexistingfile"));
+    CHECK_LOG_CTX("Invalid argument value (ly_ctx_unset_searchdir()).", NULL);
+
+    /* first */
+    assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, path1));
+    assert_int_equal(1, UTEST_LYCTX->search_paths.count);
+    assert_string_not_equal(path1, list[0]);
+
+    /* second */
+    assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, path2));
+    assert_int_equal(0, UTEST_LYCTX->search_paths.count);
+
+    free(path1);
+    free(path2);
+}
+
+#else
+
 static void
 test_searchdirs(void **state)
 {
@@ -112,6 +180,8 @@
     assert_string_equal(TESTS_BIN, UTEST_LYCTX->search_paths.objs[1]);
 }
 
+#endif
+
 static void
 test_options(void **state)
 {