diff --git a/tests/dname.c b/tests/dname.c
index 4d8910e4bd0f7819d535d2521992650c69467d05..154fd51c938fc6513e6aa7d00f48f9e9b8387988 100644
--- a/tests/dname.c
+++ b/tests/dname.c
@@ -14,6 +14,7 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <stdlib.h>
 #include <tap/basic.h>
 
 #include "libknot/dname.h"
@@ -24,73 +25,317 @@ static int test_fw(size_t l, const char *w) {
 	return knot_dname_wire_check((const uint8_t *)w, np, NULL) > 0;
 }
 
+/* Test dname to/from string operations */
+static void test_str(const char *in_str, const char *in_bin, size_t bin_len) {
+	uint8_t      d1[KNOT_DNAME_MAXLEN] = "";
+	char         s1[4 * KNOT_DNAME_MAXLEN] = "";
+	knot_dname_t *d2 = NULL, *aux_d = NULL;
+	char         *s2 = NULL, *aux_s = NULL;
+	int          ret = 0;
+
+	/* dname_from_str */
+	aux_d = knot_dname_from_str(d1, in_str, sizeof(d1));
+	ok(aux_d != NULL, "dname_from_str: %s", in_str);
+	if (aux_d == NULL) {
+		skip_block(10, "dname_from_str: %s", in_str);
+		return;
+	}
+
+	/* dname_wire_check */
+	ret = knot_dname_wire_check(d1, d1 + sizeof(d1), NULL);
+	ok(ret == bin_len, "dname_wire_check: %s", in_str);
+
+	/* dname compare */
+	ok(memcmp(d1, in_bin, bin_len) == 0, "dname compare: %s", in_str);
+
+	/* dname_to_str */
+	aux_s = knot_dname_to_str(s1, d1, sizeof(s1));
+	ok(aux_s != NULL, "dname_to_str: %s", in_str);
+	if (aux_s == NULL) {
+		skip_block(7, "dname_to_str: %s", in_str);
+		return;
+	}
+
+	/* dname_from_str_alloc */
+	d2 = knot_dname_from_str_alloc(s1);
+	ok(d2 != NULL, "dname_from_str_alloc: %s", s1);
+	if (d2 == NULL) {
+		skip_block(6, "dname_from_str_alloc: %s", s1);
+		return;
+	}
+
+	/* dname_wire_check */
+	ret = knot_dname_wire_check(d2, d2 + bin_len, NULL);
+	ok(ret == bin_len, "dname_wire_check: %s", s1);
+
+	/* dname compare */
+	ok(memcmp(d2, in_bin, bin_len) == 0, "dname compare: %s", s1);
+
+	/* dname_to_str_alloc */
+	s2 = knot_dname_to_str_alloc(d2);
+	knot_dname_free(&d2, NULL);
+	ok(s2 != NULL, "dname_to_str_alloc: %s", s1);
+	if (s2 == NULL) {
+		skip_block(3, "dname_to_str_alloc: %s", s1);
+		return;
+	}
+
+	/* As the string representation is ambiguous, the following steps
+	 * are just for comparison in wire form.
+	 */
+	d2 = knot_dname_from_str_alloc(s2);
+	ok(d2 != NULL, "dname_from_str_alloc: %s", s2);
+	if (aux_d == NULL) {
+		skip_block(2, "dname_from_str_alloc: %s", s2);
+		free(s2);
+		return;
+	}
+
+	/* dname_wire_check */
+	ret = knot_dname_wire_check(d2, d2 + bin_len, NULL);
+	ok(ret == bin_len, "dname_wire_check: %s", s2);
+
+	/* dname compare */
+	ok(memcmp(d2, in_bin, bin_len) == 0, "dname compare: %s", s2);
+
+	knot_dname_free(&d2, NULL);
+	free(s2);
+}
+
 int main(int argc, char *argv[])
 {
-	plan(29);
- 
+	plan(269);
+
 	knot_dname_t *d = NULL, *d2 = NULL;
 	const char *w = NULL, *t = NULL;
 	unsigned len = 0;
 	size_t pos = 0;
 
-	/* 1. NULL wire */
+	/* DNAME WIRE CHECKS */
+
+	/* NULL wire */
 	ok(!test_fw(0, NULL), "parsing NULL dname");
 
-	/* 2. empty label */
+	/* empty label */
 	ok(test_fw(1, ""), "parsing empty dname");
 
-	/* 3. incomplete dname */
+	/* incomplete dname */
 	ok(!test_fw(5, "\x08""dddd"), "parsing incomplete wire");
 
-	/* 4. non-fqdn */
+	/* non-fqdn */
 	ok(!test_fw(3, "\x02""ab"), "parsing non-fqdn name");
 
-	/* 5. label > 63b */
+	/* label length == 63 */
+	w = "\x3f""ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";
+	ok(test_fw(1 + 63 + 1, w), "parsing label length == 63");
+
+	/* label length > 63 */
 	w = "\x40""dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";
-	ok(!test_fw(65, w), "parsing label > 63b");
+	ok(!test_fw(1 + 64 + 1, w), "parsing label length > 63");
 
-	/* 6. label count == 126 */
-	w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64";
-	ok(test_fw(253, w), "parsing label count == 127");
+	/* label count == 127 (also maximal dname length) */
+	w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64";
+	ok(test_fw(127 * 2 + 1, w), "parsing label count == 127");
 
-	/* 7. label count == 127 */
-	w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64";
-	ok(test_fw(255, w), "parsing label count == 127");
+	/* label count > 127 */
+	w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64";
+	ok(!test_fw(128 * 2 + 1, w), "parsing label count > 127");
 
-	/* 8. label count > 127 */
-	w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64";
-	ok(!test_fw(257, w), "parsing label count > 127");
+	/* dname length > 255 */
+	w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"
+	    "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x02\x64\x64";
+	ok(!test_fw(126 * 2 + 3 + 1, w), "parsing dname len > 255");
 
-	/* 9. dname length > 255 */
-	w = "\xff""ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";
-	ok(!test_fw(257, w), "parsing dname len > 255");
+	/* DNAME STRING CHECKS */
 
-	/* 10. special case - invalid label */
-	w = "\x20\x68\x6d\x6e\x63\x62\x67\x61\x61\x61\x61\x65\x72\x6b\x30\x30\x30\x30\x64\x6c\x61\x61\x61\x61\x61\x61\x61\x61\x62\x65\x6a\x61\x6d\x20\x67\x6e\x69\x64\x68\x62\x61\x61\x61\x61\x65\x6c\x64\x30\x30\x30\x30\x64\x6c\x61\x61\x61\x61\x61\x61\x61\x61\x62\x65\x6a\x61\x6d\x20\x61\x63\x6f\x63\x64\x62\x61\x61\x61\x61\x65\x6b\x72\x30\x30\x30\x30\x64\x6c\x61\x61\x61\x61\x61\x61\x61\x61\x62\x65\x6a\x61\x6d\x20\x69\x62\x63\x6d\x6a\x6f\x61\x61\x61\x61\x65\x72\x6a\x30\x30\x30\x30\x64\x6c\x61\x61\x61\x61\x61\x61\x61\x61\x62\x65\x6a\x61\x6d\x20\x6f\x6c\x6e\x6c\x67\x68\x61\x61\x61\x61\x65\x73\x72\x30\x30\x30\x30\x64\x6c\x61\x61\x61\x61\x61\x61\x61\x61\x62\x65\x6a\x61\x6d\x20\x6a\x6b\x64\x66\x66\x67\x61\x61\x61\x61\x65\x6c\x68\x30\x30\x30\x30\x64\x6c\x61\x61\x61\x61\x61\x61\x61\x61\x62\x65\x6a\x61\x6d\x20\x67\x67\x6c\x70\x70\x61\x61\x61\x61\x61\x65\x73\x72\x30\x30\x30\x30\x64\x6c\x61\x61\x61\x61\x61\x61\x61\x61\x62\x65\x6a\x61\x6d\x20\x65\x6b\x6c\x67\x70\x66\x61\x61\x61\x61\x65\x6c\x68\x30\x30\x30\x30\x64\x6c\x61\x61\x61\x61\x61\x0\x21\x42\x63\x84\xa5\xc6\xe7\x8\xa\xd\x11\x73\x3\x6e\x69\x63\x2\x43\x5a";
-	ok(!test_fw(277, w), "parsing invalid label (spec. case 1)");
+	/* root dname */
+	test_str(".", "\x00", 1);
 
-	/* 11. parse from string (correct) .*/
-	len = 10;
-	w = "\x04""abcd""\x03""efg";
-	t = "abcd.efg";
-	d = knot_dname_from_str_alloc(t);
-	ok(d && knot_dname_size(d) == len && memcmp(d, w, len) == 0,
-	   "dname_fromstr: parsed correct non-FQDN name");
-	knot_dname_free(&d, NULL);
+	/* 1-char dname */
+	test_str("a.", "\x01""a", 2 + 1);
+
+	/* 1-char dname - non-fqdn */
+	test_str("a", "\x01""a", 2 + 1);
+
+	/* wildcard and asterisks */
+	test_str("*.*a.a*a.**.",
+	         "\x01" "*" "\x02" "*a" "\x03" "a*a" "\x02" "**",
+	         2 + 3 + 4 + 3 + 1);
+
+	/* special label */
+	test_str("\\000\\0320\\ \\\\\\\"\\.\\@\\*.",
+	         "\x09" "\x00\x20\x30\x20\x5c\x22.@*",
+	         10 + 1);
+
+	/* unescaped special characters */
+	test_str("_a.b-c./d.",
+	         "\x02" "_a" "\x03" "b-c" "\x02" "/d",
+	         3 + 4 + 3 + 1);
+
+	/* all possible characters */
+	test_str("\\000\\001\\002\\003\\004\\005\\006\\007\\008\\009\\010\\011\\012\\013\\014\\015\\016\\017\\018\\019",
+	         "\x14" "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13",
+	         22);
+	test_str("\\020\\021\\022\\023\\024\\025\\026\\027\\028\\029\\030\\031\\032\\033\\034\\035\\036\\037\\038\\039",
+	         "\x14" "\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27",
+	         22);
+	test_str("\\040\\041\\042\\043\\044\\045\\046\\047\\048\\049\\050\\051\\052\\053\\054\\055\\056\\057\\058\\059",
+	         "\x14" "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b",
+	         22);
+	test_str("\\060\\061\\062\\063\\064\\065\\066\\067\\068\\069\\070\\071\\072\\073\\074\\075\\076\\077\\078\\079",
+	         "\x14" "\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f",
+	         22);
+	test_str("\\080\\081\\082\\083\\084\\085\\086\\087\\088\\089\\090\\091\\092\\093\\094\\095\\096\\097\\098\\099",
+	         "\x14" "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63",
+	         22);
+	test_str("\\100\\101\\102\\103\\104\\105\\106\\107\\108\\109\\110\\111\\112\\113\\114\\115\\116\\117\\118\\119",
+	         "\x14" "\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77",
+	         22);
+	test_str("\\120\\121\\122\\123\\124\\125\\126\\127\\128\\129\\130\\131\\132\\133\\134\\135\\136\\137\\138\\139",
+	         "\x14" "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b",
+	         22);
+	test_str("\\140\\141\\142\\143\\144\\145\\146\\147\\148\\149\\150\\151\\152\\153\\154\\155\\156\\157\\158\\159",
+	         "\x14" "\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f",
+	         22);
+	test_str("\\160\\161\\162\\163\\164\\165\\166\\167\\168\\169\\170\\171\\172\\173\\174\\175\\176\\177\\178\\179",
+	         "\x14" "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3",
+	         22);
+	test_str("\\180\\181\\182\\183\\184\\185\\186\\187\\188\\189\\190\\191\\192\\193\\194\\195\\196\\197\\198\\199",
+	         "\x14" "\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7",
+	         22);
+	test_str("\\200\\201\\202\\203\\204\\205\\206\\207\\208\\209\\210\\211\\212\\213\\214\\215\\216\\217\\218\\219",
+	         "\x14" "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb",
+	         22);
+	test_str("\\220\\221\\222\\223\\224\\225\\226\\227\\228\\229\\230\\231\\232\\233\\234\\235\\236\\237\\238\\239",
+	         "\x14" "\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef",
+	         22);
+	test_str("\\240\\241\\242\\243\\244\\245\\246\\247\\248\\249\\250\\251\\252\\253\\254\\255",
+	         "\x10" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+	         18);
+
+	/* maximal dname label length */
+	test_str("12345678901234567890123456789012345678901234567890123456789012\\063",
+		 "\x3f" "12345678901234567890123456789012345678901234567890123456789012?",
+		 65);
+
+	/* maximal dname length */
+	test_str("1234567890123456789012345678901234567890123456789."
+	         "1234567890123456789012345678901234567890123456789."
+	         "1234567890123456789012345678901234567890123456789."
+	         "1234567890123456789012345678901234567890123456789."
+	         "\\#234567890123456789012345678901234567890123456789012\\063",
+	         "\x31" "1234567890123456789012345678901234567890123456789"
+	         "\x31" "1234567890123456789012345678901234567890123456789"
+	         "\x31" "1234567890123456789012345678901234567890123456789"
+	         "\x31" "1234567890123456789012345678901234567890123456789"
+	         "\x35" "#234567890123456789012345678901234567890123456789012?",
+	         255);
 
-	/* 12. parse FQDN from string (correct) .*/
-	t = "abcd.efg.";
+	/* NULL dname */
+	char *s = knot_dname_to_str_alloc(NULL);
+	ok(s == NULL, "dname_to_str: null dname");
+
+	/* empty dname is considered as a root dname */
+	w = "";
+	s = knot_dname_to_str_alloc((const uint8_t *)w);
+	ok(s != NULL, "dname_to_str: empty dname");
+	if (s != NULL) {
+		ok(memcmp(s, ".", 1) == 0, "dname_to_str: empty dname is root dname");
+		free(s);
+	} else {
+		skip("dname_to_str: empty dname");
+	}
+
+	/* NULL string */
+	d = knot_dname_from_str_alloc(NULL);
+	ok(d == NULL, "dname_from_str: null string");
+
+	/* empty string */
+	t = "";
 	d = knot_dname_from_str_alloc(t);
-	ok(d && knot_dname_size(d) == len && memcmp(d, w, len) == 0,
-	   "dname_fromstr: parsed correct FQDN name");
-	knot_dname_free(&d, NULL);
+	ok(d == NULL, "dname_from_str: empty string");
 
-	/* 13. parse name from string (incorrect) .*/
+	/* empty label */
 	t = "..";
 	d = knot_dname_from_str_alloc(t);
-	ok(d == NULL, "dname_fromstr: parsed incorrect name");
+	ok(d == NULL, "dname_from_str: empty label");
+
+	/* leading dot */
+	t = ".a";
+	d = knot_dname_from_str_alloc(t);
+	ok(d == NULL, "dname_from_str: leading dot");
+
+	/* incomplete decimal notation I */
+	t = "\\1";
+	d = knot_dname_from_str_alloc(t);
+	ok(d == NULL, "dname_from_str: incomplete decimal I");
+
+	/* incomplete decimal notation II */
+	t = "\\12";
+	d = knot_dname_from_str_alloc(t);
+	ok(d == NULL, "dname_from_str: incomplete decimal II");
+
+	/* label length > 63 I */
+	t = "1234567890123456789012345678901234567890123456789012345678901234";
+	d = knot_dname_from_str_alloc(t);
+	ok(d == NULL, "dname_from_str: label length > 63 I");
+
+	/* label length > 63 II */
+	t = "123456789012345678901234567890123456789012345678901234567890123\\?";
+	d = knot_dname_from_str_alloc(t);
+	ok(d == NULL, "dname_from_str: label length > 63 II");
 
-	/* 14. equal name is subdomain */
+	/* label length > 63 III */
+	t = "123456789012345678901234567890123456789012345678901234567890123\\063";
+	d = knot_dname_from_str_alloc(t);
+	ok(d == NULL, "dname_from_str: label length > 63 III");
+
+	/* dname label length > 255 */
+	t = "1234567890123456789012345678901234567890123456789."
+	    "1234567890123456789012345678901234567890123456789."
+	    "1234567890123456789012345678901234567890123456789."
+	    "1234567890123456789012345678901234567890123456789."
+	    "123456789012345678901234567890123456789012345678901234.",
+	ok(d == NULL, "dname_from_str: dname label length > 255");
+
+	/* DNAME SUBDOMAIN CHECKS */
+
+	/* equal name is subdomain */
 	t = "ab.cd.ef";
 	d2 = knot_dname_from_str_alloc(t);
 	t = "ab.cd.ef";
@@ -98,26 +343,28 @@ int main(int argc, char *argv[])
 	ok(!knot_dname_is_sub(d, d2), "dname_subdomain: equal name");
 	knot_dname_free(&d, NULL);
 
-	/* 15. true subdomain */
+	/* true subdomain */
 	t = "0.ab.cd.ef";
 	d = knot_dname_from_str_alloc(t);
 	ok(knot_dname_is_sub(d, d2), "dname_subdomain: true subdomain");
 	knot_dname_free(&d, NULL);
 
-	/* 16. not subdomain */
+	/* not subdomain */
 	t = "cd.ef";
 	d = knot_dname_from_str_alloc(t);
 	ok(!knot_dname_is_sub(d, d2), "dname_subdomain: not subdomain");
 	knot_dname_free(&d, NULL);
 
-	/* 17. root subdomain */
+	/* root subdomain */
 	t = ".";
 	d = knot_dname_from_str_alloc(t);
 	ok(knot_dname_is_sub(d2, d), "dname_subdomain: root subdomain");
 	knot_dname_free(&d, NULL);
 	knot_dname_free(&d2, NULL);
 
-	/* 18-19. dname cat (valid) */
+	/* DNAME CAT CHECKS */
+
+	/* dname cat (valid) */
 	w = "\x03""cat";
 	d = knot_dname_copy((const uint8_t *)w, NULL);
 	t = "*";
@@ -130,7 +377,9 @@ int main(int argc, char *argv[])
 	knot_dname_free(&d, NULL);
 	knot_dname_free(&d2, NULL);
 
-	/* 20-21. parse from wire (valid) */
+	/* DNAME PARSE CHECKS */
+
+	/* parse from wire (valid) */
 	t = "\x04""abcd""\x03""efg";
 	len = 10;
 	pos = 0;
@@ -139,7 +388,7 @@ int main(int argc, char *argv[])
 	ok(pos == len, "dname_parse: valid name (parsed length)");
 	knot_dname_free(&d, NULL);
 
-	/* 22-23. parse from wire (invalid) */
+	/* parse from wire (invalid) */
 	t = "\x08""dddd";
 	len = 5;
 	pos = 0;
@@ -147,30 +396,38 @@ int main(int argc, char *argv[])
 	ok(d == NULL, "dname_parse: bad name");
 	ok(pos == 0, "dname_parse: bad name (parsed length)");
 
-	/* name equality checks */
+	/* DNAME EQUALITY CHECKS */
+
 	t = "ab.cd.ef";
 	d = knot_dname_from_str_alloc(t);
 	ok(knot_dname_is_equal(d, d), "dname_is_equal: equal names");
+
 	t = "ab.cd.fe";
 	d2 = knot_dname_from_str_alloc(t);
 	ok(!knot_dname_is_equal(d, d2), "dname_is_equal: same label count");
 	knot_dname_free(&d2, NULL);
+
 	t = "ab.cd";
 	d2 = knot_dname_from_str_alloc(t);
 	ok(!knot_dname_is_equal(d, d2), "dname_is_equal: len(d1) < len(d2)");
 	knot_dname_free(&d2, NULL);
+
 	t = "ab.cd.ef.gh";
 	d2 = knot_dname_from_str_alloc(t);
 	ok(!knot_dname_is_equal(d, d2), "dname_is_equal: len(d1) > len(d2)");
 	knot_dname_free(&d2, NULL);
+
 	t = "ab.cd.efe";
 	d2 = knot_dname_from_str_alloc(t);
 	ok(!knot_dname_is_equal(d, d2), "dname_is_equal: last label longer");
 	knot_dname_free(&d2, NULL);
+
 	t = "ab.cd.e";
 	d2 = knot_dname_from_str_alloc(t);
 	ok(!knot_dname_is_equal(d, d2), "dname_is_equal: last label shorter");
 	knot_dname_free(&d2, NULL);
 
+	knot_dname_free(&d, NULL);
+
 	return 0;
 }