Skip to content

Commit

Permalink
feat: add charAt, split, indexOf method.
Browse files Browse the repository at this point in the history
  • Loading branch information
hotoo committed May 7, 2019
1 parent b1d923d commit 7567b16
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 2 deletions.
27 changes: 26 additions & 1 deletion src/EmojiCharString.js
Original file line number Diff line number Diff line change
@@ -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) || []
}
Expand All @@ -16,6 +17,10 @@ class EmojiCharString {
return this._string
}

valueOf () {
return this._string
}

/**
* Reverse the string in place
* @return {[String]} [The reversed string]
Expand Down Expand Up @@ -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
77 changes: 76 additions & 1 deletion test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
})
})

0 comments on commit 7567b16

Please sign in to comment.