schema helpers CHANGE added LYS_MOD_IMPORTED_REV

The new ::lys_get_module_without_revision() modifies the behavior of
the ::lys_parse_load() when a module is imported without specifying a
revision. Such an imported module is marked with the
::LYS_MOD_IMPORTED_REV flag and its priority is the highest. Also, the
implemented module takes precedence over the module with the latest
revision.
diff --git a/tests/utests/basic/test_context.c b/tests/utests/basic/test_context.c
index ce262ff..000c187 100644
--- a/tests/utests/basic/test_context.c
+++ b/tests/utests/basic/test_context.c
@@ -302,15 +302,17 @@
 static void
 test_imports(void **state)
 {
-    struct lys_module *mod1, *mod2, *import;
+    struct lys_module *mod1, *mod2, *mod3, *import;
     char *str;
+    uint16_t ctx_options;
 
     /* use own context with extra flags */
     ly_ctx_destroy(UTEST_LYCTX);
+    ctx_options = LY_CTX_DISABLE_SEARCHDIRS | LY_CTX_NO_YANGLIBRARY;
 
-    /* import callback provides newer revision of module 'a' than present in context, so when importing 'a', the newer revision
-     * from the callback should be loaded into the context and used as an import */
-    assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &UTEST_LYCTX));
+    /* Import callback provides newer revision of module 'a',
+     * however the older revision is implemented soon and therefore it is preferred. */
+    assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, ctx_options, &UTEST_LYCTX));
     ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "module a {namespace urn:a; prefix a; revision 2019-09-17;}");
     assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module a {namespace urn:a;prefix a;revision 2019-09-16;}",
             LYS_IN_YANG, &mod1));
@@ -318,35 +320,42 @@
     assert_int_equal(1, mod1->implemented);
     assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module b {namespace urn:b;prefix b;import a {prefix a;}}",
             LYS_IN_YANG, &mod2));
-    import = mod2->parsed->imports[0].module;
-    assert_true(LYS_MOD_LATEST_SEARCHDIRS & import->latest_revision);
-    assert_int_equal(0, mod1->latest_revision);
-    assert_ptr_not_equal(mod1, import);
-    assert_string_equal("2019-09-17", import->revision);
-    assert_int_equal(0, import->implemented);
+    assert_ptr_equal(mod1, mod2->parsed->imports[0].module);
+    assert_true((LYS_MOD_LATEST_REV | LYS_MOD_IMPORTED_REV) & mod1->latest_revision);
+    assert_string_equal("2019-09-16", mod1->revision);
+    assert_int_equal(1, mod1->implemented);
     assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "a", "2019-09-16"));
     ly_ctx_destroy(UTEST_LYCTX);
 
-    /* import callback provides older revision of module 'a' than present in context, so when importing a, the newer revision
-     * already present in the context should be selected and the callback's revision should not be loaded into the context */
-    assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &UTEST_LYCTX));
-    ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "module a {namespace urn:a; prefix a; revision 2019-09-17;}");
-    assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module a {namespace urn:a;prefix a;revision 2019-09-18;}",
-            LYS_IN_YANG, &mod1));
-    assert_true(LYS_MOD_LATEST_REV & mod1->latest_revision);
-    assert_int_equal(1, mod1->implemented);
+    /* Import callback provides older revision of module 'a' and it is
+     * imported by another module, so it is preferred even if newer
+     * revision is implemented later. */
+    assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, ctx_options, &UTEST_LYCTX));
+    ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "module a {namespace urn:a; prefix a; revision 2019-09-16;}");
     assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module b {namespace urn:b;prefix b;import a {prefix a;}}",
             LYS_IN_YANG, &mod2));
+    assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module a {namespace urn:a;prefix a;revision 2019-09-17;}",
+            LYS_IN_YANG, &mod1));
+    ly_log_level(LY_LLVRB);
+    assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module c {namespace urn:c;prefix c;import a {prefix a;}}",
+            LYS_IN_YANG, &mod3));
+    CHECK_LOG("Implemented module \"a@2019-09-17\" is not used for import, revision \"2019-09-16\" is imported instead.", NULL);
+    ly_log_level(LY_LLWRN);
+    assert_true(LYS_MOD_LATEST_SEARCHDIRS & mod1->latest_revision);
+    assert_int_equal(1, mod1->implemented);
     import = mod2->parsed->imports[0].module;
-    assert_ptr_equal(mod1, import);
-    assert_true(LYS_MOD_LATEST_SEARCHDIRS & import->latest_revision);
-    assert_int_equal(1, import->implemented);
-    assert_string_equal("2019-09-18", import->revision);
-    assert_null(ly_ctx_get_module(UTEST_LYCTX, "a", "2019-09-17"));
+    assert_true(LYS_MOD_IMPORTED_REV & import->latest_revision);
+    assert_string_equal("2019-09-16", import->revision);
+    assert_int_equal(0, import->implemented);
+    import = mod3->parsed->imports[0].module;
+    assert_string_equal("2019-09-16", import->revision);
+    assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "a", "2019-09-16"));
+    assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "a", "2019-09-17"));
+    assert_string_equal("2019-09-17", ly_ctx_get_module_implemented(UTEST_LYCTX, "a")->revision);
     ly_ctx_destroy(UTEST_LYCTX);
 
     /* check of circular dependency */
-    assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS | LY_CTX_NO_YANGLIBRARY, &UTEST_LYCTX));
+    assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, ctx_options, &UTEST_LYCTX));
     str = "module a {namespace urn:a; prefix a;"
             "import b {prefix b;}"
             "}";