From 26ae0a4d48d095a44608f2082f320f39494afe12 Mon Sep 17 00:00:00 2001 From: hugo Date: Sun, 15 Feb 2026 17:35:49 +0100 Subject: [PATCH] chore: made reference files align better with production code --- tests/assets/wxr-ref/about.md | 2 +- tests/assets/wxr-ref/atomo.md | 3 +- tests/assets/wxr-ref/bilderarchiv.md | 2 +- tests/assets/wxr-ref/bitrot-reloaded.md | 3 +- tests/assets/wxr-ref/bottle.md | 3 +- ...uction-to-chicken-schemes-object-system.md | 3 +- tests/assets/wxr-ref/evil-is-king.md | 3 +- tests/assets/wxr-ref/herbst.md | 3 +- tests/assets/wxr-ref/ihr-seid-helden.md | 3 +- tests/assets/wxr-ref/impressum.md | 2 +- .../assets/wxr-ref/jquery-lightbox-plugin.md | 3 +- tests/assets/wxr-ref/linkdump.md | 2 +- tests/assets/wxr-ref/mal-wieder-auf-linux.md | 3 +- tests/assets/wxr-ref/millima-mabonde.md | 3 +- ...-nach-scharferen-gesetzen-tagesschau-de.md | 3 +- ...ist-eine-analoge-digitalkamera-golem-de.md | 3 +- .../wxr-ref/pferderouladen-mit-ratatouille.md | 3 +- ...en-vegetarisch-und-so-garnicht-russisch.md | 3 +- tests/assets/wxr-ref/rfc1437-on-the-road.md | 3 +- tests/assets/wxr-ref/rinderrouladen.md | 3 +- ...etworks-und-meine-nutzung-von-denselben.md | 3 +- ...2%80%94-courtesy-of-safari-touch-arcade.md | 3 +- ...ered-in-amd-cpus-%e2%80%a2-the-register.md | 3 +- .../svb-brettspielrunde-im-internet.md | 2 +- tests/assets/wxr-ref/sweet-so-sweet.md | 3 +- .../the-art-and-science-of-smalltalk.md | 3 +- tests/assets/wxr-ref/turfiguren.md | 3 +- tests/assets/wxr-ref/what-a-superb-owl.md | 3 +- tests/assets/wxr-ref/wir-haben-geheiratet.md | 3 +- .../wxr-ref/wochentliche-leseliste-2.md | 3 +- .../wxr-ref/wochentliche-leseliste-4.md | 3 +- .../assets/wxr-ref/wochentliche-leseliste.md | 3 +- ...che-integrator-%c2%ab-wordpress-plugins.md | 3 +- .../engine/WxrReferenceComparison.e2e.test.ts | 578 ++++++++++++++++++ 34 files changed, 611 insertions(+), 61 deletions(-) create mode 100644 tests/engine/WxrReferenceComparison.e2e.test.ts diff --git a/tests/assets/wxr-ref/about.md b/tests/assets/wxr-ref/about.md index 64f9f5f..a696235 100644 --- a/tests/assets/wxr-ref/about.md +++ b/tests/assets/wxr-ref/about.md @@ -3,7 +3,7 @@ id: 0c31ccbe-51b7-46df-8b7a-418fe4193428 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: About slug: about -status: publish +status: published createdAt: '2010-11-13T10:27:56.000Z' updatedAt: '2010-11-13T12:19:15.000Z' categories: diff --git a/tests/assets/wxr-ref/atomo.md b/tests/assets/wxr-ref/atomo.md index 433b367..a20ced8 100644 --- a/tests/assets/wxr-ref/atomo.md +++ b/tests/assets/wxr-ref/atomo.md @@ -3,14 +3,13 @@ id: db4b98d7-0611-4258-b558-2357314b640f projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: atomo slug: atomo -status: publish +status: published createdAt: '2010-11-14T11:41:25.000Z' updatedAt: '2011-02-28T15:20:12.000Z' tags: - programmieren categories: - asides - - article author: hugo publishedAt: '2010-11-14T10:41:25.000Z' --- diff --git a/tests/assets/wxr-ref/bilderarchiv.md b/tests/assets/wxr-ref/bilderarchiv.md index 81da172..4ffc11a 100644 --- a/tests/assets/wxr-ref/bilderarchiv.md +++ b/tests/assets/wxr-ref/bilderarchiv.md @@ -3,7 +3,7 @@ id: ffe762f1-6d45-4ea5-bc73-a7064a4039a3 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Bilderarchiv slug: bilderarchiv -status: publish +status: published createdAt: '2011-05-16T13:43:39.000Z' updatedAt: '2011-05-17T14:12:46.000Z' categories: diff --git a/tests/assets/wxr-ref/bitrot-reloaded.md b/tests/assets/wxr-ref/bitrot-reloaded.md index b789b8d..2cdeb6a 100644 --- a/tests/assets/wxr-ref/bitrot-reloaded.md +++ b/tests/assets/wxr-ref/bitrot-reloaded.md @@ -3,7 +3,7 @@ id: aedbc32a-39d7-4aec-8969-cfef38469262 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Bitrot reloaded slug: bitrot-reloaded -status: publish +status: published createdAt: '2010-11-13T12:11:34.000Z' updatedAt: '2010-11-14T12:28:02.000Z' tags: @@ -11,7 +11,6 @@ tags: - wordpress categories: - artikel - - article author: hugo publishedAt: '2010-11-13T11:11:34.000Z' --- diff --git a/tests/assets/wxr-ref/bottle.md b/tests/assets/wxr-ref/bottle.md index 7275409..dce99d0 100644 --- a/tests/assets/wxr-ref/bottle.md +++ b/tests/assets/wxr-ref/bottle.md @@ -3,14 +3,13 @@ id: 0df0a274-fbc0-4d90-8c4c-a4ad6ea70981 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Bottle slug: bottle -status: publish +status: published createdAt: '2010-11-19T08:14:36.000Z' updatedAt: '2010-11-19T08:14:36.000Z' tags: - film categories: - artikel - - article author: hugo publishedAt: '2010-11-19T07:14:36.000Z' --- diff --git a/tests/assets/wxr-ref/devrandom-random-thoughts-on-programming-in-parentheses-coops-an-introduction-to-chicken-schemes-object-system.md b/tests/assets/wxr-ref/devrandom-random-thoughts-on-programming-in-parentheses-coops-an-introduction-to-chicken-schemes-object-system.md index b454eec..05a7555 100644 --- a/tests/assets/wxr-ref/devrandom-random-thoughts-on-programming-in-parentheses-coops-an-introduction-to-chicken-schemes-object-system.md +++ b/tests/assets/wxr-ref/devrandom-random-thoughts-on-programming-in-parentheses-coops-an-introduction-to-chicken-schemes-object-system.md @@ -3,7 +3,7 @@ id: 432af9b5-0143-4c03-93d5-5ecc3db61936 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: '/dev/random - Random Thoughts On Programming In Parentheses - Coops - An introduction to chicken scheme''s object system' slug: devrandom-random-thoughts-on-programming-in-parentheses-coops-an-introduction-to-chicken-schemes-object-system -status: publish +status: published createdAt: '2011-01-21T14:03:36.000Z' updatedAt: '2011-02-28T15:18:35.000Z' tags: @@ -12,7 +12,6 @@ tags: - scheme categories: - asides - - article author: hugo publishedAt: '2011-01-21T13:03:36.000Z' --- diff --git a/tests/assets/wxr-ref/evil-is-king.md b/tests/assets/wxr-ref/evil-is-king.md index 21e920c..2933223 100644 --- a/tests/assets/wxr-ref/evil-is-king.md +++ b/tests/assets/wxr-ref/evil-is-king.md @@ -3,14 +3,13 @@ id: 1ecf84f0-b1fb-498a-9e59-5a517aecfeba projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: EVIL is King slug: evil-is-king -status: publish +status: published createdAt: '2011-07-24T16:26:31.000Z' updatedAt: '2011-07-25T14:50:59.000Z' tags: - fotografie categories: - artikel - - article author: hugo publishedAt: '2011-07-24T14:26:31.000Z' --- diff --git a/tests/assets/wxr-ref/herbst.md b/tests/assets/wxr-ref/herbst.md index c256ced..9c311d3 100644 --- a/tests/assets/wxr-ref/herbst.md +++ b/tests/assets/wxr-ref/herbst.md @@ -3,14 +3,13 @@ id: e6e9d27c-f5c6-4124-a0bd-d6e706dbdd1e projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Herbst slug: herbst -status: publish +status: published createdAt: '2010-11-13T13:59:38.000Z' updatedAt: '2011-02-28T14:34:33.000Z' tags: - fotografie categories: - galerie - - article author: hugo publishedAt: '2010-11-13T12:59:38.000Z' --- diff --git a/tests/assets/wxr-ref/ihr-seid-helden.md b/tests/assets/wxr-ref/ihr-seid-helden.md index 2fa64d2..8b0f3be 100644 --- a/tests/assets/wxr-ref/ihr-seid-helden.md +++ b/tests/assets/wxr-ref/ihr-seid-helden.md @@ -3,7 +3,7 @@ id: f6d26648-016d-4cd6-a889-debde902b7f7 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: 'Ihr seid Helden!' slug: ihr-seid-helden -status: publish +status: published createdAt: '2011-02-25T12:55:46.000Z' updatedAt: '2011-02-25T12:56:52.000Z' tags: @@ -11,7 +11,6 @@ tags: - medien categories: - artikel - - article author: hugo publishedAt: '2011-02-25T11:55:46.000Z' --- diff --git a/tests/assets/wxr-ref/impressum.md b/tests/assets/wxr-ref/impressum.md index 1d859a4..88f7c1a 100644 --- a/tests/assets/wxr-ref/impressum.md +++ b/tests/assets/wxr-ref/impressum.md @@ -3,7 +3,7 @@ id: 1be432f9-6db1-40a9-8ef5-23e390e9896d projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Impressum slug: impressum -status: publish +status: published createdAt: '2010-11-13T13:39:06.000Z' updatedAt: '2018-05-25T13:03:51.000Z' categories: diff --git a/tests/assets/wxr-ref/jquery-lightbox-plugin.md b/tests/assets/wxr-ref/jquery-lightbox-plugin.md index e95d3fe..023a5fe 100644 --- a/tests/assets/wxr-ref/jquery-lightbox-plugin.md +++ b/tests/assets/wxr-ref/jquery-lightbox-plugin.md @@ -3,7 +3,7 @@ id: 5614c28f-ec24-467d-a265-c91d1ff95364 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: jQuery lightBox plugin slug: jquery-lightbox-plugin -status: publish +status: published createdAt: '2010-11-14T16:51:48.000Z' updatedAt: '2011-02-28T15:20:12.000Z' tags: @@ -12,7 +12,6 @@ tags: - wordpress categories: - asides - - article author: hugo publishedAt: '2010-11-14T15:51:48.000Z' --- diff --git a/tests/assets/wxr-ref/linkdump.md b/tests/assets/wxr-ref/linkdump.md index 9fbd1ba..066495c 100644 --- a/tests/assets/wxr-ref/linkdump.md +++ b/tests/assets/wxr-ref/linkdump.md @@ -3,7 +3,7 @@ id: 783692aa-8bec-4665-ba51-96395ec19790 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Linkdump slug: linkdump -status: publish +status: published createdAt: '2010-12-28T19:38:24.000Z' updatedAt: '2010-12-28T20:17:21.000Z' categories: diff --git a/tests/assets/wxr-ref/mal-wieder-auf-linux.md b/tests/assets/wxr-ref/mal-wieder-auf-linux.md index 9036f0b..c103a78 100644 --- a/tests/assets/wxr-ref/mal-wieder-auf-linux.md +++ b/tests/assets/wxr-ref/mal-wieder-auf-linux.md @@ -3,12 +3,11 @@ id: 10b4560f-fbb2-42de-b411-2434b89e5686 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Mal wieder auf Linux ... slug: mal-wieder-auf-linux -status: publish +status: published createdAt: '2023-08-19T15:26:04.000Z' updatedAt: '2023-08-19T15:28:14.000Z' categories: - artikel - - article author: hugo publishedAt: '2023-08-19T13:26:04.000Z' --- diff --git a/tests/assets/wxr-ref/millima-mabonde.md b/tests/assets/wxr-ref/millima-mabonde.md index 3dbe3e6..9e2e435 100644 --- a/tests/assets/wxr-ref/millima-mabonde.md +++ b/tests/assets/wxr-ref/millima-mabonde.md @@ -3,7 +3,7 @@ id: 375ec97e-479b-49ee-9a5b-209269418c43 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Sommerkonzert Millima Mabonde slug: millima-mabonde -status: publish +status: published createdAt: '2011-07-03T22:05:56.000Z' updatedAt: '2011-07-08T14:20:22.000Z' tags: @@ -12,7 +12,6 @@ tags: - musik categories: - galerie - - article author: hugo publishedAt: '2011-07-03T20:05:56.000Z' --- diff --git a/tests/assets/wxr-ref/mit-sicherheit-rufe-nach-scharferen-gesetzen-tagesschau-de.md b/tests/assets/wxr-ref/mit-sicherheit-rufe-nach-scharferen-gesetzen-tagesschau-de.md index ba8fab9..6a21024 100644 --- a/tests/assets/wxr-ref/mit-sicherheit-rufe-nach-scharferen-gesetzen-tagesschau-de.md +++ b/tests/assets/wxr-ref/mit-sicherheit-rufe-nach-scharferen-gesetzen-tagesschau-de.md @@ -3,7 +3,7 @@ id: a6c5c6c1-0c11-49b1-bd52-2c698de0e640 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: 'Mit Sicherheit: Rufe nach schärferen Gesetzen | tagesschau.de' slug: mit-sicherheit-rufe-nach-scharferen-gesetzen-tagesschau-de -status: publish +status: published createdAt: '2010-11-18T20:32:15.000Z' updatedAt: '2011-02-28T15:20:03.000Z' tags: @@ -12,7 +12,6 @@ tags: categories: - asides - metaowl - - article author: hugo publishedAt: '2010-11-18T19:32:15.000Z' --- diff --git a/tests/assets/wxr-ref/ohne-display-leica-m-d-ist-eine-analoge-digitalkamera-golem-de.md b/tests/assets/wxr-ref/ohne-display-leica-m-d-ist-eine-analoge-digitalkamera-golem-de.md index 5443d99..aa983c4 100644 --- a/tests/assets/wxr-ref/ohne-display-leica-m-d-ist-eine-analoge-digitalkamera-golem-de.md +++ b/tests/assets/wxr-ref/ohne-display-leica-m-d-ist-eine-analoge-digitalkamera-golem-de.md @@ -3,7 +3,7 @@ id: 49c4c9f2-5c46-47d0-ae16-be13f81b6696 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: 'Ohne Display: Leica M-D ist eine analoge Digitalkamera - Golem.de' slug: ohne-display-leica-m-d-ist-eine-analoge-digitalkamera-golem-de -status: publish +status: published createdAt: '2016-04-29T12:05:22.000Z' updatedAt: '2016-04-29T12:05:22.000Z' tags: @@ -12,7 +12,6 @@ tags: categories: - artikel - asides - - article author: hugo publishedAt: '2016-04-29T10:05:22.000Z' --- diff --git a/tests/assets/wxr-ref/pferderouladen-mit-ratatouille.md b/tests/assets/wxr-ref/pferderouladen-mit-ratatouille.md index 88ed41f..4a2ab08 100644 --- a/tests/assets/wxr-ref/pferderouladen-mit-ratatouille.md +++ b/tests/assets/wxr-ref/pferderouladen-mit-ratatouille.md @@ -3,7 +3,7 @@ id: dd79e799-155a-4043-b8b8-dd1242a6a5ab projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Pferderouladen mit Ratatouille slug: pferderouladen-mit-ratatouille -status: publish +status: published createdAt: '2011-03-05T20:39:56.000Z' updatedAt: '2011-03-05T21:15:06.000Z' tags: @@ -11,7 +11,6 @@ tags: categories: - artikel - kochbuch - - article author: hugo publishedAt: '2011-03-05T19:39:56.000Z' --- diff --git a/tests/assets/wxr-ref/piroggen-vegetarisch-und-so-garnicht-russisch.md b/tests/assets/wxr-ref/piroggen-vegetarisch-und-so-garnicht-russisch.md index e12b6a4..1474199 100644 --- a/tests/assets/wxr-ref/piroggen-vegetarisch-und-so-garnicht-russisch.md +++ b/tests/assets/wxr-ref/piroggen-vegetarisch-und-so-garnicht-russisch.md @@ -3,7 +3,7 @@ id: 8825edef-ccea-4931-b880-e84ec50c007d projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: 'Piroggen (vegetarisch, und so garnicht russisch)' slug: piroggen-vegetarisch-und-so-garnicht-russisch -status: publish +status: published createdAt: '2011-04-26T20:16:32.000Z' updatedAt: '2011-07-25T13:28:03.000Z' tags: @@ -11,7 +11,6 @@ tags: categories: - artikel - kochbuch - - article author: hugo publishedAt: '2011-04-26T18:16:32.000Z' --- diff --git a/tests/assets/wxr-ref/rfc1437-on-the-road.md b/tests/assets/wxr-ref/rfc1437-on-the-road.md index 5431df7..189dc26 100644 --- a/tests/assets/wxr-ref/rfc1437-on-the-road.md +++ b/tests/assets/wxr-ref/rfc1437-on-the-road.md @@ -3,7 +3,7 @@ id: b49e03d2-ca4a-4427-9970-81272f5ef317 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Kochen mit rfc1437 - Schweinegeschnetzeltes Mediterran slug: rfc1437-on-the-road -status: publish +status: published createdAt: '2011-02-26T16:03:08.000Z' updatedAt: '2011-03-19T20:52:27.000Z' tags: @@ -11,7 +11,6 @@ tags: categories: - artikel - kochbuch - - article author: hugo publishedAt: '2011-02-26T15:03:08.000Z' --- diff --git a/tests/assets/wxr-ref/rinderrouladen.md b/tests/assets/wxr-ref/rinderrouladen.md index b8e2b5a..4ad6616 100644 --- a/tests/assets/wxr-ref/rinderrouladen.md +++ b/tests/assets/wxr-ref/rinderrouladen.md @@ -3,7 +3,7 @@ id: 9e8ec9f3-f974-45b3-93ba-da716a000ee3 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Rinderrouladen slug: rinderrouladen -status: publish +status: published createdAt: '2012-03-17T19:34:48.000Z' updatedAt: '2012-03-17T19:34:48.000Z' tags: @@ -11,7 +11,6 @@ tags: categories: - galerie - kochbuch - - article author: hugo publishedAt: '2012-03-17T18:34:48.000Z' --- diff --git a/tests/assets/wxr-ref/social-networks-und-meine-nutzung-von-denselben.md b/tests/assets/wxr-ref/social-networks-und-meine-nutzung-von-denselben.md index 4439670..c16269c 100644 --- a/tests/assets/wxr-ref/social-networks-und-meine-nutzung-von-denselben.md +++ b/tests/assets/wxr-ref/social-networks-und-meine-nutzung-von-denselben.md @@ -3,14 +3,13 @@ id: 59d159ed-75a2-41bc-99db-0043f86b6f4a projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Social Networks und meine Nutzung von denselben slug: social-networks-und-meine-nutzung-von-denselben -status: publish +status: published createdAt: '2011-07-25T11:01:43.000Z' updatedAt: '2011-07-25T11:01:43.000Z' tags: - web categories: - artikel - - article author: hugo publishedAt: '2011-07-25T09:01:43.000Z' --- diff --git a/tests/assets/wxr-ref/space-quest-lands-on-the-ipad-%e2%80%94-courtesy-of-safari-touch-arcade.md b/tests/assets/wxr-ref/space-quest-lands-on-the-ipad-%e2%80%94-courtesy-of-safari-touch-arcade.md index a57a742..400da87 100644 --- a/tests/assets/wxr-ref/space-quest-lands-on-the-ipad-%e2%80%94-courtesy-of-safari-touch-arcade.md +++ b/tests/assets/wxr-ref/space-quest-lands-on-the-ipad-%e2%80%94-courtesy-of-safari-touch-arcade.md @@ -3,14 +3,13 @@ id: 41c5382e-4bb1-4ee0-bb0f-3efbb4f1b039 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: '''Space Quest'' Lands on the iPad — Courtesy of Safari | Touch Arcade' slug: space-quest-lands-on-the-ipad-%e2%80%94-courtesy-of-safari-touch-arcade -status: publish +status: published createdAt: '2010-11-15T08:40:37.000Z' updatedAt: '2011-02-28T15:20:12.000Z' tags: - javascript categories: - asides - - article author: hugo publishedAt: '2010-11-15T07:40:37.000Z' --- diff --git a/tests/assets/wxr-ref/super-secret-debugger-discovered-in-amd-cpus-%e2%80%a2-the-register.md b/tests/assets/wxr-ref/super-secret-debugger-discovered-in-amd-cpus-%e2%80%a2-the-register.md index 4425f1e..5e9e549 100644 --- a/tests/assets/wxr-ref/super-secret-debugger-discovered-in-amd-cpus-%e2%80%a2-the-register.md +++ b/tests/assets/wxr-ref/super-secret-debugger-discovered-in-amd-cpus-%e2%80%a2-the-register.md @@ -3,7 +3,7 @@ id: cd1c7500-0041-4767-93f3-eaefc1d8131a projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: '''Super-secret'' debugger discovered in AMD CPUs • The Register' slug: super-secret-debugger-discovered-in-amd-cpus-%e2%80%a2-the-register -status: publish +status: published createdAt: '2010-11-15T22:02:32.000Z' updatedAt: '2011-02-28T15:20:12.000Z' tags: @@ -11,7 +11,6 @@ tags: - sysadmin categories: - asides - - article author: hugo publishedAt: '2010-11-15T21:02:32.000Z' --- diff --git a/tests/assets/wxr-ref/svb-brettspielrunde-im-internet.md b/tests/assets/wxr-ref/svb-brettspielrunde-im-internet.md index cdcf240..24113e7 100644 --- a/tests/assets/wxr-ref/svb-brettspielrunde-im-internet.md +++ b/tests/assets/wxr-ref/svb-brettspielrunde-im-internet.md @@ -3,7 +3,7 @@ id: 0375a895-da45-4ab5-b554-30ea41096526 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: SVB Brettspielrunde im Internet slug: svb-brettspielrunde-im-internet -status: publish +status: published createdAt: '2020-03-24T13:48:33.000Z' updatedAt: '2021-05-30T13:33:18.000Z' categories: diff --git a/tests/assets/wxr-ref/sweet-so-sweet.md b/tests/assets/wxr-ref/sweet-so-sweet.md index 7b265fe..cb5d776 100644 --- a/tests/assets/wxr-ref/sweet-so-sweet.md +++ b/tests/assets/wxr-ref/sweet-so-sweet.md @@ -3,14 +3,13 @@ id: 793221fd-4c49-4053-bb20-739de5776a6e projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: 'Sweet, so sweet' slug: sweet-so-sweet -status: publish +status: published createdAt: '2022-11-05T08:08:12.000Z' updatedAt: '2022-11-05T08:14:24.000Z' tags: - photography categories: - galerie - - article author: hugo publishedAt: '2022-11-05T07:08:12.000Z' --- diff --git a/tests/assets/wxr-ref/the-art-and-science-of-smalltalk.md b/tests/assets/wxr-ref/the-art-and-science-of-smalltalk.md index 018a345..07b99c2 100644 --- a/tests/assets/wxr-ref/the-art-and-science-of-smalltalk.md +++ b/tests/assets/wxr-ref/the-art-and-science-of-smalltalk.md @@ -3,7 +3,7 @@ id: b410e924-6e3d-4f20-8512-41095b9fd4d0 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: The Art and Science of Smalltalk slug: the-art-and-science-of-smalltalk -status: publish +status: published createdAt: '2010-12-26T10:32:08.000Z' updatedAt: '2011-02-28T15:19:14.000Z' tags: @@ -11,7 +11,6 @@ tags: - smalltalk categories: - asides - - article author: hugo publishedAt: '2010-12-26T09:32:08.000Z' --- diff --git a/tests/assets/wxr-ref/turfiguren.md b/tests/assets/wxr-ref/turfiguren.md index fda9517..3c61d52 100644 --- a/tests/assets/wxr-ref/turfiguren.md +++ b/tests/assets/wxr-ref/turfiguren.md @@ -3,7 +3,7 @@ id: e772081f-6021-4231-b0e4-5c4ff7196386 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Türfiguren slug: turfiguren -status: publish +status: published createdAt: '2011-03-15T14:23:23.000Z' updatedAt: '2011-04-16T21:39:08.000Z' tags: @@ -11,7 +11,6 @@ tags: - münster categories: - galerie - - article author: hugo publishedAt: '2011-03-15T13:23:23.000Z' --- diff --git a/tests/assets/wxr-ref/what-a-superb-owl.md b/tests/assets/wxr-ref/what-a-superb-owl.md index db7c98d..4e7766f 100644 --- a/tests/assets/wxr-ref/what-a-superb-owl.md +++ b/tests/assets/wxr-ref/what-a-superb-owl.md @@ -3,14 +3,13 @@ id: 64ab1b8f-89fb-4dda-b2db-5955dbdcbd34 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: what a superb owl slug: what-a-superb-owl -status: publish +status: published createdAt: '2011-02-06T23:02:46.000Z' updatedAt: '2011-02-07T11:08:48.000Z' tags: - sport categories: - artikel - - article author: hugo publishedAt: '2011-02-06T22:02:46.000Z' --- diff --git a/tests/assets/wxr-ref/wir-haben-geheiratet.md b/tests/assets/wxr-ref/wir-haben-geheiratet.md index ea19fc9..5ae1e98 100644 --- a/tests/assets/wxr-ref/wir-haben-geheiratet.md +++ b/tests/assets/wxr-ref/wir-haben-geheiratet.md @@ -3,7 +3,7 @@ id: ecd3eb2d-bfec-452f-8bba-63378953337a projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Wir haben geheiratet slug: wir-haben-geheiratet -status: publish +status: published createdAt: '2011-09-04T16:50:06.000Z' updatedAt: '2011-09-04T16:52:20.000Z' tags: @@ -11,7 +11,6 @@ tags: - hochzeit categories: - artikel - - article author: hugo publishedAt: '2011-09-04T14:50:06.000Z' --- diff --git a/tests/assets/wxr-ref/wochentliche-leseliste-2.md b/tests/assets/wxr-ref/wochentliche-leseliste-2.md index 7f1ac86..0f9a376 100644 --- a/tests/assets/wxr-ref/wochentliche-leseliste-2.md +++ b/tests/assets/wxr-ref/wochentliche-leseliste-2.md @@ -3,7 +3,7 @@ id: a5099d66-a85b-445d-92ce-fb2dd42cdb97 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Wöchentliche Leseliste slug: wochentliche-leseliste-2 -status: publish +status: published createdAt: '2013-04-14T18:49:57.000Z' updatedAt: '2013-04-14T18:50:37.000Z' tags: @@ -13,7 +13,6 @@ tags: - politik categories: - asides - - article author: hugo publishedAt: '2013-04-14T16:49:57.000Z' --- diff --git a/tests/assets/wxr-ref/wochentliche-leseliste-4.md b/tests/assets/wxr-ref/wochentliche-leseliste-4.md index 9bfec79..7274986 100644 --- a/tests/assets/wxr-ref/wochentliche-leseliste-4.md +++ b/tests/assets/wxr-ref/wochentliche-leseliste-4.md @@ -3,12 +3,11 @@ id: 1bac8511-fe76-487f-82f8-42b38a869f22 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Wöchentliche Leseliste slug: wochentliche-leseliste-4 -status: publish +status: published createdAt: '2013-04-29T20:46:39.000Z' updatedAt: '2013-05-15T10:16:32.000Z' categories: - asides - - article author: hugo publishedAt: '2013-04-29T18:46:39.000Z' --- diff --git a/tests/assets/wxr-ref/wochentliche-leseliste.md b/tests/assets/wxr-ref/wochentliche-leseliste.md index 9591a11..090af7a 100644 --- a/tests/assets/wxr-ref/wochentliche-leseliste.md +++ b/tests/assets/wxr-ref/wochentliche-leseliste.md @@ -3,12 +3,11 @@ id: 7a4168f4-f3bf-4a72-8bd8-fc9714c50f03 projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: Wöchentliche Leseliste slug: wochentliche-leseliste -status: publish +status: published createdAt: '2013-04-08T14:10:27.000Z' updatedAt: '2013-04-08T14:13:29.000Z' categories: - asides - - article author: hugo publishedAt: '2013-04-08T12:10:27.000Z' --- diff --git a/tests/assets/wxr-ref/wordpress-%e2%80%ba-wordpress-nginx-proxy-cache-integrator-%c2%ab-wordpress-plugins.md b/tests/assets/wxr-ref/wordpress-%e2%80%ba-wordpress-nginx-proxy-cache-integrator-%c2%ab-wordpress-plugins.md index de45e93..27af7a1 100644 --- a/tests/assets/wxr-ref/wordpress-%e2%80%ba-wordpress-nginx-proxy-cache-integrator-%c2%ab-wordpress-plugins.md +++ b/tests/assets/wxr-ref/wordpress-%e2%80%ba-wordpress-nginx-proxy-cache-integrator-%c2%ab-wordpress-plugins.md @@ -3,7 +3,7 @@ id: 74fa9a89-0d76-4299-9e83-b0e97a0260ad projectId: f2d5e497-5a16-4033-864a-0df066e05e17 title: WordPress › WordPress Nginx proxy cache integrator « WordPress Plugins slug: wordpress-%e2%80%ba-wordpress-nginx-proxy-cache-integrator-%c2%ab-wordpress-plugins -status: publish +status: published createdAt: '2010-11-13T12:15:48.000Z' updatedAt: '2011-02-28T15:20:19.000Z' tags: @@ -11,7 +11,6 @@ tags: - wordpress categories: - asides - - article author: hugo publishedAt: '2010-11-13T11:15:48.000Z' --- diff --git a/tests/engine/WxrReferenceComparison.e2e.test.ts b/tests/engine/WxrReferenceComparison.e2e.test.ts new file mode 100644 index 0000000..853b98c --- /dev/null +++ b/tests/engine/WxrReferenceComparison.e2e.test.ts @@ -0,0 +1,578 @@ +/** + * WXR Reference Comparison End-to-End Test + * + * This test parses the reference WXR file (tests/assets/wxr-ref/reduced_wxr.xml), + * processes it through the full import pipeline (WxrParser → ImportAnalysisEngine → ImportExecutionEngine), + * and compares each generated post/page with the expected reference markdown files. + * + * The test reports all differences between the generated output and reference files, + * excluding the id and projectId fields which are runtime-generated GUIDs. + */ + +import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'; +import * as path from 'path'; +import * as fs from 'fs'; +import matter from 'gray-matter'; +import { WxrParser, type WxrData } from '../../src/main/engine/WxrParser'; +import type { ImportAnalysisReport } from '../../src/main/engine/ImportAnalysisEngine'; + +// Read the WXR file SYNCHRONOUSLY at module load time (before mocks apply) +const wxrRefDir = path.join(__dirname, '../assets/wxr-ref'); +const wxrFilePath = path.join(wxrRefDir, 'reduced_wxr.xml'); +const wxrFileContent = fs.readFileSync(wxrFilePath, 'utf-8'); + +// Read all reference markdown files +const referenceFiles = new Map(); +const files = fs.readdirSync(wxrRefDir); +for (const file of files) { + if (file.endsWith('.md')) { + const content = fs.readFileSync(path.join(wxrRefDir, file), 'utf-8'); + referenceFiles.set(file.replace('.md', ''), content); + } +} + +// Track files written during import +const writtenFiles: Array<{ + path: string; + content: string; +}> = []; + +// Track all database inserts +const insertedPosts: Array<{ + id: string; + projectId: string; + title: string; + slug: string; + content: string | null; + status: string; + tags: string; + categories: string; + createdAt: Date; + updatedAt: Date; + publishedAt?: Date; + author?: string; +}> = []; + +const createdTags: string[] = []; + +// Mock database +const mockDb = { + insert: vi.fn().mockImplementation((table: any) => ({ + values: vi.fn().mockImplementation(async (data: any) => { + if (data && typeof data === 'object') { + if ('slug' in data && 'title' in data) { + insertedPosts.push(data); + } + } + return data; + }), + })), + select: vi.fn().mockReturnValue({ + from: vi.fn().mockReturnValue({ + where: vi.fn().mockReturnValue({ + all: vi.fn().mockResolvedValue([]), + }), + }), + }), +}; + +const mockClient = { + execute: vi.fn().mockResolvedValue({ rows: [] }), +}; + +// Mock modules +vi.mock('../../src/main/database', () => ({ + getDatabase: vi.fn(() => ({ + getLocal: vi.fn(() => mockDb), + getLocalClient: vi.fn(() => mockClient), + })), +})); + +vi.mock('fs/promises', () => ({ + mkdir: vi.fn().mockResolvedValue(undefined), + writeFile: vi.fn().mockImplementation(async (filePath: string, content: string) => { + writtenFiles.push({ path: filePath, content }); + }), + copyFile: vi.fn().mockResolvedValue(undefined), + access: vi.fn().mockResolvedValue(undefined), + stat: vi.fn().mockResolvedValue({ size: 1024 }), + readFile: vi.fn().mockImplementation(async (filePath: string) => { + if (filePath.endsWith('reduced_wxr.xml')) { + return wxrFileContent; + } + return Buffer.from('test data'); + }), +})); + +vi.mock('electron', () => ({ + app: { + getPath: vi.fn(() => '/mock/user/data'), + }, +})); + +let uuidCounter = 0; +vi.mock('uuid', () => ({ + v4: vi.fn(() => `test-uuid-${++uuidCounter}`), +})); + +// Mock TagEngine +const mockTagEngine = { + setProjectContext: vi.fn(), + createTag: vi.fn().mockImplementation(async (input: { name: string }) => { + createdTags.push(input.name.toLowerCase()); + return { + id: `tag-${input.name}`, + projectId: 'test-project', + name: input.name.toLowerCase(), + createdAt: new Date(), + updatedAt: new Date(), + }; + }), + getAllTags: vi.fn().mockResolvedValue([]), +}; + +vi.mock('../../src/main/engine/TagEngine', () => ({ + getTagEngine: vi.fn(() => mockTagEngine), +})); + +// Mock PostEngine +const mockPostEngine = { + setProjectContext: vi.fn(), + createPost: vi.fn(), + publishPost: vi.fn(), + isSlugAvailable: vi.fn().mockResolvedValue(true), + generateUniqueSlug: vi.fn().mockImplementation(async (title: string) => { + return `${title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')}-new`; + }), + updateFTSIndex: vi.fn().mockResolvedValue(undefined), +}; + +vi.mock('../../src/main/engine/PostEngine', () => ({ + getPostEngine: vi.fn(() => mockPostEngine), +})); + +// Mock MediaEngine +const mockMediaEngine = { + setProjectContext: vi.fn(), + importMedia: vi.fn().mockImplementation(async (sourcePath: string, metadata?: any) => { + return { + id: `media-${Math.random().toString(36).substr(2, 9)}`, + filename: path.basename(sourcePath), + originalName: metadata?.originalName || path.basename(sourcePath), + title: metadata?.title, + linkedPostIds: metadata?.linkedPostIds || [], + }; + }), +}; + +vi.mock('../../src/main/engine/MediaEngine', () => ({ + getMediaEngine: vi.fn(() => mockMediaEngine), +})); + +// Mock PostMediaEngine +const mockPostMediaEngine = { + setProjectContext: vi.fn(), + linkMediaToPost: vi.fn().mockResolvedValue({ + id: 'link-id', + projectId: 'test-project', + postId: 'post-id', + mediaId: 'media-id', + sortOrder: 0, + createdAt: new Date(), + }), +}; + +vi.mock('../../src/main/engine/PostMediaEngine', () => ({ + getPostMediaEngine: vi.fn(() => mockPostMediaEngine), +})); + +// Import after mocks are set up +import { ImportExecutionEngine } from '../../src/main/engine/ImportExecutionEngine'; +import { ImportAnalysisEngine } from '../../src/main/engine/ImportAnalysisEngine'; + +/** + * Parse frontmatter from a markdown file content + */ +function parseFrontmatter(content: string): { data: Record; body: string } { + const parsed = matter(content); + return { + data: parsed.data as Record, + body: parsed.content.trim(), + }; +} + +/** + * Compares two values and returns a description of differences + */ +function describeDifference(key: string, expected: unknown, actual: unknown): string | null { + // Normalize arrays for comparison (sort them) + const normalizeArray = (arr: unknown) => { + if (Array.isArray(arr)) { + return [...arr].sort(); + } + return arr; + }; + + const expectedNorm = normalizeArray(expected); + const actualNorm = normalizeArray(actual); + + // Compare stringified versions for arrays and objects + const expectedStr = JSON.stringify(expectedNorm); + const actualStr = JSON.stringify(actualNorm); + + if (expectedStr !== actualStr) { + return `${key}: expected ${expectedStr}, got ${actualStr}`; + } + return null; +} + +/** + * Compare metadata (excluding id and projectId) + */ +function compareMetadata( + expected: Record, + actual: Record, + slug: string +): string[] { + const differences: string[] = []; + + // Keys to skip (GUIDs that are runtime-generated) + const skipKeys = ['id', 'projectId']; + + // Check all expected keys + for (const key of Object.keys(expected)) { + if (skipKeys.includes(key)) continue; + + const diff = describeDifference(key, expected[key], actual[key]); + if (diff) { + differences.push(`[${slug}] Metadata ${diff}`); + } + } + + // Check for unexpected keys in actual (that aren't in expected and aren't skipped) + for (const key of Object.keys(actual)) { + if (skipKeys.includes(key)) continue; + if (!(key in expected)) { + differences.push(`[${slug}] Metadata: unexpected key "${key}" with value ${JSON.stringify(actual[key])}`); + } + } + + return differences; +} + +/** + * Compare body content + */ +function compareBody(expected: string, actual: string, slug: string): string[] { + const differences: string[] = []; + + // Normalize whitespace for comparison + const normalizeContent = (content: string) => { + return content + .replace(/\r\n/g, '\n') // Normalize line endings + .trim(); + }; + + const expectedNorm = normalizeContent(expected); + const actualNorm = normalizeContent(actual); + + if (expectedNorm !== actualNorm) { + // Find specific differences + const expectedLines = expectedNorm.split('\n'); + const actualLines = actualNorm.split('\n'); + + // Report line count difference + if (expectedLines.length !== actualLines.length) { + differences.push(`[${slug}] Body: line count differs - expected ${expectedLines.length}, got ${actualLines.length}`); + } + + // Find first differing line + const minLines = Math.min(expectedLines.length, actualLines.length); + for (let i = 0; i < minLines; i++) { + if (expectedLines[i] !== actualLines[i]) { + differences.push(`[${slug}] Body: line ${i + 1} differs`); + differences.push(` expected: "${expectedLines[i].substring(0, 100)}${expectedLines[i].length > 100 ? '...' : ''}"`); + differences.push(` actual: "${actualLines[i].substring(0, 100)}${actualLines[i].length > 100 ? '...' : ''}"`); + break; // Only report first difference for conciseness + } + } + + // If we didn't find a difference yet but line counts differ, show extra/missing lines + if (differences.length === 1 && expectedLines.length !== actualLines.length) { + if (actualLines.length > expectedLines.length) { + differences.push(`[${slug}] Body: extra lines starting at line ${expectedLines.length + 1}`); + differences.push(` first extra line: "${actualLines[expectedLines.length]?.substring(0, 100) || ''}"`); + } else { + differences.push(`[${slug}] Body: missing lines starting at line ${actualLines.length + 1}`); + differences.push(` first missing line: "${expectedLines[actualLines.length]?.substring(0, 100) || ''}"`); + } + } + } + + return differences; +} + +describe('WXR Reference Comparison E2E Tests', () => { + let executionEngine: ImportExecutionEngine; + let analysisEngine: ImportAnalysisEngine; + let wxrData: WxrData; + + beforeEach(async () => { + // Reset tracking arrays + writtenFiles.length = 0; + insertedPosts.length = 0; + createdTags.length = 0; + uuidCounter = 0; + + // Clear all mocks + vi.clearAllMocks(); + + // Create engine instances + executionEngine = new ImportExecutionEngine(); + executionEngine.setProjectContext('test-project', '/mock/test/data'); + + analysisEngine = new ImportAnalysisEngine(); + analysisEngine.setProjectContext('test-project'); + + // Parse the WXR file + const parser = new WxrParser(); + wxrData = await parser.parseFile(wxrFilePath); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('should parse the WXR file correctly', () => { + // Verify we have posts and pages + expect(wxrData.posts.length).toBeGreaterThan(0); + expect(wxrData.pages.length).toBeGreaterThan(0); + + console.log(`\nParsed WXR file:`); + console.log(` - Posts: ${wxrData.posts.length}`); + console.log(` - Pages: ${wxrData.pages.length}`); + console.log(` - Categories: ${wxrData.categories.length}`); + console.log(` - Tags: ${wxrData.tags.length}`); + console.log(` - Reference files: ${referenceFiles.size}`); + }); + + it('should compare all posts and pages with reference files', async () => { + // Analyze the WXR data + const report = await analysisEngine.analyzeWxr(wxrData, wxrFilePath); + + // Execute the import + const result = await executionEngine.executeImport(report, {}); + + console.log(`\nImport completed:`); + console.log(` - Posts imported: ${result.posts.imported}`); + console.log(` - Pages imported: ${result.pages.imported}`); + console.log(` - Tags created: ${result.tags.created}`); + console.log(` - Files written: ${writtenFiles.length}`); + + // Collect all differences + const allDifferences: string[] = []; + const matchedSlugs: string[] = []; + const unmatchedReferences: string[] = []; + const unmatchedGenerated: string[] = []; + + // Build a map of generated files by slug + const generatedBySlug = new Map(); + for (const file of writtenFiles) { + const filename = path.basename(file.path, '.md'); + generatedBySlug.set(filename, file); + } + + // Compare each reference file with generated output + for (const [slug, refContent] of referenceFiles) { + const generated = generatedBySlug.get(slug); + + if (!generated) { + unmatchedReferences.push(slug); + continue; + } + + matchedSlugs.push(slug); + + // Parse both files + const refParsed = parseFrontmatter(refContent); + const genParsed = parseFrontmatter(generated.content); + + // Compare metadata + const metaDiffs = compareMetadata(refParsed.data, genParsed.data, slug); + allDifferences.push(...metaDiffs); + + // Compare body + const bodyDiffs = compareBody(refParsed.body, genParsed.body, slug); + allDifferences.push(...bodyDiffs); + } + + // Find generated files without reference + for (const slug of generatedBySlug.keys()) { + if (!referenceFiles.has(slug)) { + unmatchedGenerated.push(slug); + } + } + + // Report results + console.log(`\n${'='.repeat(80)}`); + console.log('REFERENCE COMPARISON RESULTS'); + console.log('='.repeat(80)); + + console.log(`\nMatched slugs: ${matchedSlugs.length}`); + if (matchedSlugs.length > 0 && matchedSlugs.length <= 50) { + console.log(` ${matchedSlugs.join(', ')}`); + } + + if (unmatchedReferences.length > 0) { + console.log(`\nReference files without generated output (${unmatchedReferences.length}):`); + for (const slug of unmatchedReferences) { + console.log(` - ${slug}`); + } + } + + if (unmatchedGenerated.length > 0) { + console.log(`\nGenerated files without reference (${unmatchedGenerated.length}):`); + for (const slug of unmatchedGenerated) { + console.log(` - ${slug}`); + } + } + + if (allDifferences.length > 0) { + console.log(`\n${'='.repeat(80)}`); + console.log(`DIFFERENCES FOUND: ${allDifferences.length}`); + console.log('='.repeat(80)); + for (const diff of allDifferences) { + console.log(diff); + } + } else { + console.log(`\n${'='.repeat(80)}`); + console.log('NO DIFFERENCES FOUND - ALL OUTPUTS MATCH REFERENCE FILES'); + console.log('='.repeat(80)); + } + + // Summary statistics + console.log(`\n${'='.repeat(80)}`); + console.log('SUMMARY'); + console.log('='.repeat(80)); + console.log(`Total reference files: ${referenceFiles.size}`); + console.log(`Total generated files: ${generatedBySlug.size}`); + console.log(`Matched: ${matchedSlugs.length}`); + console.log(`Unmatched references: ${unmatchedReferences.length}`); + console.log(`Unmatched generated: ${unmatchedGenerated.length}`); + console.log(`Total differences: ${allDifferences.length}`); + + // The test expects differences - we're reporting them, not failing on them + // The purpose is to analyze the current state of the conversion + expect(true).toBe(true); + }); + + it('should report detailed differences for each post/page', async () => { + // Analyze the WXR data + const report = await analysisEngine.analyzeWxr(wxrData, wxrFilePath); + + // Execute the import + await executionEngine.executeImport(report, {}); + + // Build a map of generated files by slug + const generatedBySlug = new Map(); + for (const file of writtenFiles) { + const filename = path.basename(file.path, '.md'); + generatedBySlug.set(filename, file); + } + + // Detailed comparison for each file + const detailedReport: Array<{ + slug: string; + status: 'match' | 'mismatch' | 'missing-reference' | 'missing-generated'; + metadataDiffs: string[]; + bodyDiffs: string[]; + }> = []; + + for (const [slug, refContent] of referenceFiles) { + const generated = generatedBySlug.get(slug); + + if (!generated) { + detailedReport.push({ + slug, + status: 'missing-generated', + metadataDiffs: ['File not generated during import'], + bodyDiffs: [], + }); + continue; + } + + const refParsed = parseFrontmatter(refContent); + const genParsed = parseFrontmatter(generated.content); + + const metaDiffs = compareMetadata(refParsed.data, genParsed.data, slug); + const bodyDiffs = compareBody(refParsed.body, genParsed.body, slug); + + detailedReport.push({ + slug, + status: metaDiffs.length === 0 && bodyDiffs.length === 0 ? 'match' : 'mismatch', + metadataDiffs: metaDiffs, + bodyDiffs: bodyDiffs, + }); + } + + // Print detailed report + console.log(`\n${'='.repeat(80)}`); + console.log('DETAILED COMPARISON REPORT'); + console.log('='.repeat(80)); + + const matches = detailedReport.filter(r => r.status === 'match'); + const mismatches = detailedReport.filter(r => r.status === 'mismatch'); + const missingGenerated = detailedReport.filter(r => r.status === 'missing-generated'); + + console.log(`\nMatching files (${matches.length}):`); + if (matches.length > 0) { + for (const m of matches) { + console.log(` ✓ ${m.slug}`); + } + } else { + console.log(' (none)'); + } + + console.log(`\nFiles with differences (${mismatches.length}):`); + if (mismatches.length > 0) { + for (const m of mismatches) { + console.log(`\n ✗ ${m.slug}:`); + if (m.metadataDiffs.length > 0) { + console.log(' Metadata differences:'); + for (const d of m.metadataDiffs) { + console.log(` ${d}`); + } + } + if (m.bodyDiffs.length > 0) { + console.log(' Body differences:'); + for (const d of m.bodyDiffs) { + console.log(` ${d}`); + } + } + } + } else { + console.log(' (none)'); + } + + console.log(`\nMissing generated files (${missingGenerated.length}):`); + if (missingGenerated.length > 0) { + for (const m of missingGenerated) { + console.log(` ✗ ${m.slug}`); + } + } else { + console.log(' (none)'); + } + + // Final summary + console.log(`\n${'='.repeat(80)}`); + console.log('FINAL SUMMARY'); + console.log('='.repeat(80)); + console.log(`Total files compared: ${detailedReport.length}`); + console.log(`Perfect matches: ${matches.length}`); + console.log(`Files with differences: ${mismatches.length}`); + console.log(`Missing generated files: ${missingGenerated.length}`); + + // Expect the test to pass - we're just reporting + expect(detailedReport.length).toBeGreaterThan(0); + }); +});