Repository: rust-lang/annotate-snippets-rs
Pull request #86 (2024-03-02 23:31:15)

refactor(fixtures): Move to snapbox with SVGs
I was not happy with how fixtures were currently being run, as when one failed it would take down the whole thing failed, and it could not continue past the failed fixture test. To make this better I switched the fixture tests to use a custom test harness, built on top of [`snapbox::harness::Harness`](https://docs.rs/snapbox/latest/snapbox/harness/struct.Harness.html). This makes it so each test is run by itself so you can see exactly which test is failing. In doing this I also switched the expected output to be compared to SVGs, which makes seeing visual changes much easier, while still retaining the ability to see the text differences.


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 53b8e3c..034e18c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -26,28 +26,109 @@ dependencies = [
  "difference",
  "glob",
  "serde",
+ "snapbox",
  "toml",
  "unicode-width",
 ]
 
+[[package]]
+name = "anstream"
+version = "0.6.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "utf8parse",
+]
+
 [[package]]
 name = "anstyle"
 version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
 
+[[package]]
+name = "anstyle-lossy"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9a0444767dbd4aea9355cb47a370eb184dbfe918875e127eff52cb9d1638181"
+dependencies = [
+ "anstyle",
+]
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
+dependencies = [
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "anstyle-svg"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b6ddad447b448d6d5db36b31cbd3ff27c7af071619501998eeceab01968287a"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "anstyle-lossy",
+ "html-escape",
+ "unicode-width",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
+dependencies = [
+ "anstyle",
+ "windows-sys 0.52.0",
+]
+
 [[package]]
 name = "autocfg"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
 [[package]]
 name = "bitflags"
 version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
 
+[[package]]
+name = "bstr"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c"
+dependencies = [
+ "memchr",
+ "serde",
+]
+
 [[package]]
 name = "bumpalo"
 version = "3.14.0"
@@ -100,6 +181,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b"
 dependencies = [
  "clap_builder",
+ "clap_derive",
 ]
 
 [[package]]
@@ -108,8 +190,22 @@ version = "4.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663"
 dependencies = [
+ "anstream",
  "anstyle",
  "clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -118,6 +214,21 @@ version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
 
+[[package]]
+name = "colorchoice"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
+
+[[package]]
+name = "content_inspector"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38"
+dependencies = [
+ "memchr",
+]
+
 [[package]]
 name = "criterion"
 version = "0.5.1"
@@ -193,6 +304,12 @@ version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
 
+[[package]]
+name = "dunce"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b"
+
 [[package]]
 name = "either"
 version = "1.9.0"
@@ -201,12 +318,39 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
 
 [[package]]
 name = "errno"
-version = "0.3.6"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "escape8259"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba4f4911e3666fcd7826997b4745c8224295a6f3072f1418c3067b97a67557ee"
+dependencies = [
+ "rustversion",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
+
+[[package]]
+name = "filetime"
+version = "0.2.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e"
+checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
 dependencies = [
+ "cfg-if",
  "libc",
- "windows-sys",
+ "redox_syscall",
+ "windows-sys 0.52.0",
 ]
 
 [[package]]
@@ -215,18 +359,62 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
 
+[[package]]
+name = "globset"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1"
+dependencies = [
+ "aho-corasick",
+ "bstr",
+ "log",
+ "regex-automata",
+ "regex-syntax",
+]
+
 [[package]]
 name = "half"
 version = "1.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
 
+[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+
 [[package]]
 name = "hermit-abi"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
 
+[[package]]
+name = "html-escape"
+version = "0.2.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476"
+dependencies = [
+ "utf8-width",
+]
+
+[[package]]
+name = "ignore"
+version = "0.4.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1"
+dependencies = [
+ "crossbeam-deque",
+ "globset",
+ "log",
+ "memchr",
+ "regex-automata",
+ "same-file",
+ "walkdir",
+ "winapi-util",
+]
+
 [[package]]
 name = "is-terminal"
 version = "0.4.9"
@@ -235,7 +423,7 @@ checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
 dependencies = [
  "hermit-abi",
  "rustix",
- "windows-sys",
+ "windows-sys 0.48.0",
 ]
 
 [[package]]
@@ -264,15 +452,27 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.150"
+version = "0.2.153"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
+checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
+
+[[package]]
+name = "libtest-mimic"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f0f4c6f44ecfd52e8b443f2ad18f2b996540135771561283c2352ce56a1c70b"
+dependencies = [
+ "clap",
+ "escape8259",
+ "termcolor",
+ "threadpool",
+]
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.4.11"
+version = "0.4.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
+checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
 
 [[package]]
 name = "log"
@@ -295,6 +495,12 @@ dependencies = [
  "autocfg",
 ]
 
+[[package]]
+name = "normalize-line-endings"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
+
 [[package]]
 name = "num-traits"
 version = "0.2.17"
@@ -304,6 +510,16 @@ dependencies = [
  "autocfg",
 ]
 
+[[package]]
+name = "num_cpus"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
 [[package]]
 name = "once_cell"
 version = "1.18.0"
@@ -382,6 +598,15 @@ dependencies = [
  "crossbeam-utils",
 ]
 
+[[package]]
+name = "redox_syscall"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
 [[package]]
 name = "regex"
 version = "1.10.2"
@@ -413,17 +638,23 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
 
 [[package]]
 name = "rustix"
-version = "0.38.21"
+version = "0.38.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
+checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
 dependencies = [
- "bitflags",
+ "bitflags 2.4.1",
  "errno",
  "libc",
  "linux-raw-sys",
- "windows-sys",
+ "windows-sys 0.52.0",
 ]
 
+[[package]]
+name = "rustversion"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
+
 [[package]]
 name = "ryu"
 version = "1.0.15"
@@ -476,6 +707,49 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "similar"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21"
+
+[[package]]
+name = "snapbox"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6de4a00e16c1e859fbc29a6484c5aad30f18fb9f4c2c29033c28aef7e965b82e"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "anstyle-svg",
+ "content_inspector",
+ "dunce",
+ "filetime",
+ "ignore",
+ "libtest-mimic",
+ "normalize-line-endings",
+ "serde_json",
+ "similar",
+ "snapbox-macros",
+ "tempfile",
+ "walkdir",
+]
+
+[[package]]
+name = "snapbox-macros"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1c4b838b05d15ab22754068cb73500b2f3b07bf09d310e15b27f88160f1de40"
+dependencies = [
+ "anstream",
+]
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
 [[package]]
 name = "syn"
 version = "2.0.48"
@@ -487,6 +761,36 @@ dependencies = [
  "unicode-ident",
 ]
 
+[[package]]
+name = "tempfile"
+version = "3.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "rustix",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "threadpool"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
+dependencies = [
+ "num_cpus",
+]
+
 [[package]]
 name = "tinytemplate"
 version = "1.2.1"
@@ -518,6 +822,18 @@ version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
 
+[[package]]
+name = "utf8-width"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+
 [[package]]
 name = "walkdir"
 version = "2.4.0"
@@ -629,7 +945,16 @@ version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
 dependencies = [
- "windows-targets",
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets 0.52.4",
 ]
 
 [[package]]
@@ -638,13 +963,28 @@ version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
 dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.4",
+ "windows_aarch64_msvc 0.52.4",
+ "windows_i686_gnu 0.52.4",
+ "windows_i686_msvc 0.52.4",
+ "windows_x86_64_gnu 0.52.4",
+ "windows_x86_64_gnullvm 0.52.4",
+ "windows_x86_64_msvc 0.52.4",
 ]
 
 [[package]]
@@ -653,38 +993,80 @@ version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
 
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
+
 [[package]]
 name = "windows_aarch64_msvc"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
 
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
+
 [[package]]
 name = "windows_i686_gnu"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
 
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
+
 [[package]]
 name = "windows_i686_msvc"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
 
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
+
 [[package]]
 name = "windows_x86_64_gnu"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
 
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
+
 [[package]]
 name = "windows_x86_64_gnullvm"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
 
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
+
 [[package]]
 name = "windows_x86_64_msvc"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
diff --git a/Cargo.toml b/Cargo.toml
index 3f5bf82..8763c11 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -32,12 +32,17 @@ criterion = "0.5.1"
 difference = "2.0.0"
 glob = "0.3.1"
 serde = { version = "1.0.197", features = ["derive"] }
+snapbox = { version = "0.5.8", features = ["diff", "harness", "path", "term-svg"] }
 toml = "0.5.11"
 
 [[bench]]
 name = "simple"
 harness = false
 
+[[test]]
+name = "fixtures"
+harness = false
+
 [features]
 default = []
 testing-colors = []


Test patch:
diff --git a/tests/diff/mod.rs b/tests/diff/mod.rs
deleted file mode 100644
index 60ccae1..0000000
--- a/tests/diff/mod.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-use annotate_snippets::renderer::{AnsiColor, Color, Style};
-use difference::{Changeset, Difference};
-
-const GREEN: Style = AnsiColor::Green.on_default();
-pub fn get_diff(left: &str, right: &str) -> String {
-    let mut output = String::new();
-
-    let Changeset { diffs, .. } = Changeset::new(left, right, "\n");
-
-    for i in 0..diffs.len() {
-        match diffs[i] {
-            Difference::Same(ref x) => {
-                output += &format!(" {}\n", x);
-            }
-            Difference::Add(ref x) => {
-                match diffs[i - 1] {
-                    Difference::Rem(ref y) => {
-                        output += &format!("{}+{}", GREEN.render(), GREEN.render_reset());
-                        let Changeset { diffs, .. } = Changeset::new(y, x, " ");
-                        for c in diffs {
-                            match c {
-                                Difference::Same(ref z) => {
-                                    output += &format!(
-                                        "{}{}{} ",
-                                        GREEN.render(),
-                                        z.as_str(),
-                                        GREEN.render_reset()
-                                    );
-                                }
-                                Difference::Add(ref z) => {
-                                    let black_on_green = Style::new()
-                                        .bg_color(Some(Color::Ansi(AnsiColor::Green)))
-                                        .fg_color(Some(Color::Ansi(AnsiColor::Black)));
-                                    output += &format!(
-                                        "{}{}{} ",
-                                        black_on_green.render(),
-                                        z.as_str(),
-                                        black_on_green.render_reset()
-                                    );
-                                }
-                                _ => (),
-                            }
-                        }
-                        output += "\n";
-                    }
-                    _ => {
-                        output += &format!(
-                            "+{}{}{}\n",
-                            GREEN.render(),
-                            x.as_str(),
-                            GREEN.render_reset()
-                        );
-                    }
-                };
-            }
-            Difference::Rem(ref x) => {
-                let red = AnsiColor::Red.on_default();
-                output += &format!("-{}{}{}\n", red.render(), x.as_str(), red.render_reset());
-            }
-        }
-    }
-    output
-}
diff --git a/tests/deserialize/mod.rs b/tests/fixtures/deserialize.rs
similarity index 100%
rename from tests/deserialize/mod.rs
rename to tests/fixtures/deserialize.rs
diff --git a/tests/fixtures/main.rs b/tests/fixtures/main.rs
new file mode 100644
index 0000000..c320407
--- /dev/null
+++ b/tests/fixtures/main.rs
@@ -0,0 +1,33 @@
+mod deserialize;
+
+use crate::deserialize::Fixture;
+use annotate_snippets::{Renderer, Snippet};
+use snapbox::data::DataFormat;
+use snapbox::Data;
+use std::error::Error;
+
+fn main() {
+    #[cfg(not(windows))]
+    snapbox::harness::Harness::new("tests/fixtures/", setup, test)
+        .select(["*/*.toml"])
+        .action_env("SNAPSHOTS")
+        .test();
+}
+
+fn setup(input_path: std::path::PathBuf) -> snapbox::harness::Case {
+    let name = input_path.file_name().unwrap().to_str().unwrap().to_owned();
+    let expected = input_path.with_extension("svg");
+    snapbox::harness::Case {
+        name,
+        fixture: input_path,
+        expected,
+    }
+}
+
+fn test(input_path: &std::path::Path) -> Result<Data, Box<dyn Error>> {
+    let src = std::fs::read_to_string(input_path)?;
+    let (renderer, snippet): (Renderer, Snippet<'_>) =
+        toml::from_str(&src).map(|a: Fixture| (a.renderer.into(), a.snippet.into()))?;
+    let actual = renderer.render(snippet).to_string();
+    Ok(Data::from(actual).coerce_to(DataFormat::TermSvg))
+}
diff --git a/tests/fixtures/no-color/issue_52.svg b/tests/fixtures/no-color/issue_52.svg
new file mode 100644
index 0000000..5ed2228
--- /dev/null
+++ b/tests/fixtures/no-color/issue_52.svg
@@ -0,0 +1,35 @@
+<svg width="740px" height="146px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan>error</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan> --&gt; path/to/error.rs:3:1</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>  |</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan>...</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>3 | invalid syntax</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>  | -------------- error here</tspan>
+</tspan>
+    <tspan x="10px" y="136px"><tspan>  |</tspan>
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/fixtures/no-color/issue_52.txt b/tests/fixtures/no-color/issue_52.txt
deleted file mode 100644
index b1c6bf2..0000000
--- a/tests/fixtures/no-color/issue_52.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-error
- --> path/to/error.rs:3:1
-  |
-...
-3 | invalid syntax
-  | -------------- error here
-  |
\ No newline at end of file
diff --git a/tests/fixtures/no-color/issue_9.svg b/tests/fixtures/no-color/issue_9.svg
new file mode 100644
index 0000000..af22d82
--- /dev/null
+++ b/tests/fixtures/no-color/issue_9.svg
@@ -0,0 +1,45 @@
+<svg width="911px" height="236px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan>error: expected one of `.`, `;`, `?`, or an operator, found `for`</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan> --&gt; /code/rust/src/test/ui/annotate-snippet/suggestion.rs:4:5</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>  |</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan>4 | let x = vec![1];</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>  |     - move occurs because `x` has type `std::vec::Vec&lt;i32&gt;`, which does not implement the `Copy` trait</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>  |</tspan>
+</tspan>
+    <tspan x="10px" y="136px"><tspan>7 | let y = x;</tspan>
+</tspan>
+    <tspan x="10px" y="154px"><tspan>  |         - value moved here</tspan>
+</tspan>
+    <tspan x="10px" y="172px"><tspan>  |</tspan>
+</tspan>
+    <tspan x="10px" y="190px"><tspan>9 | x;</tspan>
+</tspan>
+    <tspan x="10px" y="208px"><tspan>  | ^ value used here after move</tspan>
+</tspan>
+    <tspan x="10px" y="226px"><tspan>  |</tspan>
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/fixtures/no-color/issue_9.txt b/tests/fixtures/no-color/issue_9.txt
deleted file mode 100644
index affe6bc..0000000
--- a/tests/fixtures/no-color/issue_9.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-error: expected one of `.`, `;`, `?`, or an operator, found `for`
- --> /code/rust/src/test/ui/annotate-snippet/suggestion.rs:4:5
-  |
-4 | let x = vec![1];
-  |     - move occurs because `x` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
-  |
-7 | let y = x;
-  |         - value moved here
-  |
-9 | x;
-  | ^ value used here after move
-  |
\ No newline at end of file
diff --git a/tests/fixtures/no-color/multiline_annotation.svg b/tests/fixtures/no-color/multiline_annotation.svg
new file mode 100644
index 0000000..5fa6e81
--- /dev/null
+++ b/tests/fixtures/no-color/multiline_annotation.svg
@@ -0,0 +1,49 @@
+<svg width="869px" height="272px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan>error[E0308]: mismatched types</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan>  --&gt; src/format.rs:51:6</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>   |</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan>51 |   ) -&gt; Option&lt;String&gt; {</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>   |        -------------- expected `std::option::Option&lt;std::string::String&gt;` because of return type</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>52 | /     for ann in annotations {</tspan>
+</tspan>
+    <tspan x="10px" y="136px"><tspan>53 | |         match (ann.range.0, ann.range.1) {</tspan>
+</tspan>
+    <tspan x="10px" y="154px"><tspan>54 | |             (None, None) =&gt; continue,</tspan>
+</tspan>
+    <tspan x="10px" y="172px"><tspan>55 | |             (Some(start), Some(end)) if start &gt; end_index || end &lt; start_index =&gt; continue,</tspan>
+</tspan>
+    <tspan x="10px" y="190px"><tspan>...  |</tspan>
+</tspan>
+    <tspan x="10px" y="208px"><tspan>71 | |         }</tspan>
+</tspan>
+    <tspan x="10px" y="226px"><tspan>72 | |     }</tspan>
+</tspan>
+    <tspan x="10px" y="244px"><tspan>   | |_____^ expected enum `std::option::Option`, found ()</tspan>
+</tspan>
+    <tspan x="10px" y="262px"><tspan>   |</tspan>
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/fixtures/no-color/multiline_annotation.txt b/tests/fixtures/no-color/multiline_annotation.txt
deleted file mode 100644
index bacdec1..0000000
--- a/tests/fixtures/no-color/multiline_annotation.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0308]: mismatched types
-  --> src/format.rs:51:6
-   |
-51 |   ) -> Option<String> {
-   |        -------------- expected `std::option::Option<std::string::String>` because of return type
-52 | /     for ann in annotations {
-53 | |         match (ann.range.0, ann.range.1) {
-54 | |             (None, None) => continue,
-55 | |             (Some(start), Some(end)) if start > end_index || end < start_index => continue,
-...  |
-71 | |         }
-72 | |     }
-   | |_____^ expected enum `std::option::Option`, found ()
-   |
diff --git a/tests/fixtures/no-color/multiline_annotation2.svg b/tests/fixtures/no-color/multiline_annotation2.svg
new file mode 100644
index 0000000..f4b4433
--- /dev/null
+++ b/tests/fixtures/no-color/multiline_annotation2.svg
@@ -0,0 +1,39 @@
+<svg width="740px" height="182px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan>error[E0027]: pattern does not mention fields `lineno`, `content`</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan>   --&gt; src/display_list.rs:139:32</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>    |</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan>139 |                           if let DisplayLine::Source {</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>    |  ________________________________^</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>140 | |                             ref mut inline_marks,</tspan>
+</tspan>
+    <tspan x="10px" y="136px"><tspan>141 | |                         } = body[body_idx]</tspan>
+</tspan>
+    <tspan x="10px" y="154px"><tspan>    | |_________________________^ missing fields `lineno`, `content`</tspan>
+</tspan>
+    <tspan x="10px" y="172px"><tspan>    |</tspan>
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/fixtures/no-color/multiline_annotation2.txt b/tests/fixtures/no-color/multiline_annotation2.txt
deleted file mode 100644
index 8a00bfa..0000000
--- a/tests/fixtures/no-color/multiline_annotation2.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0027]: pattern does not mention fields `lineno`, `content`
-   --> src/display_list.rs:139:32
-    |
-139 |                           if let DisplayLine::Source {
-    |  ________________________________^
-140 | |                             ref mut inline_marks,
-141 | |                         } = body[body_idx]
-    | |_________________________^ missing fields `lineno`, `content`
-    |
diff --git a/tests/fixtures/no-color/multiline_annotation3.svg b/tests/fixtures/no-color/multiline_annotation3.svg
new file mode 100644
index 0000000..18a9bf6
--- /dev/null
+++ b/tests/fixtures/no-color/multiline_annotation3.svg
@@ -0,0 +1,39 @@
+<svg width="740px" height="182px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan>error[E####]: spacing error found</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan>  --&gt; foo.txt:26:12</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>   |</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan>26 |   This is an exampl</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>   |  ____________^</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>27 | | e of an edge case of an annotation overflowing</tspan>
+</tspan>
+    <tspan x="10px" y="136px"><tspan>   | |_^ this should not be on separate lines</tspan>
+</tspan>
+    <tspan x="10px" y="154px"><tspan>28 |   to exactly one character on next line.</tspan>
+</tspan>
+    <tspan x="10px" y="172px"><tspan>   |</tspan>
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/fixtures/no-color/multiline_annotation3.txt b/tests/fixtures/no-color/multiline_annotation3.txt
deleted file mode 100644
index 12e174c..0000000
--- a/tests/fixtures/no-color/multiline_annotation3.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E####]: spacing error found
-  --> foo.txt:26:12
-   |
-26 |   This is an exampl
-   |  ____________^
-27 | | e of an edge case of an annotation overflowing
-   | |_^ this should not be on separate lines
-28 |   to exactly one character on next line.
-   |
\ No newline at end of file
diff --git a/tests/fixtures/no-color/multiple_annotations.svg b/tests/fixtures/no-color/multiple_annotations.svg
new file mode 100644
index 0000000..3f15144
--- /dev/null
+++ b/tests/fixtures/no-color/multiple_annotations.svg
@@ -0,0 +1,49 @@
+<svg width="768px" height="272px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan>    |</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan> 96 | fn add_title_line(result: &amp;mut Vec&lt;String&gt;, main_annotation: Option&lt;&amp;Annotation&gt;) {</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan> 97 |     if let Some(annotation) = main_annotation {</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan>    |                 ^^^^^^^^^^ Variable defined here</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan> 98 |         result.push(format_title_line(</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan> 99 |             &amp;annotation.annotation_type,</tspan>
+</tspan>
+    <tspan x="10px" y="136px"><tspan>    |              ^^^^^^^^^^ Referenced here</tspan>
+</tspan>
+    <tspan x="10px" y="154px"><tspan>100 |             None,</tspan>
+</tspan>
+    <tspan x="10px" y="172px"><tspan>101 |             &amp;annotation.label,</tspan>
+</tspan>
+    <tspan x="10px" y="190px"><tspan>    |              ^^^^^^^^^^ Referenced again here</tspan>
+</tspan>
+    <tspan x="10px" y="208px"><tspan>102 |         ));</tspan>
+</tspan>
+    <tspan x="10px" y="226px"><tspan>103 |     }</tspan>
+</tspan>
+    <tspan x="10px" y="244px"><tspan>104 | }</tspan>
+</tspan>
+    <tspan x="10px" y="262px"><tspan>    |</tspan>
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/fixtures/no-color/multiple_annotations.txt b/tests/fixtures/no-color/multiple_annotations.txt
deleted file mode 100644
index 26c677f..0000000
--- a/tests/fixtures/no-color/multiple_annotations.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-    |
- 96 | fn add_title_line(result: &mut Vec<String>, main_annotation: Option<&Annotation>) {
- 97 |     if let Some(annotation) = main_annotation {
-    |                 ^^^^^^^^^^ Variable defined here
- 98 |         result.push(format_title_line(
- 99 |             &annotation.annotation_type,
-    |              ^^^^^^^^^^ Referenced here
-100 |             None,
-101 |             &annotation.label,
-    |              ^^^^^^^^^^ Referenced again here
-102 |         ));
-103 |     }
-104 | }
-    |
diff --git a/tests/fixtures/no-color/one_past.svg b/tests/fixtures/no-color/one_past.svg
new file mode 100644
index 0000000..c8900d0
--- /dev/null
+++ b/tests/fixtures/no-color/one_past.svg
@@ -0,0 +1,33 @@
+<svg width="740px" height="128px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan>error: expected `.`, `=`</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan> --&gt; Cargo.toml:1:5</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>  |</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan>1 | asdf</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>  |     ^</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>  |</tspan>
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/fixtures/no-color/one_past.txt b/tests/fixtures/no-color/one_past.txt
deleted file mode 100644
index 7f255b8..0000000
--- a/tests/fixtures/no-color/one_past.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-error: expected `.`, `=`
- --> Cargo.toml:1:5
-  |
-1 | asdf
-  |     ^
-  |
diff --git a/tests/fixtures/no-color/simple.svg b/tests/fixtures/no-color/simple.svg
new file mode 100644
index 0000000..51a3a65
--- /dev/null
+++ b/tests/fixtures/no-color/simple.svg
@@ -0,0 +1,39 @@
+<svg width="740px" height="182px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan>error: expected one of `.`, `;`, `?`, or an operator, found `for`</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan>   --&gt; src/format_color.rs:171:9</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>    |</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan>169 |         })</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>    |           - expected one of `.`, `;`, `?`, or an operator here</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>170 | </tspan>
+</tspan>
+    <tspan x="10px" y="136px"><tspan>171 |         for line in &amp;self.body {</tspan>
+</tspan>
+    <tspan x="10px" y="154px"><tspan>    |         ^^^ unexpected token</tspan>
+</tspan>
+    <tspan x="10px" y="172px"><tspan>    |</tspan>
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/fixtures/no-color/simple.txt b/tests/fixtures/no-color/simple.txt
deleted file mode 100644
index 752cc89..0000000
--- a/tests/fixtures/no-color/simple.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-error: expected one of `.`, `;`, `?`, or an operator, found `for`
-   --> src/format_color.rs:171:9
-    |
-169 |         })
-    |           - expected one of `.`, `;`, `?`, or an operator here
-170 | 
-171 |         for line in &self.body {
-    |         ^^^ unexpected token
-    |
diff --git a/tests/fixtures/no-color/strip_line.svg b/tests/fixtures/no-color/strip_line.svg
new file mode 100644
index 0000000..b1fd8a6
--- /dev/null
+++ b/tests/fixtures/no-color/strip_line.svg
@@ -0,0 +1,33 @@
+<svg width="740px" height="128px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan>error[E0308]: mismatched types</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan>  --&gt; $DIR/whitespace-trimming.rs:4:193</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>   |</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan>LL | ...                   let _: () = 42;</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>   |                                   ^^ expected (), found integer</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>   |</tspan>
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/fixtures/no-color/strip_line.txt b/tests/fixtures/no-color/strip_line.txt
deleted file mode 100644
index 65b0538..0000000
--- a/tests/fixtures/no-color/strip_line.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/whitespace-trimming.rs:4:193
-   |
-LL | ...                   let _: () = 42;
-   |                                   ^^ expected (), found integer
-   |
diff --git a/tests/fixtures/no-color/strip_line_char.svg b/tests/fixtures/no-color/strip_line_char.svg
new file mode 100644
index 0000000..15296a1
--- /dev/null
+++ b/tests/fixtures/no-color/strip_line_char.svg
@@ -0,0 +1,33 @@
+<svg width="740px" height="128px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan>error[E0308]: mismatched types</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan>  --&gt; $DIR/whitespace-trimming.rs:4:193</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>   |</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan>LL | ...                   let _: () = 42ñ</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>   |                                   ^^ expected (), found integer</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>   |</tspan>
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/fixtures/no-color/strip_line_char.txt b/tests/fixtures/no-color/strip_line_char.txt
deleted file mode 100644
index 3d4b700..0000000
--- a/tests/fixtures/no-color/strip_line_char.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/whitespace-trimming.rs:4:193
-   |
-LL | ...                   let _: () = 42ñ
-   |                                   ^^ expected (), found integer
-   |
diff --git a/tests/fixtures/no-color/strip_line_non_ws.svg b/tests/fixtures/no-color/strip_line_non_ws.svg
new file mode 100644
index 0000000..6a72e7c
--- /dev/null
+++ b/tests/fixtures/no-color/strip_line_non_ws.svg
@@ -0,0 +1,33 @@
+<svg width="1238px" height="128px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan>error[E0308]: mismatched types</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan>  --&gt; $DIR/non-whitespace-trimming.rs:4:241</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>   |</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan>LL | ... = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();...</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>   |                                                       ^^ expected (), found integer</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>   |</tspan>
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/fixtures/no-color/strip_line_non_ws.txt b/tests/fixtures/no-color/strip_line_non_ws.txt
deleted file mode 100644
index 850619a..0000000
--- a/tests/fixtures/no-color/strip_line_non_ws.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/non-whitespace-trimming.rs:4:241
-   |
-LL | ... = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();...
-   |                                                       ^^ expected (), found integer
-   |
diff --git a/tests/fixtures_test.rs b/tests/fixtures_test.rs
deleted file mode 100644
index 063829a..0000000
--- a/tests/fixtures_test.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-mod deserialize;
-mod diff;
-
-use crate::deserialize::Fixture;
-use annotate_snippets::Renderer;
-use annotate_snippets::Snippet;
-use glob::glob;
-use std::{error::Error, fs::File, io, io::prelude::*};
-
-fn read_file(path: &str) -> Result<String, io::Error> {
-    let mut f = File::open(path)?;
-    let mut s = String::new();
-    (f.read_to_string(&mut s))?;
-    Ok(s.trim_end().to_string())
-}
-
-fn read_fixture(src: &str) -> Result<(Renderer, Snippet<'_>), Box<dyn Error>> {
-    Ok(toml::from_str(src).map(|a: Fixture| (a.renderer.into(), a.snippet.into()))?)
-}
-
-#[test]
-#[cfg(not(windows))] // HACK: Not working on windows due to a serde error
-fn test_fixtures() {
-    for entry in glob("./tests/fixtures/no-color/**/*.toml").expect("Failed to read glob pattern") {
-        let p = entry.expect("Error while getting an entry");
-
-        let path_in = p.to_str().expect("Can't print path");
-        let path_out = path_in.replace(".toml", ".txt");
-
-        let src = read_file(path_in).expect("Failed to read file");
-        let (renderer, snippet) = read_fixture(&src).expect("Failed to read file");
-        let expected_out = read_file(&path_out).expect("Failed to read file");
-
-        let actual_out = renderer.render(snippet).to_string();
-        println!("{}", expected_out);
-        println!("{}", actual_out.trim_end());
-
-        assert_eq!(
-            expected_out,
-            actual_out.trim_end(),
-            "\n\n\nWhile parsing: {}\nThe diff is:\n\n\n{}\n\n\n",
-            path_in,
-            diff::get_diff(expected_out.as_str(), actual_out.as_str())
-        );
-    }
-}