Skip to content
This repository was archived by the owner on Jan 10, 2025. It is now read-only.

Commit 44eb26b

Browse files
committed
created name package
1 parent 3d3d518 commit 44eb26b

25 files changed

+1113
-1
lines changed

Diff for: .changeset/popular-items-occur.md

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

Diff for: README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ These libraries compose together to help you create performant modern JS apps th
1313

1414
## Usage
1515

16-
The Quilt repo is managed as a monorepo that is composed of 69 npm packages and one Ruby gem.
16+
The Quilt repo is managed as a monorepo that is composed of 70 npm packages and one Ruby gem.
1717
Each package/gem has its own `README.md` and documentation describing usage.
1818

1919
### Package Index
@@ -49,6 +49,7 @@ Each package/gem has its own `README.md` and documentation describing usage.
4949
| [@shopify/koa-shopify-webhooks](packages/koa-shopify-webhooks) | <a href="https://badge.fury.io/js/%40shopify%2Fkoa-shopify-webhooks"><img src="https://badge.fury.io/js/%40shopify%2Fkoa-shopify-webhooks.svg" width="200px" /></a> | Receive webhooks from Shopify with ease |
5050
| [@shopify/logger](packages/logger) | <a href="https://badge.fury.io/js/%40shopify%2Flogger"><img src="https://badge.fury.io/js/%40shopify%2Flogger.svg" width="200px" /></a> | Opinionated logger for production-scale applications |
5151
| [@shopify/mime-types](packages/mime-types) | <a href="https://badge.fury.io/js/%40shopify%2Fmime-types"><img src="https://badge.fury.io/js/%40shopify%2Fmime-types.svg" width="200px" /></a> | MIME type consistency |
52+
| [@shopify/name](packages/name) | <a href="https://badge.fury.io/js/%40shopify%2Fname"><img src="https://badge.fury.io/js/%40shopify%2Fname.svg" width="200px" /></a> | Name-related utilities |
5253
| [@shopify/network](packages/network) | <a href="https://badge.fury.io/js/%40shopify%2Fnetwork"><img src="https://badge.fury.io/js/%40shopify%2Fnetwork.svg" width="200px" /></a> | Common values related to dealing with the network |
5354
| [@shopify/performance](packages/performance) | <a href="https://badge.fury.io/js/%40shopify%2Fperformance"><img src="https://badge.fury.io/js/%40shopify%2Fperformance.svg" width="200px" /></a> | Primitives for collecting browser performance metrics |
5455
| [@shopify/polyfills](packages/polyfills) | <a href="https://badge.fury.io/js/%40shopify%2Fpolyfills"><img src="https://badge.fury.io/js/%40shopify%2Fpolyfills.svg" width="200px" /></a> | Blessed polyfills for web platform features |

Diff for: packages/name/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Changelog
2+
3+
## 1.0.0
4+
5+
- Start of Changelog

