-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add unit tests to app/utils/markdown (#8135)
- Loading branch information
Showing
2 changed files
with
207 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||
// See LICENSE.txt for license information. | ||
|
||
import {Platform, type TextStyle} from 'react-native'; | ||
|
||
import {Preferences} from '@constants'; | ||
|
||
import { | ||
getCodeFont, | ||
getMarkdownTextStyles, | ||
getMarkdownBlockStyles, | ||
getHighlightLanguageFromNameOrAlias, | ||
getHighlightLanguageName, | ||
escapeRegex, | ||
getMarkdownImageSize, | ||
computeTextStyle, | ||
parseSearchTerms, | ||
convertSearchTermToRegex, | ||
} from './index'; | ||
|
||
jest.mock('@utils/images', () => ({ | ||
getViewPortWidth: jest.fn(), | ||
})); | ||
|
||
jest.mock('@utils/log', () => ({ | ||
logError: jest.fn(), | ||
})); | ||
|
||
describe('Utility functions', () => { | ||
describe('getCodeFont', () => { | ||
it('should return the correct font for iOS', () => { | ||
Platform.OS = 'ios'; | ||
expect(getCodeFont()).toBe('Menlo'); | ||
}); | ||
|
||
it('should return the correct font for Android', () => { | ||
Platform.OS = 'android'; | ||
expect(getCodeFont()).toBe('monospace'); | ||
}); | ||
}); | ||
|
||
describe('getMarkdownTextStyles', () => { | ||
it('should return correct text styles', () => { | ||
const styles = getMarkdownTextStyles(Preferences.THEMES.denim); | ||
expect(styles).toHaveProperty('emph'); | ||
expect(styles).toHaveProperty('strong'); | ||
expect(styles).toHaveProperty('del'); | ||
expect(styles).toHaveProperty('link'); | ||
expect(styles).toHaveProperty('heading1'); | ||
expect(styles).toHaveProperty('code'); | ||
expect(styles).toHaveProperty('mention'); | ||
expect(styles).toHaveProperty('error'); | ||
expect(styles).toHaveProperty('table_header_row'); | ||
expect(styles).toHaveProperty('mention_highlight'); | ||
}); | ||
}); | ||
|
||
describe('getMarkdownBlockStyles', () => { | ||
it('should return correct block styles', () => { | ||
const styles = getMarkdownBlockStyles(Preferences.THEMES.denim); | ||
expect(styles).toHaveProperty('adjacentParagraph'); | ||
expect(styles).toHaveProperty('horizontalRule'); | ||
expect(styles).toHaveProperty('quoteBlockIcon'); | ||
}); | ||
}); | ||
|
||
describe('getHighlightLanguageFromNameOrAlias', () => { | ||
it('should return correct language name or alias', () => { | ||
expect(getHighlightLanguageFromNameOrAlias('javascript')).toBe('javascript'); | ||
expect(getHighlightLanguageFromNameOrAlias('js')).toBe('javascript'); | ||
expect(getHighlightLanguageFromNameOrAlias('unknown')).toBe(''); | ||
}); | ||
}); | ||
|
||
describe('getHighlightLanguageName', () => { | ||
it('should return correct language name', () => { | ||
expect(getHighlightLanguageName('javascript')).toBe('JavaScript'); | ||
expect(getHighlightLanguageName('unknown')).toBe(''); | ||
}); | ||
}); | ||
|
||
describe('escapeRegex', () => { | ||
it('should escape special regex characters', () => { | ||
expect(escapeRegex('hello.*')).toBe('hello\\.\\*'); | ||
}); | ||
}); | ||
|
||
describe('getMarkdownImageSize', () => { | ||
it('should return correct size for sourceSize', () => { | ||
const size = getMarkdownImageSize(false, false, {width: 100, height: 200}); | ||
expect(size).toEqual({width: 100, height: 200}); | ||
}); | ||
|
||
it('should return correct size for sourceSize without height', () => { | ||
const size = getMarkdownImageSize(false, false, {width: 100}); | ||
expect(size).toEqual({width: 100, height: 100}); | ||
}); | ||
|
||
it('should return correct size for sourceSize without height and known size', () => { | ||
const size = getMarkdownImageSize(false, false, {width: 100}, {width: 100, height: 200}); | ||
expect(size).toEqual({width: 100, height: 200}); | ||
}); | ||
|
||
it('should return correct size for sourceSize height height and known size', () => { | ||
const size = getMarkdownImageSize(false, false, {height: 100}, {width: 100, height: 200}); | ||
expect(size).toEqual({width: 50, height: 100}); | ||
}); | ||
|
||
it('should return correct size for knownSize', () => { | ||
const size = getMarkdownImageSize(false, false, undefined, {width: 100, height: 200}); | ||
expect(size).toEqual({width: 100, height: 200}); | ||
}); | ||
|
||
it('should return correct size when no metadata and source size is not specified', () => { | ||
const size = getMarkdownImageSize(false, false, undefined, undefined, 150, 250); | ||
expect(size).toEqual({width: 150, height: 250}); | ||
}); | ||
}); | ||
|
||
describe('computeTextStyle', () => { | ||
const textStyles: { [key: string]: TextStyle } = { | ||
bold: {fontWeight: 'bold'}, | ||
italic: {fontStyle: 'italic'}, | ||
underline: {textDecorationLine: 'underline'}, | ||
}; | ||
|
||
const baseStyle: TextStyle = {color: 'black'}; | ||
|
||
it('should return base style if context is empty', () => { | ||
expect(computeTextStyle(textStyles, baseStyle, [])).toEqual(baseStyle); | ||
}); | ||
|
||
it('should return base style if context has no matching styles', () => { | ||
expect(computeTextStyle(textStyles, baseStyle, ['unknown'])).toEqual(baseStyle); | ||
}); | ||
|
||
it('should apply a single context style', () => { | ||
expect(computeTextStyle(textStyles, baseStyle, ['bold'])).toEqual([baseStyle, textStyles.bold]); | ||
}); | ||
|
||
it('should apply multiple context styles', () => { | ||
expect(computeTextStyle(textStyles, baseStyle, ['bold', 'italic'])).toEqual([baseStyle, textStyles.bold, textStyles.italic]); | ||
}); | ||
|
||
it('should ignore undefined styles', () => { | ||
expect(computeTextStyle(textStyles, baseStyle, ['bold', 'unknown'])).toEqual([baseStyle, textStyles.bold]); | ||
}); | ||
|
||
it('should handle multiple undefined styles', () => { | ||
expect(computeTextStyle(textStyles, baseStyle, ['unknown1', 'unknown2'])).toEqual(baseStyle); | ||
}); | ||
}); | ||
|
||
describe('parseSearchTerms', () => { | ||
it('should capture quoted strings', () => { | ||
expect(parseSearchTerms('"hello world"')).toEqual(['hello world']); | ||
}); | ||
|
||
it('should ignore search flags', () => { | ||
expect(parseSearchTerms('in:channel before:2021-01-01')).toEqual([]); | ||
}); | ||
|
||
it('should capture @ mentions', () => { | ||
expect(parseSearchTerms('@username')).toEqual(['username']); | ||
}); | ||
|
||
it('should capture plain text up to the next quote or search flag', () => { | ||
expect(parseSearchTerms('plain text "quoted text"')).toEqual(['plain', 'text', 'quoted text']); | ||
}); | ||
|
||
it('should split plain text into words', () => { | ||
expect(parseSearchTerms('this is a test')).toEqual(['this', 'is', 'a', 'test']); | ||
}); | ||
|
||
it('should handle a mix of all cases', () => { | ||
const searchTerm = 'in:channel @username "quoted text" plain text'; | ||
const expected = ['username', 'quoted text', 'plain', 'text']; | ||
expect(parseSearchTerms(searchTerm)).toEqual(expected); | ||
}); | ||
}); | ||
|
||
describe('convertSearchTermToRegex', () => { | ||
it('should create regex for CJK characters', () => { | ||
const result = convertSearchTermToRegex('你好'); | ||
expect(result.pattern).toEqual(/()(你好)/gi); | ||
}); | ||
|
||
it('should create regex for wildcard at the end', () => { | ||
const result = convertSearchTermToRegex('hello*'); | ||
expect(result.pattern).toEqual(/\b()(hello)/gi); | ||
}); | ||
|
||
it('should create regex for mentions and hashtags', () => { | ||
const result = convertSearchTermToRegex('@user'); | ||
expect(result.pattern).toEqual(/(\W|^)(@user)\b/gi); | ||
}); | ||
|
||
it('should create regex for plain text', () => { | ||
const result = convertSearchTermToRegex('hello'); | ||
expect(result.pattern).toEqual(/\b()(hello)\b/gi); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters