refactor(avatarName): remove avatarName class

This commit is contained in:
Christopher Astfalk
2021-05-28 16:09:48 +02:00
parent 9a06ac909d
commit df43922406
6 changed files with 14 additions and 282 deletions
-1
View File
@@ -26,7 +26,6 @@ In this directory are the general and setup modules located. Most of the App is
- The store/state
- Service-Worker
- [`app.js`](./app.js) is the root component. Routing and different Providers get handled here.
- [`avatarName.ts`](./avatarName.ts) handles parsing and displaying avatar names.
- [`llsd.js`](./llsd.js) A copy of LindenLabs [LLSD](http://wiki.secondlife.com/wiki/LLSD "LLSD documentation") [Javascript library](https://bitbucket.org/lindenlab/llsd/src/default/js/ "Repository of different LLSD libraries").
- [`react-app-env.d.ts`](./react-app-env.d.ts) importing of react-app types.
- [`registerServiceWorker.js`](./registerServiceWorker.js).
-148
View File
@@ -1,148 +0,0 @@
import AvatarName from './avatarName'
test('should parse a given name', () => {
expect(new AvatarName('First.Last')).toEqual({
first: 'First',
last: 'Last',
displayName: '',
isUsingDisplayName: false,
didLoadDisplayName: false,
isLoadingDisplayName: false
})
expect(new AvatarName('Tester Linden')).toEqual({
first: 'Tester',
last: 'Linden',
displayName: '',
isUsingDisplayName: false,
didLoadDisplayName: false,
isLoadingDisplayName: false
})
expect(new AvatarName('Tester')).toEqual({
first: 'Tester',
last: 'Resident',
displayName: '',
isUsingDisplayName: false,
didLoadDisplayName: false,
isLoadingDisplayName: false
})
expect(new AvatarName({ first: 'Tester' })).toEqual({
first: 'Tester',
last: 'Resident',
displayName: '',
isUsingDisplayName: false,
didLoadDisplayName: false,
isLoadingDisplayName: false
})
expect(new AvatarName({
first: 'Tester',
last: 'Linden',
displayName: '',
isUsingDisplayName: false,
didLoadDisplayName: false,
isLoadingDisplayName: false
})).toEqual({
first: 'Tester',
last: 'Linden',
displayName: '',
isUsingDisplayName: false,
didLoadDisplayName: false,
isLoadingDisplayName: false
})
expect(new AvatarName({
id: 'e856f8e7-f774-4040-8392-df4185fa37e4'
})).toEqual({
first: '',
last: 'e856f8e7-f774-4040-8392-df4185fa37e4',
displayName: '',
isUsingDisplayName: false,
didLoadDisplayName: false,
isLoadingDisplayName: false
})
})
test(
'should give only the first name by the method getName() if the ' +
'last name is "Resident"',
() => {
expect(new AvatarName('Tester.Resident').getName()).toBe('Tester')
expect(new AvatarName('hal2000').getName()).toBe('Hal2000')
}
)
test('should give the full name with the method getFullName()', () => {
expect(new AvatarName('Tester').getFullName()).toBe('Tester Resident')
expect(new AvatarName('Tester.Linden').getFullName()).toBe('Tester Linden')
})
test('should have a toString method that behaves like getFullName', () => {
expect(new AvatarName('Tester.Resident').toString()).toBe('Tester')
expect(new AvatarName('hal2000').toString()).toBe('Hal2000')
})
test('should be comparable with the compare method', () => {
const first = new AvatarName('test')
const second = new AvatarName({ first: 'test', last: 'Linden' })
const third = new AvatarName('tEst Resident')
expect(first.compare(second)).toBe(false)
expect(second.compare(third)).toBe(false)
expect(second.compare('Test Linden')).toBe(true)
expect(second.compare(third)).toBe(false)
expect(first.compare({
first: 'Test',
last: 'Resident'
})).toBe(true)
})
test('should format names', () => {
expect(new AvatarName('tester linden')).toEqual({
first: 'Tester',
last: 'Linden',
displayName: '',
isUsingDisplayName: false,
didLoadDisplayName: false,
isLoadingDisplayName: false
})
expect(new AvatarName('teSteR lInDeN')).toEqual({
first: 'Tester',
last: 'Linden',
displayName: '',
isUsingDisplayName: false,
didLoadDisplayName: false,
isLoadingDisplayName: false
})
})
test('should copy itself', () => {
const old = new AvatarName('test')
const isLoading = old.withIsLoadingSetTo(true)
const displayName = isLoading.withDisplayNameSetTo('Hello')
expect(old).not.toBe(isLoading)
expect(isLoading).not.toBe(displayName)
})
test('should update its display name', () => {
const old = new AvatarName('test')
const isLoading = old.withIsLoadingSetTo(true)
const displayName = isLoading.withDisplayNameSetTo('Hello')
expect(isLoading).toEqual({
first: 'Test',
last: 'Resident',
displayName: '',
isUsingDisplayName: false,
didLoadDisplayName: false,
isLoadingDisplayName: true
})
expect(displayName).toEqual({
first: 'Test',
last: 'Resident',
displayName: 'Hello',
isUsingDisplayName: true,
didLoadDisplayName: true,
isLoadingDisplayName: false
})
})
-120
View File
@@ -1,120 +0,0 @@
// parses an avatar name
// Searches for a dot or white space that separates the first and last names
// if neither is given, then 'resident' will be used for the last name
// first.last and first last will become {first: 'first', last: 'last'}
function cleanName (name: string) {
// deletes characters that will be in names but shouldn't
const trimmed = name.trim().replace(/["\0]/gi, '')
const upperCased = trimmed.charAt(0).toUpperCase() + // name -> Name
trimmed.substring(1).toLowerCase()
return upperCased
}
export default class AvatarName {
first: string
last: string
displayName: string
isUsingDisplayName: boolean
didLoadDisplayName: boolean
isLoadingDisplayName: boolean
constructor (name: AvatarName | string | { first: string, last?: string } | { id: string }, lastName?: string) {
if (name instanceof AvatarName) {
this.first = name.first
this.last = name.last
this.displayName = name.displayName
this.isUsingDisplayName = name.isUsingDisplayName
this.didLoadDisplayName = name.didLoadDisplayName
this.isLoadingDisplayName = name.isLoadingDisplayName
return
} else if (typeof name === 'object' && 'id' in name) {
this.first = ''
this.last = name.id
} else if (typeof name === 'object' && typeof name.first === 'string') {
this.first = cleanName(name.first)
this.last = cleanName(name.last || 'Resident')
} else if (typeof name === 'string' && arguments.length === 1) {
const separator = name.match(/[.\s]/) // either a dot or a space
if (separator) {
const parts = name.split(separator[0])
this.first = cleanName(parts[0])
this.last = cleanName(parts[1])
} else {
this.first = cleanName(name)
this.last = 'Resident'
}
} else if (typeof name === 'string' && typeof lastName === 'string') {
this.first = cleanName(name)
this.last = cleanName(lastName)
} else {
throw new TypeError(`couldn't parse ${name}`)
}
this.displayName = ''
this.isUsingDisplayName = false
this.didLoadDisplayName = false
this.isLoadingDisplayName = false
}
getFullName () {
return `${this.first} ${this.last}`
}
getName () {
if (this.last === 'Resident') {
return this.first
} else {
return this.getFullName()
}
}
getDisplayName () {
if (this.didLoadDisplayName && this.isUsingDisplayName) {
return `${this.displayName} (${this.getName()})`
} else {
return this.getName()
}
}
toString () {
return this.getDisplayName()
}
compare (other: AvatarName, strict: boolean = false) {
if (strict && !(other instanceof AvatarName)) {
return false
}
const otherName = typeof other === 'string' ? new AvatarName(other) : other
return otherName.first === this.first && otherName.last === this.last
}
willHaveDisplayName () {
return this.didLoadDisplayName || this.isLoadingDisplayName || this.displayName.length > 0
}
withIsLoadingSetTo (isLoading: boolean) {
const next = new AvatarName(this)
next.isLoadingDisplayName = isLoading
return next
}
withDisplayNameSetTo (displayName: string, legacyFirstName: string, legacyLastName: string) {
const next = new AvatarName(this)
if (legacyFirstName != null) {
next.first = legacyFirstName
}
if (legacyLastName != null) {
next.last = legacyLastName
}
next.isLoadingDisplayName = false
next.didLoadDisplayName = true
next.displayName = displayName
next.isUsingDisplayName = next.getName() !== displayName
return next
}
}
+10 -10
View File
@@ -17,7 +17,7 @@ import {
describe('actions', () => {
describe('addMissing', () => {
it('should add a missing name', async () => {
const { store, getDiff } = await createTestStore({})
const { store, getDiff } = await createTestStore()
store.dispatch(addMissing({
id: 'e856f8e7-f774-4040-8392-df4185fa37e4'
@@ -44,7 +44,7 @@ describe('actions', () => {
})
it('should parse the fallback name', async () => {
const { store, getDiff } = await createTestStore({})
const { store, getDiff } = await createTestStore()
store.dispatch(addMissing({
id: 'e856f8e7-f774-4040-8392-df4185fa37e4',
@@ -72,7 +72,7 @@ describe('actions', () => {
})
it('should not change an existing name', async () => {
const { store, setMark, getDiff } = await createTestStore({})
const { store, setMark, getDiff } = await createTestStore()
store.dispatch(addMissing({
id: 'e856f8e7-f774-4040-8392-df4185fa37e4',
@@ -90,7 +90,7 @@ describe('actions', () => {
})
it('should not add a NIL UUID', async () => {
const { store, getDiff } = await createTestStore({})
const { store, getDiff } = await createTestStore()
store.dispatch(addMissing({
id: NIL
@@ -102,7 +102,7 @@ describe('actions', () => {
describe('displayNamesStartLoading', () => {
it('should set isLoadingDisplayName of the names', async () => {
const { store, setMark, getDiff } = await createTestStore({})
const { store, setMark, getDiff } = await createTestStore()
store.dispatch(addMissing({
id: 'e856f8e7-f774-4040-8392-df4185fa37e4',
@@ -129,13 +129,13 @@ describe('actions', () => {
})
const idsAfterStart = selectIdOfNamesToLoad(store.getState())
expect(idsAfterStart).toEqual([])
expect(idsAfterStart).toHaveLength(0)
})
})
describe('displayNamesLoaded', () => {
it('should add the display names', async () => {
const { store, setMark, getDiff } = await createTestStore({})
const { store, setMark, getDiff } = await createTestStore()
store.dispatch(addMissing({
id: 'e856f8e7-f774-4040-8392-df4185fa37e4',
@@ -185,7 +185,7 @@ describe('actions', () => {
})
it('should update first name and last name', async () => {
const { store, setMark, getDiff } = await createTestStore({})
const { store, setMark, getDiff } = await createTestStore()
store.dispatch(addMissing({
id: 'e856f8e7-f774-4040-8392-df4185fa37e4',
@@ -234,7 +234,7 @@ describe('actions', () => {
})
it('should set bad ids as loaded', async () => {
const { store, setMark, getDiff } = await createTestStore({})
const { store, setMark, getDiff } = await createTestStore()
store.dispatch(addMissing({
id: 'e856f8e7-f774-4040-8392-df4185fa37e4',
@@ -263,7 +263,7 @@ describe('actions', () => {
})
it('should handle displayNames that are the default name', async () => {
const { store, setMark, getDiff } = await createTestStore({})
const { store, setMark, getDiff } = await createTestStore()
store.dispatch(addMissing({
id: 'e856f8e7-f774-4040-8392-df4185fa37e4',
+3 -2
View File
@@ -118,15 +118,16 @@ export function createExtraArgument (
createDatabases: (args: CreateDatabasesArgs) => CreateDatabasesResult
): ExtraArguments {
const { local, remote } = createDatabases({ local: true, remote: '_users', skipSetup: true })
const placeholder = () => Promise.reject(new Error('unimplemented'))
const extraArgument = {
cryptoStore: createCryptoStore(local),
db: local!,
remoteDB: remote!,
createDatabases,
// Must be added after the store was created
proxyFetch: () => Promise.reject(new Error('unimplemented')),
proxyFetch: placeholder,
// Must be added after the store was created
fetchLLSD: () => Promise.reject(new Error('unimplemented')),
fetchLLSD: placeholder,
onAvatarLogout: [],
circuit: null // will be set on login
}
+1 -1
View File
@@ -78,7 +78,7 @@ export async function createTestStore ({ localDB, remoteDB, state = AppState.Log
localDB?: PouchDB.Database,
remoteDB?: PouchDB.Database,
state?: AppState
}) {
} = {}) {
let isSetup = true // when the the create Databases callback is called the first time
const extraArgument = createExtraArgument(({ local, remote }) => {
const result: { local: PouchDB.Database | null, remote: PouchDB.Database | null } = {