Diff for: packages/name/README.md

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# `@shopify/name`
2+
3+
[![Build Status](https://github.com/Shopify/quilt/workflows/Node-CI/badge.svg?branch=main)](https://github.com/Shopify/quilt/actions?query=workflow%3ANode-CI)
4+
[![Build Status](https://github.com/Shopify/quilt/workflows/Ruby-CI/badge.svg?branch=main)](https://github.com/Shopify/quilt/actions?query=workflow%3ARuby-CI)
5+
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE.md) [![npm version](https://badge.fury.io/js/%40shopify%2Fname.svg)](https://badge.fury.io/js/%40shopify%2Fname)
6+
![npm bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/%40shopify%2Fname.svg)
7+
8+
Utilities for formatting localized names.
9+
10+
## Installation
11+
12+
```bash
13+
yarn add @shopify/name
14+
```
15+
16+
### formatName
17+
18+
Formats a name (given name and/or family name) according to the locale. For example:
19+
20+
- `formatName({name: {givenName: 'John', familyName: 'Smith'}, locale: 'en'})` will return `John` in English and `Smith様` in Japanese
21+
- `formatName({name: {givenName: 'John', familyName: 'Smith'}, locale: 'en', options: {full: true}})` will return `John Smith` in English and `SmithJohn` in Japanese
22+
23+
### hasFamilyNameGivenNameOrdering
24+
25+
Returns `true` when the provided locale formats family name before given name.
26+
For example:
27+
28+
- `hasFamilyNameGivenNameOrdering('ja')` will return `true`
29+
- `hasFamilyNameGivenNameOrdering('en')` will return `false`
30+
31+
### abbreviateName
32+
33+
Takes a name (given and family name) and returns a language appropriate abbreviated name, or will return `formatName` if
34+
it is unable to find a suitable abbreviation.
35+
36+
For example:
37+
38+
- `abbreviateName({name: {givenName: 'John', familyName: 'Smith'}, locale: 'en'})` will return `JS`
39+
- `abbreviateName({name: {givenName: '健', familyName: '田中'}, locale: 'en'})` will return `田中`
40+
41+
You may also pass an optional `idealMaxLength` parameter, which gives the maximum allowable abbreviation length when
42+
trying to abbreviate a name in the Korean language (default 3 characters). In Korean, if the given name is longer than
43+
this length, the method will instead return the first character of the given name.
44+
45+
### abbreviateBusinessName
46+
47+
Takes a business name and returns a language appropriate abbreviated name, or will return the input name if it is unable to find
48+
a suitable abbreviation.
49+
50+
For example:
51+
52+
- `abbreviateBusinessName({name: 'Shopify'})` will return `Sho`
53+
- `abbreviateBusinessName({name: 'My Store'})` will return `MS`
54+
- `abbreviateBusinessName({name: '任天堂'})` will return `任天堂`
55+
56+
You may also pass an optional `idealMaxLength` parameter, which gives the maximum allowable abbreviation length when
57+
trying to abbreviate a name.

Diff for: packages/name/package.json

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "@shopify/name",
3+
"version": "1.0.0",
4+
"license": "MIT",
5+
"description": "Name-related utilities",
6+
"main": "index.js",
7+
"types": "./build/ts/index.d.ts",
8+
"publishConfig": {
9+
"access": "public",
10+
"@shopify:registry": "https://registry.npmjs.org"
11+
},
12+
"author": "Shopify Inc.",
13+
"repository": {
14+
"type": "git",
15+
"url": "git+https://github.com/Shopify/quilt.git",
16+
"directory": "packages/name"
17+
},
18+
"bugs": {
19+
"url": "https://github.com/Shopify/quilt/issues"
20+
},
21+
"homepage": "https://github.com/Shopify/quilt/blob/main/packages/name/README.md",
22+
"engines": {
23+
"node": "^14.17.0 || >=16.0.0"
24+
},
25+
"sideEffects": false,
26+
"files": [
27+
"build/",
28+
"!build/*.tsbuildinfo",
29+
"!build/ts/**/tests/",
30+
"index.js",
31+
"index.mjs",
32+
"index.esnext"
33+
],
34+
"module": "index.mjs",
35+
"esnext": "index.esnext",
36+
"exports": {
37+
".": {
38+
"types": "./build/ts/index.d.ts",
39+
"esnext": "./index.esnext",
40+
"import": "./index.mjs",
41+
"require": "./index.js"
42+
}
43+
}
44+
}

Diff for: packages/name/rollup.config.mjs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import {buildConfig} from '../../config/rollup.mjs';
2+
3+
export default buildConfig(import.meta.url, {
4+
entries: ['./src/index.ts'],
5+
entrypoints: {index: './src/index.ts'},
6+
});

Diff for: packages/name/src/abbreviateBusinessName.ts

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import {getGraphemes, identifyScripts} from './utilities';
2+
import {UnicodeCharacterSet} from './constants';
3+
4+
// Note: A similar Ruby implementation of this function also exists at https://github.com/Shopify/shopify-i18n/blob/main/lib/shopify-i18n/business_name_formatter.rb.
5+
export function abbreviateBusinessName({
6+
name,
7+
idealMaxLength,
8+
}: {
9+
name: string;
10+
idealMaxLength?: number;
11+
}) {
12+
return tryAbbreviateBusinessName({name, idealMaxLength}) ?? name;
13+
}
14+
15+
export function tryAbbreviateBusinessName({
16+
name,
17+
idealMaxLength = 3,
18+
}: {
19+
name: string;
20+
idealMaxLength?: number;
21+
}): string | undefined {
22+
const nameTrimmed = name.trim();
23+
24+
const scripts = identifyScripts(nameTrimmed);
25+
if (scripts.length !== 1) {
26+
return undefined;
27+
}
28+
const script = scripts[0];
29+
const words = nameTrimmed.split(' ');
30+
31+
switch (script) {
32+
case UnicodeCharacterSet.Latin:
33+
if (words.length === 1) {
34+
return words[0].slice(0, idealMaxLength);
35+
} else if (words.length <= idealMaxLength) {
36+
return words.map((word) => word[0]).join('');
37+
} else {
38+
return words.slice(0)[0][0] + words.slice(-1)[0][0];
39+
}
40+
case UnicodeCharacterSet.Han:
41+
case UnicodeCharacterSet.Katakana:
42+
case UnicodeCharacterSet.Hiragana: {
43+
if (nameTrimmed.includes(' ')) {
44+
return undefined;
45+
} else {
46+
return nameTrimmed;
47+
}
48+
}
49+
case UnicodeCharacterSet.Hangul: {
50+
const firstWord = nameTrimmed.split(' ')[0];
51+
return getGraphemes({text: firstWord, locale: 'ko'})
52+
?.slice(0, idealMaxLength)
53+
.join('');
54+
}
55+
case UnicodeCharacterSet.Thai: {
56+
// Thai language does not use spaces between words
57+
if (nameTrimmed.includes(' ')) {
58+
return undefined;
59+
} else {
60+
return getGraphemes({text: nameTrimmed, locale: 'th'})?.[0];
61+
}
62+
}
63+
default:
64+
return undefined;
65+
}
66+
}

Diff for: packages/name/src/abbreviateName.ts

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import {getGraphemes, identifyScripts} from './utilities';
2+
import {formatName} from './formatName';
3+
import {UnicodeCharacterSet} from './constants';
4+
5+
// Note: A similar Ruby implementation of this function also exists at https://github.com/Shopify/shopify-i18n/blob/main/lib/shopify-i18n/name_formatter.rb.
6+
export function abbreviateName({
7+
name,
8+
locale,
9+
options,
10+
}: {
11+
name: {givenName?: string; familyName?: string};
12+
locale: string;
13+
options?: {idealMaxLength?: number};
14+
}) {
15+
return (
16+
tryAbbreviateName({
17+
givenName: name.givenName,
18+
familyName: name.familyName,
19+
idealMaxLength: options?.idealMaxLength,
20+
}) ?? formatName({name, locale})
21+
);
22+
}
23+
24+
export function tryAbbreviateName({
25+
givenName,
26+
familyName,
27+
idealMaxLength = 3,
28+
}: {
29+
givenName?: string;
30+
familyName?: string;
31+
idealMaxLength?: number;
32+
}): string | undefined {
33+
if (!givenName && !familyName) {
34+
return undefined;
35+
}
36+
37+
const givenNameTrimmed = givenName?.trim();
38+
const familyNameTrimmed = familyName?.trim();
39+
40+
const combinedName = [givenNameTrimmed, familyNameTrimmed].join('');
41+
if (new RegExp(`${UnicodeCharacterSet.Punctuation}|\\s`).test(combinedName)) {
42+
return undefined;
43+
}
44+
45+
const scripts = identifyScripts(combinedName);
46+
if (scripts.length !== 1) {
47+
return undefined;
48+
}
49+
const script = scripts[0];
50+
51+
switch (script) {
52+
case UnicodeCharacterSet.Latin:
53+
return [givenNameTrimmed?.[0], familyNameTrimmed?.[0]].join('');
54+
case UnicodeCharacterSet.Han:
55+
case UnicodeCharacterSet.Katakana:
56+
case UnicodeCharacterSet.Hiragana:
57+
return familyNameTrimmed;
58+
case UnicodeCharacterSet.Hangul:
59+
if (givenNameTrimmed) {
60+
if (givenNameTrimmed.length > idealMaxLength) {
61+
return getGraphemes({text: givenNameTrimmed, locale: 'ko'})?.[0];
62+
} else {
63+
return givenNameTrimmed;
64+
}
65+
} else {
66+
return familyNameTrimmed;
67+
}
68+
case UnicodeCharacterSet.Thai:
69+
if (givenNameTrimmed) {
70+
return getGraphemes({text: givenNameTrimmed, locale: 'th'})?.[0];
71+
} else {
72+
return getGraphemes({text: familyNameTrimmed, locale: 'th'})?.[0];
73+
}
74+
default:
75+
return undefined;
76+
}
77+
}

Diff for: packages/name/src/constants.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
export enum UnicodeCharacterSet {
2+
Punctuation = '[!-#%-\\*,-\\/:;\\?@\\[-\\]_\\{\\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65\uD800]|[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDEAD\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]',
3+
Latin = '[A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uAB66-\uAB69\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A]|\uD801[\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD837[\uDF00-\uDF1E]',
4+
Han = '[\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u3005\u3007\u3021-\u3029\u3038-\u303B\u3400-\u4DBF\u4E00-\u9FFF\uF900-\uFA6D\uFA70-\uFAD9]|\uD81B[\uDFE2\uDFE3\uDFF0\uDFF1]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A]',
5+
Hangul = '[\u1100-\u11FF\u302E\u302F\u3131-\u318E\u3200-\u321E\u3260-\u327E\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]',
6+
Katakana = '[\u30A1-\u30FA\u30FD-\u30FF\u31F0-\u31FF\u32D0-\u32FE\u3300-\u3357\uFF66-\uFF6F\uFF71-\uFF9D\uD82B]|[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00\uDD20-\uDD22\uDD64-\uDD67]',
7+
Hiragana = '[\u3041-\u3096\u309D-\u309F]|\uD82C[\uDC01-\uDD1F\uDD50-\uDD52]|\uD83C\uDE00',
8+
Thai = '[\u0E01-\u0E3A\u0E40-\u0E5B]',
9+
}
10+
11+
export const FAMILY_NAME_GIVEN_NAME_ORDERING = new Map([
12+
['ko', defaultFamilyNameGivenNameOrderingFormatter],
13+
[
14+
'ja',
15+
(givenName: string, familyName: string, full: boolean) =>
16+
full ? `${familyName}${givenName}` : `${familyName}様`,
17+
],
18+
['zh-CN', defaultFamilyNameGivenNameOrderingFormatter],
19+
['zh-TW', defaultFamilyNameGivenNameOrderingFormatter],
20+
]);
21+
22+
function defaultFamilyNameGivenNameOrderingFormatter(
23+
givenName: string,
24+
familyName: string,
25+
full: boolean,
26+
) {
27+
return full ? `${familyName}${givenName}` : familyName;
28+
}

Diff for: packages/name/src/formatName.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import {FAMILY_NAME_GIVEN_NAME_ORDERING} from './constants';
2+
3+
// Note: A similar Ruby implementation of this function also exists at https://github.com/Shopify/shopify-i18n/blob/main/lib/shopify-i18n/name_formatter.rb.
4+
export function formatName({
5+
name,
6+
locale,
7+
options,
8+
}: {
9+
name: {givenName?: string; familyName?: string};
10+
locale: string;
11+
options?: {full?: boolean};
12+
}) {
13+
if (!name.givenName) {
14+
return name.familyName || '';
15+
}
16+
if (!name.familyName) {
17+
return name.givenName;
18+
}
19+
20+
const isFullName = Boolean(options && options.full);
21+
22+
const customNameFormatter = FAMILY_NAME_GIVEN_NAME_ORDERING.get(locale);
23+
24+
if (customNameFormatter) {
25+
return customNameFormatter(name.givenName, name.familyName, isFullName);
26+
}
27+
if (isFullName) {
28+
return `${name.givenName} ${name.familyName}`;
29+
}
30+
return name.givenName;
31+
}

Diff for: packages/name/src/hasFamilyNameGivenNameOrdering.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import {FAMILY_NAME_GIVEN_NAME_ORDERING} from './constants';
2+
3+
export function hasFamilyNameGivenNameOrdering(locale: string) {
4+
const familyNameGivenNameOrdering =
5+
FAMILY_NAME_GIVEN_NAME_ORDERING.get(locale);
6+
return Boolean(familyNameGivenNameOrdering);
7+
}

Diff for: packages/name/src/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export {abbreviateName} from './abbreviateName';
2+
export {abbreviateBusinessName} from './abbreviateBusinessName';
3+
export {formatName} from './formatName';
4+
export {hasFamilyNameGivenNameOrdering} from './hasFamilyNameGivenNameOrdering';
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {abbreviateBusinessName} from '../abbreviateBusinessName';
2+
3+
describe('#abbreviateBusinessName()', () => {
4+
it('returns input name if no abbreviation found', () => {
5+
const input = {name: '😀😃😄'};
6+
expect(abbreviateBusinessName(input)).toBe(input.name);
7+
});
8+
9+
it('returns abbreviated name if abbreviation found', () => {
10+
const input = {name: 'shop-123'};
11+
expect(abbreviateBusinessName(input)).toBe('sho');
12+
});
13+
});

Diff for: packages/name/src/tests/abbreviateName.test.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {formatName} from '../formatName';
2+
import {abbreviateName} from '../abbreviateName';
3+
4+
const locale = 'en';
5+
6+
describe('#abbreviateName()', () => {
7+
it('returns formatName if no abbreviation found', () => {
8+
// no abbreviation as has space in family name
9+
const name = {givenName: 'Michael', familyName: 'van Finkle'};
10+
expect(abbreviateName({name, locale})).toBe(formatName({name, locale}));
11+
});
12+
13+
it('returns abbreviated name if abbreviation found', () => {
14+
const name = {givenName: 'Michael', familyName: 'Garfinkle'};
15+
expect(abbreviateName({name, locale})).toBe('MG');
16+
});
17+
});

0 commit comments

Comments
 (0)