diff --git a/packages/lib/jest.config.js b/packages/lib/jest.config.js index 10680d038f..742dc95b6b 100644 --- a/packages/lib/jest.config.js +++ b/packages/lib/jest.config.js @@ -11,6 +11,9 @@ module.exports = { testEnvironment: 'node', - setupFilesAfterEnv: [`${__dirname}/jest.setup.js`], + setupFilesAfterEnv: [ + 'jest-expect-message', + `${__dirname}/jest.setup.js`, + ], slowTestThreshold: 40, }; diff --git a/packages/lib/package.json b/packages/lib/package.json index 6f981bd5c7..bb145ef221 100644 --- a/packages/lib/package.json +++ b/packages/lib/package.json @@ -20,6 +20,7 @@ "@types/adm-zip": "0.5.7", "@types/fs-extra": "11.0.4", "@types/jest": "29.5.12", + "@types/jest-expect-message": "1.1.0", "@types/js-yaml": "4.0.9", "@types/jsdom": "21.1.7", "@types/markdown-it": "13.0.9", @@ -31,6 +32,7 @@ "canvas": "2.11.2", "clean-html": "1.5.0", "jest": "29.7.0", + "jest-expect-message": "1.1.3", "jsdom": "23.2.0", "pdfjs-dist": "3.11.174", "react": "18.3.1", diff --git a/packages/lib/services/interop/InteropService_Importer_OneNote.test.ts b/packages/lib/services/interop/InteropService_Importer_OneNote.test.ts index 766c1c168e..b15c747c3a 100644 --- a/packages/lib/services/interop/InteropService_Importer_OneNote.test.ts +++ b/packages/lib/services/interop/InteropService_Importer_OneNote.test.ts @@ -10,6 +10,18 @@ import InteropService_Importer_OneNote from './InteropService_Importer_OneNote'; import { JSDOM } from 'jsdom'; import { ImportModuleOutputFormat } from './types'; +const instructionMessage = ` +-------------------------------------- +IF THIS IS FAILING IN THE CI +you can test it locally +Check packages/onenote-converter/README.md for more instructions +-------------------------------------- +`; + +const expectWithInstructions = (value: T) => { + return expect(value, instructionMessage); +}; + // We don't require all developers to have Rust to run the project, so we skip this test if not running in CI const skipIfNotCI = process.env.IS_CONTINUOUS_INTEGRATION ? it : it.skip; @@ -44,17 +56,17 @@ describe('InteropService_Importer_OneNote', () => { const notes = await importNote(`${supportDir}/onenote/simple_notebook.zip`); const folders = await Folder.all(); - expect(notes.length).toBe(2); + expectWithInstructions(notes.length).toBe(2); const mainNote = notes[0]; - expect(folders.length).toBe(3); + expectWithInstructions(folders.length).toBe(3); const parentFolder = folders.find(f => f.id === mainNote.parent_id); - expect(parentFolder.title).toBe('Section title'); - expect(folders.find(f => f.id === parentFolder.parent_id).title).toBe('Simple notebook'); + expectWithInstructions(parentFolder.title).toBe('Section title'); + expectWithInstructions(folders.find(f => f.id === parentFolder.parent_id).title).toBe('Simple notebook'); - expect(mainNote.title).toBe('Page title'); - expect(mainNote.markup_language).toBe(MarkupToHtml.MARKUP_LANGUAGE_HTML); - expect(mainNote.body).toMatchSnapshot(mainNote.title); + expectWithInstructions(mainNote.title).toBe('Page title'); + expectWithInstructions(mainNote.markup_language).toBe(MarkupToHtml.MARKUP_LANGUAGE_HTML); + expectWithInstructions(mainNote.body).toMatchSnapshot(mainNote.title); }); skipIfNotCI('should preserve indentation of subpages in Section page', async () => { @@ -65,16 +77,16 @@ describe('InteropService_Importer_OneNote', () => { const menuLines = menuHtml.split(''); const pageTwo = notes.find(n => n.title === 'Page 2'); - expect(menuLines[3].trim()).toBe(`
  • ${pageTwo.title}`); + expectWithInstructions(menuLines[3].trim()).toBe(`
  • ${pageTwo.title}`); const pageTwoA = notes.find(n => n.title === 'Page 2-a'); - expect(menuLines[4].trim()).toBe(`
  • ${pageTwoA.title}`); + expectWithInstructions(menuLines[4].trim()).toBe(`
  • ${pageTwoA.title}`); const pageTwoAA = notes.find(n => n.title === 'Page 2-a-a'); - expect(menuLines[5].trim()).toBe(`
  • ${pageTwoAA.title}`); + expectWithInstructions(menuLines[5].trim()).toBe(`
  • ${pageTwoAA.title}`); const pageTwoB = notes.find(n => n.title === 'Page 2-b'); - expect(menuLines[7].trim()).toBe(`
  • ${pageTwoB.title}`); + expectWithInstructions(menuLines[7].trim()).toBe(`
  • ${pageTwoB.title}`); }); skipIfNotCI('should created subsections', async () => { @@ -87,12 +99,12 @@ describe('InteropService_Importer_OneNote', () => { const subSection2 = folders.find(f => f.title === 'Subsection 2'); const notesFromParentSection = notes.filter(n => n.parent_id === parentSection.id); - expect(parentSection.id).toBe(subSection1.parent_id); - expect(parentSection.id).toBe(subSection2.parent_id); - expect(parentSection.id).toBe(subSection.parent_id); - expect(folders.length).toBe(7); - expect(notes.length).toBe(6); - expect(notesFromParentSection.length).toBe(2); + expectWithInstructions(parentSection.id).toBe(subSection1.parent_id); + expectWithInstructions(parentSection.id).toBe(subSection2.parent_id); + expectWithInstructions(parentSection.id).toBe(subSection.parent_id); + expectWithInstructions(folders.length).toBe(7); + expectWithInstructions(notes.length).toBe(6); + expectWithInstructions(notesFromParentSection.length).toBe(2); }); skipIfNotCI('should expect notes to be rendered the same', async () => { @@ -102,12 +114,12 @@ describe('InteropService_Importer_OneNote', () => { const folders = await Folder.all(); const parentSection = folders.find(f => f.title === 'Quick Notes'); - expect(folders.length).toBe(3); - expect(notes.length).toBe(7); - expect(notes.filter(n => n.parent_id === parentSection.id).length).toBe(6); + expectWithInstructions(folders.length).toBe(3); + expectWithInstructions(notes.length).toBe(7); + expectWithInstructions(notes.filter(n => n.parent_id === parentSection.id).length).toBe(6); for (const note of notes) { - expect(note.body).toMatchSnapshot(note.title); + expectWithInstructions(note.body).toMatchSnapshot(note.title); } BaseModel.setIdGenerator(originalIdGenerator); }); @@ -125,19 +137,19 @@ describe('InteropService_Importer_OneNote', () => { const sectionD1 = folders.find(f => f.title === 'Section D1'); const sectionD = folders.find(f => f.title === 'Section D'); - expect(section.parent_id).toBe(mainFolder.id); - expect(sectionA.parent_id).toBe(mainFolder.id); - expect(sectionD.parent_id).toBe(mainFolder.id); + expectWithInstructions(section.parent_id).toBe(mainFolder.id); + expectWithInstructions(sectionA.parent_id).toBe(mainFolder.id); + expectWithInstructions(sectionD.parent_id).toBe(mainFolder.id); - expect(sectionA1.parent_id).toBe(sectionA.id); - expect(sectionB.parent_id).toBe(sectionA.id); + expectWithInstructions(sectionA1.parent_id).toBe(sectionA.id); + expectWithInstructions(sectionB.parent_id).toBe(sectionA.id); - expect(sectionB1.parent_id).toBe(sectionB.id); - expect(sectionD1.parent_id).toBe(sectionD.id); + expectWithInstructions(sectionB1.parent_id).toBe(sectionB.id); + expectWithInstructions(sectionD1.parent_id).toBe(sectionD.id); - expect(notes.filter(n => n.parent_id === sectionA1.id).length).toBe(2); - expect(notes.filter(n => n.parent_id === sectionB1.id).length).toBe(2); - expect(notes.filter(n => n.parent_id === sectionD1.id).length).toBe(1); + expectWithInstructions(notes.filter(n => n.parent_id === sectionA1.id).length).toBe(2); + expectWithInstructions(notes.filter(n => n.parent_id === sectionB1.id).length).toBe(2); + expectWithInstructions(notes.filter(n => n.parent_id === sectionD1.id).length).toBe(1); }); skipIfNotCI.each([ @@ -164,7 +176,7 @@ describe('InteropService_Importer_OneNote', () => { xmlSerializer: new jsdom.window.XMLSerializer(), }); - expect(importer.extractSvgs(content, titleGenerator())).toMatchSnapshot(); + expectWithInstructions(importer.extractSvgs(content, titleGenerator())).toMatchSnapshot(); }); skipIfNotCI('should ignore broken characters at the start of paragraph', async () => { @@ -172,7 +184,7 @@ describe('InteropService_Importer_OneNote', () => { const originalIdGenerator = BaseModel.setIdGenerator(() => String(idx++)); const notes = await importNote(`${supportDir}/onenote/bug_broken_character.zip`); - expect(notes.find(n => n.title === 'Action research - Wikipedia').body).toMatchSnapshot(); + expectWithInstructions(notes.find(n => n.title === 'Action research - Wikipedia').body).toMatchSnapshot(); BaseModel.setIdGenerator(originalIdGenerator); }); @@ -183,7 +195,7 @@ describe('InteropService_Importer_OneNote', () => { const notes = await importNote(`${supportDir}/onenote/remove_hyperlink_on_title.zip`); for (const note of notes) { - expect(note.body).toMatchSnapshot(note.title); + expectWithInstructions(note.body).toMatchSnapshot(note.title); } BaseModel.setIdGenerator(originalIdGenerator); }); @@ -193,8 +205,8 @@ describe('InteropService_Importer_OneNote', () => { const noteToTest = notes.find(n => n.title === 'Tips from a Pro Using Trees for Dramatic Landscape Photography'); - expect(noteToTest).toBeTruthy(); - expect(noteToTest.body.includes('Tips from a Pro: Using Trees for Dramatic Landscape Photography')).toBe(true); + expectWithInstructions(noteToTest).toBeTruthy(); + expectWithInstructions(noteToTest.body.includes('Tips from a Pro: Using Trees for Dramatic Landscape Photography')).toBe(true); }); skipIfNotCI('should render links properly by ignoring wrongly set indices when the first character is a hyperlink marker', async () => { @@ -203,7 +215,7 @@ describe('InteropService_Importer_OneNote', () => { const notes = await importNote(`${supportDir}/onenote/hyperlink_marker_as_first_character.zip`); for (const note of notes) { - expect(note.body).toMatchSnapshot(note.title); + expectWithInstructions(note.body).toMatchSnapshot(note.title); } BaseModel.setIdGenerator(originalIdGenerator); }); @@ -213,10 +225,10 @@ describe('InteropService_Importer_OneNote', () => { const originalIdGenerator = BaseModel.setIdGenerator(() => String(idx++)); const notes = await importNote(`${supportDir}/onenote/corrupted_attachment.zip`); - expect(notes.length).toBe(2); + expectWithInstructions(notes.length).toBe(2); for (const note of notes) { - expect(note.body).toMatchSnapshot(note.title); + expectWithInstructions(note.body).toMatchSnapshot(note.title); } BaseModel.setIdGenerator(originalIdGenerator); }); @@ -226,10 +238,10 @@ describe('InteropService_Importer_OneNote', () => { const originalIdGenerator = BaseModel.setIdGenerator(() => String(idx++)); const notes = await importNote(`${supportDir}/onenote/note_with_audio_embedded.zip`); - expect(notes.length).toBe(2); + expectWithInstructions(notes.length).toBe(2); for (const note of notes) { - expect(note.body).toMatchSnapshot(note.title); + expectWithInstructions(note.body).toMatchSnapshot(note.title); } BaseModel.setIdGenerator(originalIdGenerator); }); diff --git a/packages/onenote-converter/README.md b/packages/onenote-converter/README.md index 533bc0127b..2ed57c6175 100644 --- a/packages/onenote-converter/README.md +++ b/packages/onenote-converter/README.md @@ -56,12 +56,27 @@ To work with the project you will need: - Rust https://www.rust-lang.org/learn/get-started +### Running tests + +Tests for the project are located in the `lib` packages, but to make it work it is necessary to build this project first: + +`IS_CONTINUOUS_INTEGRATION=1 yarn build # for production build` +or +`IS_CONTINUOUS_INTEGRATION=1 yarn buildDev # for build with more logs and compiles faster` + +After that you should navigate to `lib` package and run the tests of `InteropService_Importer_OneNote.test.` file + +``` +cd ../lib +IS_CONTINUOUS_INTEGRATION=1 yarn test services/interop/InteropService_Importer_OneNote.test. +``` + +### Developing + When working with the Rust code you will probably rather run `yarn buildDev` since it is faster and it has more logging messages (they can be disabled in the macro `log!()`) During development, it will be easier to test it where this library is called. `InteropService_Importer_Onenote.ts` is the code that depends on this and already has some tests. -### Running tests and IS_CONTINUOUS_INTEGRATION - We don't require developers that won't work on this project to have Rust installed on their machine. To make this work we: diff --git a/yarn.lock b/yarn.lock index 071d63d794..f4d821ad03 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9046,6 +9046,7 @@ __metadata: "@types/adm-zip": 0.5.7 "@types/fs-extra": 11.0.4 "@types/jest": 29.5.12 + "@types/jest-expect-message": 1.1.0 "@types/js-yaml": 4.0.9 "@types/jsdom": 21.1.7 "@types/markdown-it": 13.0.9 @@ -9078,6 +9079,7 @@ __metadata: image-data-uri: 2.0.1 immer: 9.0.21 jest: 29.7.0 + jest-expect-message: 1.1.3 js-yaml: 4.1.0 jsdom: 23.2.0 markdown-it: 13.0.2