refactor: change return type of frontmatter extractor to use undefined

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2023-05-19 19:41:25 +02:00
parent 77f858bff8
commit 4d0a2cb79e
5 changed files with 29 additions and 56 deletions

View file

@ -4,7 +4,6 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { extractFrontmatter } from './extractor.js'
import type { PresentFrontmatterExtractionResult } from './types.js'
import { describe, expect, it } from '@jest/globals'
describe('frontmatter extraction', () => {
@ -12,22 +11,22 @@ describe('frontmatter extraction', () => {
it('is false when note does not contain three dashes at all', () => {
const testNote = ['abcdef', 'more text']
const extraction = extractFrontmatter(testNote)
expect(extraction.isPresent).toBe(false)
expect(extraction).toBeUndefined()
})
it('is false when note does not start with three dashes', () => {
const testNote = ['', '---', 'this is not frontmatter']
const extraction = extractFrontmatter(testNote)
expect(extraction.isPresent).toBe(false)
expect(extraction).toBeUndefined()
})
it('is false when note start with less than three dashes', () => {
const testNote = ['--', 'this is not frontmatter']
const extraction = extractFrontmatter(testNote)
expect(extraction.isPresent).toBe(false)
expect(extraction).toBeUndefined()
})
it('is false when note starts with three dashes but contains other characters in the same line', () => {
const testNote = ['--- a', 'this is not frontmatter']
const extraction = extractFrontmatter(testNote)
expect(extraction.isPresent).toBe(false)
expect(extraction).toBeUndefined()
})
it('is false when note has no ending marker for frontmatter', () => {
const testNote = [
@ -38,75 +37,63 @@ describe('frontmatter extraction', () => {
'end marker'
]
const extraction = extractFrontmatter(testNote)
expect(extraction.isPresent).toBe(false)
expect(extraction).toBeUndefined()
})
it('is false when note end marker is present but with not the same amount of dashes as start marker', () => {
const testNote = ['---', 'this is not frontmatter', '----', 'content']
const extraction = extractFrontmatter(testNote)
expect(extraction.isPresent).toBe(false)
expect(extraction).toBeUndefined()
})
it('is true when note end marker is present with the same amount of dashes as start marker', () => {
const testNote = ['---', 'this is frontmatter', '---', 'content']
const extraction = extractFrontmatter(testNote)
expect(extraction.isPresent).toBe(true)
expect(extraction).toBeDefined()
})
it('is true when note end marker is present with the same amount of dashes as start marker but without content', () => {
const testNote = ['---', 'this is frontmatter', '---']
const extraction = extractFrontmatter(testNote)
expect(extraction.isPresent).toBe(true)
expect(extraction).toBeDefined()
})
it('is true when note end marker is present with the same amount of dots as start marker', () => {
const testNote = ['---', 'this is frontmatter', '...', 'content']
const extraction = extractFrontmatter(testNote)
expect(extraction.isPresent).toBe(true)
expect(extraction).toBeDefined()
})
})
describe('lineOffset property', () => {
it('is correct for single line frontmatter without content', () => {
const testNote = ['---', 'single line frontmatter', '...']
const extraction = extractFrontmatter(
testNote
) as PresentFrontmatterExtractionResult
expect(extraction.lineOffset).toEqual(3)
const extraction = extractFrontmatter(testNote)
expect(extraction?.lineOffset).toEqual(3)
})
it('is correct for single line frontmatter with content', () => {
const testNote = ['---', 'single line frontmatter', '...', 'content']
const extraction = extractFrontmatter(
testNote
) as PresentFrontmatterExtractionResult
expect(extraction.lineOffset).toEqual(3)
const extraction = extractFrontmatter(testNote)
expect(extraction?.lineOffset).toEqual(3)
})
it('is correct for multi-line frontmatter without content', () => {
const testNote = ['---', 'abc', '123', 'def', '...']
const extraction = extractFrontmatter(
testNote
) as PresentFrontmatterExtractionResult
expect(extraction.lineOffset).toEqual(5)
const extraction = extractFrontmatter(testNote)
expect(extraction?.lineOffset).toEqual(5)
})
it('is correct for multi-line frontmatter with content', () => {
const testNote = ['---', 'abc', '123', 'def', '...', 'content']
const extraction = extractFrontmatter(
testNote
) as PresentFrontmatterExtractionResult
expect(extraction.lineOffset).toEqual(5)
const extraction = extractFrontmatter(testNote)
expect(extraction?.lineOffset).toEqual(5)
})
})
describe('rawText property', () => {
it('contains single-line frontmatter text', () => {
const testNote = ['---', 'single-line', '...', 'content']
const extraction = extractFrontmatter(
testNote
) as PresentFrontmatterExtractionResult
expect(extraction.rawText).toEqual('single-line')
const extraction = extractFrontmatter(testNote)
expect(extraction?.rawText).toEqual('single-line')
})
it('contains multi-line frontmatter text', () => {
const testNote = ['---', 'multi', 'line', '...', 'content']
const extraction = extractFrontmatter(
testNote
) as PresentFrontmatterExtractionResult
expect(extraction.rawText).toEqual('multi\nline')
const extraction = extractFrontmatter(testNote)
expect(extraction?.rawText).toEqual('multi\nline')
})
})
})

View file

@ -20,11 +20,9 @@ const FRONTMATTER_END_REGEX = /^(?:-{3,}|\.{3,})$/
*/
export const extractFrontmatter = (
lines: string[]
): FrontmatterExtractionResult => {
): FrontmatterExtractionResult | undefined => {
if (lines.length < 2 || !FRONTMATTER_BEGIN_REGEX.test(lines[0])) {
return {
isPresent: false
}
return undefined
}
for (let i = 1; i < lines.length; i++) {
if (
@ -32,13 +30,10 @@ export const extractFrontmatter = (
FRONTMATTER_END_REGEX.test(lines[i])
) {
return {
isPresent: true,
rawText: lines.slice(1, i).join('\n'),
lineOffset: i + 1
}
}
}
return {
isPresent: false
}
return undefined
}

View file

@ -4,16 +4,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
export type FrontmatterExtractionResult =
| PresentFrontmatterExtractionResult
| NonPresentFrontmatterExtractionResult
export interface PresentFrontmatterExtractionResult {
isPresent: true
export interface FrontmatterExtractionResult {
rawText: string
lineOffset: number
}
interface NonPresentFrontmatterExtractionResult {
isPresent: false
}

View file

@ -20,7 +20,7 @@ export class FrontmatterLinter implements Linter {
lint(view: EditorView): Diagnostic[] {
const lines = view.state.doc.toString().split('\n')
const frontmatterExtraction = extractFrontmatter(lines)
if (!frontmatterExtraction.isPresent) {
if (frontmatterExtraction === undefined) {
return []
}
const startOfYaml = lines[0].length + 1

View file

@ -8,7 +8,7 @@ import { initialState } from './initial-state'
import { createNoteFrontmatterFromYaml } from './raw-note-frontmatter-parser/parser'
import type { NoteDetails } from './types/note-details'
import { extractFrontmatter, generateNoteTitle } from '@hedgedoc/commons'
import type { PresentFrontmatterExtractionResult } from '@hedgedoc/commons'
import type { FrontmatterExtractionResult } from '@hedgedoc/commons'
/**
* Copies a {@link NoteDetails} but with another markdown content.
@ -40,7 +40,7 @@ const buildStateFromMarkdownContentAndLines = (
): NoteDetails => {
const frontmatterExtraction = extractFrontmatter(markdownContentLines)
const lineStartIndexes = calculateLineStartIndexes(markdownContentLines)
if (frontmatterExtraction.isPresent) {
if (frontmatterExtraction !== undefined) {
return buildStateFromFrontmatterUpdate(
{
...state,
@ -76,7 +76,7 @@ const buildStateFromMarkdownContentAndLines = (
*/
const buildStateFromFrontmatterUpdate = (
state: NoteDetails,
frontmatterExtraction: PresentFrontmatterExtractionResult
frontmatterExtraction: FrontmatterExtractionResult
): NoteDetails => {
if (frontmatterExtraction.rawText === state.rawFrontmatter) {
return state