diff options
Diffstat (limited to 'spec/javascripts/gl_emoji_spec.js')
-rw-r--r-- | spec/javascripts/gl_emoji_spec.js | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/spec/javascripts/gl_emoji_spec.js b/spec/javascripts/gl_emoji_spec.js new file mode 100644 index 00000000000..e94e220b19f --- /dev/null +++ b/spec/javascripts/gl_emoji_spec.js @@ -0,0 +1,367 @@ + +require('~/extensions/string'); +require('~/extensions/array'); + +const glEmoji = require('~/behaviors/gl_emoji'); + +const glEmojiTag = glEmoji.glEmojiTag; +const isEmojiUnicodeSupported = glEmoji.isEmojiUnicodeSupported; +const isFlagEmoji = glEmoji.isFlagEmoji; +const isKeycapEmoji = glEmoji.isKeycapEmoji; +const isSkinToneComboEmoji = glEmoji.isSkinToneComboEmoji; +const isHorceRacingSkinToneComboEmoji = glEmoji.isHorceRacingSkinToneComboEmoji; +const isPersonZwjEmoji = glEmoji.isPersonZwjEmoji; + +const emptySupportMap = { + personZwj: false, + horseRacing: false, + flag: false, + skinToneModifier: false, + '9.0': false, + '8.0': false, + '7.0': false, + 6.1: false, + '6.0': false, + 5.2: false, + 5.1: false, + 4.1: false, + '4.0': false, + 3.2: false, + '3.0': false, + 1.1: false, +}; + +const emojiFixtureMap = { + bomb: { + name: 'bomb', + moji: 'π£', + unicodeVersion: '6.0', + }, + construction_worker_tone5: { + name: 'construction_worker_tone5', + moji: 'π·πΏ', + unicodeVersion: '8.0', + }, + five: { + name: 'five', + moji: '5οΈβ£', + unicodeVersion: '3.0', + }, +}; + +function markupToDomElement(markup) { + const div = document.createElement('div'); + div.innerHTML = markup; + return div.firstElementChild; +} + +function testGlEmojiImageFallback(element, name, src) { + expect(element.tagName.toLowerCase()).toBe('img'); + expect(element.getAttribute('src')).toBe(src); + expect(element.getAttribute('title')).toBe(`:${name}:`); + expect(element.getAttribute('alt')).toBe(`:${name}:`); +} + +const defaults = { + forceFallback: false, + sprite: false, +}; + +function testGlEmojiElement(element, name, unicodeVersion, unicodeMoji, options = {}) { + const opts = Object.assign({}, defaults, options); + expect(element.tagName.toLowerCase()).toBe('gl-emoji'); + expect(element.dataset.name).toBe(name); + expect(element.dataset.fallbackSrc.length).toBeGreaterThan(0); + expect(element.dataset.unicodeVersion).toBe(unicodeVersion); + + const fallbackSpriteClass = `emoji-${name}`; + if (opts.sprite) { + expect(element.dataset.fallbackSpriteClass).toBe(fallbackSpriteClass); + } + + if (opts.forceFallback && opts.sprite) { + expect(element.getAttribute('class')).toBe(`emoji-icon ${fallbackSpriteClass}`); + } + + if (opts.forceFallback && !opts.sprite) { + // Check for image fallback + testGlEmojiImageFallback(element.firstElementChild, name, element.dataset.fallbackSrc); + } else { + // Otherwise make sure things are still unicode text + expect(element.textContent.trim()).toBe(unicodeMoji); + } +} + +describe('gl_emoji', () => { + describe('glEmojiTag', () => { + it('bomb emoji', () => { + const emojiKey = 'bomb'; + const markup = glEmojiTag(emojiFixtureMap[emojiKey].name); + const glEmojiElement = markupToDomElement(markup); + testGlEmojiElement( + glEmojiElement, + emojiFixtureMap[emojiKey].name, + emojiFixtureMap[emojiKey].unicodeVersion, + emojiFixtureMap[emojiKey].moji, + ); + }); + + it('bomb emoji with image fallback', () => { + const emojiKey = 'bomb'; + const markup = glEmojiTag(emojiFixtureMap[emojiKey].name, { + forceFallback: true, + }); + const glEmojiElement = markupToDomElement(markup); + testGlEmojiElement( + glEmojiElement, + emojiFixtureMap[emojiKey].name, + emojiFixtureMap[emojiKey].unicodeVersion, + emojiFixtureMap[emojiKey].moji, + { + forceFallback: true, + }, + ); + }); + + it('bomb emoji with sprite fallback readiness', () => { + const emojiKey = 'bomb'; + const markup = glEmojiTag(emojiFixtureMap[emojiKey].name, { + sprite: true, + }); + const glEmojiElement = markupToDomElement(markup); + testGlEmojiElement( + glEmojiElement, + emojiFixtureMap[emojiKey].name, + emojiFixtureMap[emojiKey].unicodeVersion, + emojiFixtureMap[emojiKey].moji, + { + sprite: true, + }, + ); + }); + it('bomb emoji with sprite fallback', () => { + const emojiKey = 'bomb'; + const markup = glEmojiTag(emojiFixtureMap[emojiKey].name, { + forceFallback: true, + sprite: true, + }); + const glEmojiElement = markupToDomElement(markup); + testGlEmojiElement( + glEmojiElement, + emojiFixtureMap[emojiKey].name, + emojiFixtureMap[emojiKey].unicodeVersion, + emojiFixtureMap[emojiKey].moji, + { + forceFallback: true, + sprite: true, + }, + ); + }); + }); + + describe('isFlagEmoji', () => { + it('should detect flag_ac', () => { + expect(isFlagEmoji('π¦π¨')).toBeTruthy(); + }); + it('should detect flag_us', () => { + expect(isFlagEmoji('πΊπΈ')).toBeTruthy(); + }); + it('should detect flag_zw', () => { + expect(isFlagEmoji('πΏπΌ')).toBeTruthy(); + }); + it('should not detect flags', () => { + expect(isFlagEmoji('π')).toBeFalsy(); + }); + it('should not detect triangular_flag_on_post', () => { + expect(isFlagEmoji('π©')).toBeFalsy(); + }); + it('should not detect single letter', () => { + expect(isFlagEmoji('π¦')).toBeFalsy(); + }); + it('should not detect >2 letters', () => { + expect(isFlagEmoji('π¦π§π¨')).toBeFalsy(); + }); + }); + + describe('isKeycapEmoji', () => { + it('should detect one(keycap)', () => { + expect(isKeycapEmoji('1οΈβ£')).toBeTruthy(); + }); + it('should detect nine(keycap)', () => { + expect(isKeycapEmoji('9οΈβ£')).toBeTruthy(); + }); + it('should not detect ten(keycap)', () => { + expect(isKeycapEmoji('π')).toBeFalsy(); + }); + it('should not detect hash(keycap)', () => { + expect(isKeycapEmoji('#β£')).toBeFalsy(); + }); + }); + + describe('isSkinToneComboEmoji', () => { + it('should detect hand_splayed_tone5', () => { + expect(isSkinToneComboEmoji('ππΏ')).toBeTruthy(); + }); + it('should not detect hand_splayed', () => { + expect(isSkinToneComboEmoji('π')).toBeFalsy(); + }); + it('should detect lifter_tone1', () => { + expect(isSkinToneComboEmoji('ππ»')).toBeTruthy(); + }); + it('should not detect lifter', () => { + expect(isSkinToneComboEmoji('π')).toBeFalsy(); + }); + it('should detect rowboat_tone4', () => { + expect(isSkinToneComboEmoji('π£πΎ')).toBeTruthy(); + }); + it('should not detect rowboat', () => { + expect(isSkinToneComboEmoji('π£')).toBeFalsy(); + }); + it('should not detect individual tone emoji', () => { + expect(isSkinToneComboEmoji('π»')).toBeFalsy(); + }); + }); + + describe('isHorceRacingSkinToneComboEmoji', () => { + it('should detect horse_racing_tone2', () => { + expect(isHorceRacingSkinToneComboEmoji('ππΌ')).toBeTruthy(); + }); + it('should not detect horse_racing', () => { + expect(isHorceRacingSkinToneComboEmoji('π')).toBeFalsy(); + }); + }); + + describe('isPersonZwjEmoji', () => { + it('should detect couple_mm', () => { + expect(isPersonZwjEmoji('π¨ββ€οΈβπ¨')).toBeTruthy(); + }); + it('should not detect couple_with_heart', () => { + expect(isPersonZwjEmoji('π')).toBeFalsy(); + }); + it('should not detect couplekiss', () => { + expect(isPersonZwjEmoji('π')).toBeFalsy(); + }); + it('should detect family_mmb', () => { + expect(isPersonZwjEmoji('π¨βπ¨βπ¦')).toBeTruthy(); + }); + it('should detect family_mwgb', () => { + expect(isPersonZwjEmoji('π¨βπ©βπ§βπ¦')).toBeTruthy(); + }); + it('should not detect family', () => { + expect(isPersonZwjEmoji('πͺ')).toBeFalsy(); + }); + it('should detect kiss_ww', () => { + expect(isPersonZwjEmoji('π©ββ€οΈβπβπ©')).toBeTruthy(); + }); + it('should not detect girl', () => { + expect(isPersonZwjEmoji('π§')).toBeFalsy(); + }); + it('should not detect girl_tone5', () => { + expect(isPersonZwjEmoji('π§πΏ')).toBeFalsy(); + }); + it('should not detect man', () => { + expect(isPersonZwjEmoji('π¨')).toBeFalsy(); + }); + it('should not detect woman', () => { + expect(isPersonZwjEmoji('π©')).toBeFalsy(); + }); + }); + + describe('isEmojiUnicodeSupported', () => { + it('bomb(6.0) with 6.0 support', () => { + const emojiKey = 'bomb'; + const unicodeSupportMap = Object.assign({}, emptySupportMap, { + '6.0': true, + }); + const isSupported = isEmojiUnicodeSupported( + unicodeSupportMap, + emojiFixtureMap[emojiKey].moji, + emojiFixtureMap[emojiKey].unicodeVersion, + ); + expect(isSupported).toBeTruthy(); + }); + + it('bomb(6.0) without 6.0 support', () => { + const emojiKey = 'bomb'; + const unicodeSupportMap = emptySupportMap; + const isSupported = isEmojiUnicodeSupported( + unicodeSupportMap, + emojiFixtureMap[emojiKey].moji, + emojiFixtureMap[emojiKey].unicodeVersion, + ); + expect(isSupported).toBeFalsy(); + }); + + it('bomb(6.0) without 6.0 but with 9.0 support', () => { + const emojiKey = 'bomb'; + const unicodeSupportMap = Object.assign({}, emptySupportMap, { + '9.0': true, + }); + const isSupported = isEmojiUnicodeSupported( + unicodeSupportMap, + emojiFixtureMap[emojiKey].moji, + emojiFixtureMap[emojiKey].unicodeVersion, + ); + expect(isSupported).toBeFalsy(); + }); + + it('construction_worker_tone5(8.0) without skin tone modifier support', () => { + const emojiKey = 'construction_worker_tone5'; + const unicodeSupportMap = Object.assign({}, emptySupportMap, { + skinToneModifier: false, + '9.0': true, + '8.0': true, + '7.0': true, + 6.1: true, + '6.0': true, + 5.2: true, + 5.1: true, + 4.1: true, + '4.0': true, + 3.2: true, + '3.0': true, + 1.1: true, + }); + const isSupported = isEmojiUnicodeSupported( + unicodeSupportMap, + emojiFixtureMap[emojiKey].moji, + emojiFixtureMap[emojiKey].unicodeVersion, + ); + expect(isSupported).toBeFalsy(); + }); + + it('use native keycap on >=57 chrome', () => { + const emojiKey = 'five'; + const unicodeSupportMap = Object.assign({}, emptySupportMap, { + '3.0': true, + meta: { + isChrome: true, + chromeVersion: 57, + }, + }); + const isSupported = isEmojiUnicodeSupported( + unicodeSupportMap, + emojiFixtureMap[emojiKey].moji, + emojiFixtureMap[emojiKey].unicodeVersion, + ); + expect(isSupported).toBeTruthy(); + }); + + it('fallback keycap on <57 chrome', () => { + const emojiKey = 'five'; + const unicodeSupportMap = Object.assign({}, emptySupportMap, { + '3.0': true, + meta: { + isChrome: true, + chromeVersion: 50, + }, + }); + const isSupported = isEmojiUnicodeSupported( + unicodeSupportMap, + emojiFixtureMap[emojiKey].moji, + emojiFixtureMap[emojiKey].unicodeVersion, + ); + expect(isSupported).toBeFalsy(); + }); + }); +}); |