# Coverage This file is just a collection of unit tests not covered elsewhere. Most notably regression tests, tests improving code coverage and other useful things may drop here. (However any tests requiring any additional command line option, like enabling an extension, must be included in their respective files.) ## GitHub Issues ### [Issue 2](https://github.com/mity/md4c/issues/2) Raw HTML block: ```````````````````````````````` example . ```````````````````````````````` Inline: ```````````````````````````````` example foo bar .

foo bar

```````````````````````````````` Inline with a line break: ```````````````````````````````` example foo bar .

foo bar

```````````````````````````````` ### [Issue 4](https://github.com/mity/md4c/issues/4) ```````````````````````````````` example ![alt text with *entity* ©](img.png 'title') .

alt text with entity ©

```````````````````````````````` ### [Issue 9](https://github.com/mity/md4c/issues/9) ```````````````````````````````` example > [foo > bar]: /url > > [foo bar] .

foo bar

```````````````````````````````` ### [Issue 10](https://github.com/mity/md4c/issues/10) ```````````````````````````````` example [x]: x -
  • ```````````````````````````````` ### [Issue 11](https://github.com/mity/md4c/issues/11) ```````````````````````````````` example x [link](/url "foo – bar") x .

    x link x

    ```````````````````````````````` ### [Issue 14](https://github.com/mity/md4c/issues/14) ```````````````````````````````` example a***b* c* .

    a*b c

    ```````````````````````````````` ### [Issue 15](https://github.com/mity/md4c/issues/15) ```````````````````````````````` example ***b* c* .

    *b c

    ```````````````````````````````` ### [Issue 21](https://github.com/mity/md4c/issues/21) ```````````````````````````````` example a*b**c* .

    ab**c

    ```````````````````````````````` ### [Issue 33](https://github.com/mity/md4c/issues/33) ```````````````````````````````` example ```&&&&&&&& .
    ```````````````````````````````` ### [Issue 36](https://github.com/mity/md4c/issues/36) ```````````````````````````````` example __x_ _x___ .

    x x_

    ```````````````````````````````` ### [Issue 39](https://github.com/mity/md4c/issues/39) ```````````````````````````````` example [\\]: x . ```````````````````````````````` ### [Issue 40](https://github.com/mity/md4c/issues/40) ```````````````````````````````` example [x](url 'title' )x .

    xx

    ```````````````````````````````` ### [Issue 65](https://github.com/mity/md4c/issues/65) ```````````````````````````````` example ` .

    `

    ```````````````````````````````` ### [Issue 74](https://github.com/mity/md4c/issues/74) ```````````````````````````````` example [f]: - xx - .
    xx
    
    ```````````````````````````````` ### [Issue 78](https://github.com/mity/md4c/issues/78) ```````````````````````````````` example [SS ẞ]: /url [ẞ SS] .

    ẞ SS

    ```````````````````````````````` ### [Issue 83](https://github.com/mity/md4c/issues/83) ```````````````````````````````` example foo > .

    foo

    ```````````````````````````````` ### [Issue 95](https://github.com/mity/md4c/issues/95) ```````````````````````````````` example . foo .

    . foo

    ```````````````````````````````` ### [Issue 96](https://github.com/mity/md4c/issues/96) ```````````````````````````````` example [ab]: /foo [a] [ab] [abc] .

    [a] ab [abc]

    ```````````````````````````````` ```````````````````````````````` example [a b]: /foo [a b] .

    a b

    ```````````````````````````````` ### [Issue 97](https://github.com/mity/md4c/issues/97) ```````````````````````````````` example *a **b c* d** .

    a b c d

    ```````````````````````````````` ### [Issue 100](https://github.com/mity/md4c/issues/100) ```````````````````````````````` example .

    foo@123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123

    ```````````````````````````````` ```````````````````````````````` example .

    <foo@123456789012345678901234567890123456789012345678901234567890123x.123456789012345678901234567890123456789012345678901234567890123>

    ```````````````````````````````` (Note the `x` here which turns it over the max. allowed length limit.) ### [Issue 107](https://github.com/mity/md4c/issues/107) ```````````````````````````````` example ***foo *bar baz*** .

    *foo bar baz

    ```````````````````````````````` ### [Issue 124](https://github.com/mity/md4c/issues/124) ```````````````````````````````` example ~~~ x ~~~ ~~~ x ~~~ .
                    x
    
                     x
    
    ```````````````````````````````` ### [Issue 131](https://github.com/mity/md4c/issues/131) ```````````````````````````````` example [![alt][img]][link] [img]: img_url [link]: link_url .

    alt

    ```````````````````````````````` ### [Issue 142](https://github.com/mity/md4c/issues/142) ```````````````````````````````` example [fooﬗ]: /url [fooﬕ] .

    [fooﬕ]

    ```````````````````````````````` ### [Issue 149](https://github.com/mity/md4c/issues/149) ```````````````````````````````` example - .
    ```````````````````````````````` ## Code coverage ### `md_is_unicode_whitespace__()` Unicode whitespace (here U+2000) forms a word boundary so these cannot be resolved as emphasis span because there is no closer mark. ```````````````````````````````` example *foo *bar .

    *foo *bar

    ```````````````````````````````` ### `md_is_unicode_punct__()` Ditto for Unicode punctuation (here U+00A1). ```````````````````````````````` example *foo¡*bar .

    *foo¡*bar

    ```````````````````````````````` ### `md_get_unicode_fold_info()` ```````````````````````````````` example [Příliš žluťoučký kůň úpěl ďábelské ódy.] [PŘÍLIŠ ŽLUŤOUČKÝ KŮŇ ÚPĚL ĎÁBELSKÉ ÓDY.]: /url .

    Příliš žluťoučký kůň úpěl ďábelské ódy.

    ```````````````````````````````` ### `md_decode_utf8__()` and `md_decode_utf8_before__()` ```````````````````````````````` example á*Á (U+00E1, i.e. two byte UTF-8 sequence)  *  (U+2000, i.e. three byte UTF-8 sequence) .

    á*Á (U+00E1, i.e. two byte UTF-8 sequence) * (U+2000, i.e. three byte UTF-8 sequence)

    ```````````````````````````````` ### `md_is_link_destination_A()` ```````````````````````````````` example [link]() .

    link

    ```````````````````````````````` ### `md_link_label_eq()` ```````````````````````````````` example [foo bar] [foo bar]: /url .

    foo bar

    ```````````````````````````````` ### `md_is_inline_link_spec()` ```````````````````````````````` example > [link](/url 'foo > bar') .

    link

    ```````````````````````````````` ### `md_build_ref_def_hashtable()` All link labels in the following example all have the same FNV1a hash (after normalization of the label, which means after converting to a vector of Unicode codepoints and lowercase folding). So the example triggers quite complex code paths which are not otherwise easily tested. ```````````````````````````````` example [foo]: /foo [qnptgbh]: /qnptgbh [abgbrwcv]: /abgbrwcv [abgbrwcv]: /abgbrwcv2 [abgbrwcv]: /abgbrwcv3 [abgbrwcv]: /abgbrwcv4 [alqadfgn]: /alqadfgn [foo] [qnptgbh] [abgbrwcv] [alqadfgn] [axgydtdu] .

    foo qnptgbh abgbrwcv alqadfgn [axgydtdu]

    ```````````````````````````````` For the sake of completeness, the following C program was used to find the hash collisions by brute force: ~~~ #include #include static unsigned etalon; #define MD_FNV1A_BASE 2166136261 #define MD_FNV1A_PRIME 16777619 static inline unsigned fnv1a(unsigned base, const void* data, size_t n) { const unsigned char* buf = (const unsigned char*) data; unsigned hash = base; size_t i; for(i = 0; i < n; i++) { hash ^= buf[i]; hash *= MD_FNV1A_PRIME; } return hash; } static unsigned unicode_hash(const char* data, size_t n) { unsigned value; unsigned hash = MD_FNV1A_BASE; int i; for(i = 0; i < n; i++) { value = data[i]; hash = fnv1a(hash, &value, sizeof(unsigned)); } return hash; } static void recurse(char* buffer, size_t off, size_t len) { int ch; if(off < len - 1) { for(ch = 'a'; ch <= 'z'; ch++) { buffer[off] = ch; recurse(buffer, off+1, len); } } else { for(ch = 'a'; ch <= 'z'; ch++) { buffer[off] = ch; if(unicode_hash(buffer, len) == etalon) { printf("Dup: %.*s\n", (int)len, buffer); } } } } int main(int argc, char** argv) { char buffer[32]; int len; if(argc < 2) etalon = unicode_hash("foo", 3); else etalon = unicode_hash(argv[1], strlen(argv[1])); for(len = 1; len <= sizeof(buffer); len++) recurse(buffer, 0, len); return 0; } ~~~