From 7567b163c064fdce08570db6b338c65a5d0e55ae Mon Sep 17 00:00:00 2001 From: hotoo Date: Tue, 7 May 2019 15:49:58 +0800 Subject: [PATCH] feat: add charAt, split, indexOf method. --- src/EmojiCharString.js | 27 ++++++++++++++- test/test.js | 77 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 102 insertions(+), 2 deletions(-) diff --git a/src/EmojiCharString.js b/src/EmojiCharString.js index 982c044..c5fadd5 100644 --- a/src/EmojiCharString.js +++ b/src/EmojiCharString.js @@ -1,10 +1,11 @@ const astralRange = /\ud83c[\udffb-\udfff](?=\ud83c[\udffb-\udfff])|(?:[^\ud800-\udfff][\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]?|[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?(?:\u200d(?:[^\ud800-\udfff]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?)*/g -class EmojiCharString { +class EmojiCharString extends String { constructor (string) { if (typeof string !== 'string') { throw new Error('Input must be a string') } + super(string) this._string = string this._match = string.match(astralRange) || [] } @@ -16,6 +17,10 @@ class EmojiCharString { return this._string } + valueOf () { + return this._string + } + /** * Reverse the string in place * @return {[String]} [The reversed string] @@ -77,6 +82,26 @@ class EmojiCharString { slice (begin = 0, end) { return this._match.slice(begin, end).join('') } + + split (separator) { + if (separator === '') { + return this._match.slice(0) + } + return super.split(separator) + } + + charAt (index = 0) { + return this._match[index] || '' + } + + indexOf (ch, from) { + const idx = super.indexOf(ch, from) + if (idx === -1) { + return -1 + } + const match = this._string.substring(from, idx).match(astralRange) || [] + return match.length + } } export default EmojiCharString diff --git a/test/test.js b/test/test.js index 7173f3e..7a93376 100644 --- a/test/test.js +++ b/test/test.js @@ -133,7 +133,7 @@ describe('EmojiCharString Class substr method', () => { }) // slice -describe.only('EmojiCharString Class slice method', () => { +describe('EmojiCharString Class slice method', () => { let str = '👨‍👨‍👦 our family 我们一家 ❤️' let emojiStr = new EmojiCharString(str) let emojiStrLen = emojiStr.length @@ -171,3 +171,78 @@ describe.only('EmojiCharString Class slice method', () => { assert.equal(emojiStr.slice(0, 'hello'), '') }) }) + +// charAt +describe('EmojiCharString Class charAt method', () => { + let str = '👨‍👨‍👦 our family 我们一家 ❤️' + let emojiStr = new EmojiCharString(str) + let emojiStrLen = emojiStr.length + + it('If begin is omitted, it will use default value 0.', () => { + assert.equal(emojiStr.charAt(), '👨‍👨‍👦') + }) + + it('If begin is positive and is greater than or equal to the length of the string, charAt() returns an empty string.', () => { + assert.equal(emojiStr.charAt(-1), '') + assert.equal(emojiStr.charAt(emojiStrLen + 1), '') + }) + + it('If begin is negative and abs(start) is larger than the length of the string, charAt() uses 0 as the start index.', () => { + assert.equal(emojiStr.charAt(0), '👨‍👨‍👦') + assert.equal(emojiStr.charAt(1), ' ') + assert.equal(emojiStr.charAt(2), 'o') + assert.equal(emojiStr.charAt(3), 'u') + assert.equal(emojiStr.charAt(4), 'r') + assert.equal(emojiStr.charAt(5), ' ') + assert.equal(emojiStr.charAt(6), 'f') + assert.equal(emojiStr.charAt(7), 'a') + assert.equal(emojiStr.charAt(8), 'm') + assert.equal(emojiStr.charAt(9), 'i') + assert.equal(emojiStr.charAt(10), 'l') + assert.equal(emojiStr.charAt(11), 'y') + assert.equal(emojiStr.charAt(12), ' ') + assert.equal(emojiStr.charAt(13), '我') + assert.equal(emojiStr.charAt(14), '们') + assert.equal(emojiStr.charAt(15), '一') + assert.equal(emojiStr.charAt(16), '家') + assert.equal(emojiStr.charAt(17), ' ') + assert.equal(emojiStr.charAt(18), '❤️') + }) +}) + +// split +describe('EmojiCharString Class split method', () => { + let str = '👨‍👨‍👦 our family 我们一家 ❤️' + let emojiStr = new EmojiCharString(str) + + it('If begin is omitted, it will use default value undefined.', () => { + assert.equal(emojiStr.split(), str) + assert.equal(emojiStr.split(null), str) + assert.equal(emojiStr.split(undefined), str) + }) + + it('If begin is positive and is greater than or equal to the length of the string, split() returns an empty string.', () => { + assert.deepEqual(emojiStr.split(''), ['👨‍👨‍👦', ' ', 'o', 'u', 'r', ' ', 'f', 'a', 'm', 'i', 'l', 'y', ' ', '我', '们', '一', '家', ' ', '❤️']) + assert.deepEqual(emojiStr.split(' '), ['👨‍👨‍👦', 'our', 'family', '我们一家', '❤️']) + assert.deepEqual(emojiStr.split(/ /), ['👨‍👨‍👦', 'our', 'family', '我们一家', '❤️']) + }) +}) + +// indexOf +describe('EmojiCharString Class indexOf method', () => { + let str = '👨‍👨‍👦 our family 我们一家 ❤️' + let emojiStr = new EmojiCharString(str) + let emojiStrLen = emojiStr.length + + it('If begin is omitted, it will use default value 0.', () => { + assert.equal(emojiStr.indexOf(), -1) + assert.equal(emojiStr.indexOf('NOT_EXISTS'), -1) + }) + + it('If begin is positive and is greater than or equal to the length of the string, indexOf() returns an empty string.', () => { + assert.equal(str.indexOf('o'), 9) + assert.equal(emojiStr.indexOf('o'), 2) + assert.equal(emojiStr.indexOf('o', -1), 2) + assert.equal(emojiStr.indexOf('o', emojiStrLen + 1), -1) + }) +})