Skip to content

Commit f591c28

Browse files
authored
Slight refactor to pluralization util (#2707)
1 parent 3b838e0 commit f591c28

File tree

5 files changed

+24
-11
lines changed

5 files changed

+24
-11
lines changed

app/pages/project/instances/InstancesPage.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import { Tooltip } from '~/ui/lib/Tooltip'
3939
import { setDiff } from '~/util/array'
4040
import { toLocaleTimeString } from '~/util/date'
4141
import { pb } from '~/util/path-builder'
42+
import { pluralize } from '~/util/str'
4243

4344
import { useMakeInstanceActions } from './actions'
4445
import { ResizeInstanceModal } from './instance/InstancePage'
@@ -99,7 +100,8 @@ export function Component() {
99100
header: 'CPU',
100101
cell: (info) => (
101102
<>
102-
{info.getValue()} <span className="ml-1 text-tertiary">vCPU</span>
103+
{info.getValue()}{' '}
104+
<span className="ml-1 text-tertiary">{pluralize('vCPU', info.getValue())}</span>
103105
</>
104106
),
105107
}),

app/pages/project/instances/instance/InstancePage.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import { Spinner } from '~/ui/lib/Spinner'
5252
import { Tooltip } from '~/ui/lib/Tooltip'
5353
import { truncate } from '~/ui/lib/Truncate'
5454
import { pb } from '~/util/path-builder'
55+
import { pluralize } from '~/util/str'
5556
import { GiB } from '~/util/units'
5657

5758
import { useMakeInstanceActions } from '../actions'
@@ -221,7 +222,7 @@ export function InstancePage() {
221222
<PropertiesTable>
222223
<PropertiesTable.Row label="cpu">
223224
<span className="text-default">{instance.ncpus}</span>
224-
<span className="ml-1 text-tertiary"> vCPUs</span>
225+
<span className="ml-1 text-tertiary">{pluralize(' vCPU', instance.ncpus)}</span>
225226
</PropertiesTable.Row>
226227
<PropertiesTable.Row label="ram">
227228
<span className="text-default">{memory.value}</span>

app/util/str.spec.tsx

+11-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
extractText,
1515
kebabCase,
1616
normalizeName,
17+
pluralize,
1718
titleCase,
1819
} from './str'
1920

@@ -23,6 +24,14 @@ describe('capitalize', () => {
2324
})
2425
})
2526

27+
describe('pluralize', () => {
28+
it('pluralizes correctly', () => {
29+
expect(pluralize('item', 0)).toBe('items')
30+
expect(pluralize('item', 1)).toBe('item')
31+
expect(pluralize('item', 2)).toBe('items')
32+
})
33+
})
34+
2635
describe('camelCase', () => {
2736
it('basic formats to camel case', () => {
2837
expect(camelCase('camelCase')).toBe('camelCase')
@@ -51,8 +60,9 @@ it('commaSeries', () => {
5160
expect(commaSeries([], 'or')).toBe('')
5261
expect(commaSeries(['a'], 'or')).toBe('a')
5362
expect(commaSeries(['a', 'b'], 'or')).toBe('a or b')
54-
expect(commaSeries(['a', 'b'], 'or')).toBe('a or b')
63+
expect(commaSeries(['a', 'b'], 'and')).toBe('a and b')
5564
expect(commaSeries(['a', 'b', 'c'], 'or')).toBe('a, b, or c')
65+
expect(commaSeries(['a', 'b', 'c'], 'and')).toBe('a, b, and c')
5666
})
5767

5868
describe('titleCase', () => {

app/util/str.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import React, { type ReactElement, type ReactNode } from 'react'
1010

1111
export const capitalize = (s: string) => s && s.charAt(0).toUpperCase() + s.slice(1)
1212

13-
export const pluralize = (s: string, n: number) => `${n} ${s}${n === 1 ? '' : 's'}`
13+
export const pluralize = (s: string, n: number) => `${s}${n === 1 ? '' : 's'}`
1414

1515
export const camelCase = (s: string) =>
1616
s

test/e2e/instance.e2e.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ test('can resize a failed or stopped instance', async ({ page }) => {
161161
// resize 'you-fail', currently in a failed state
162162
await expectRowVisible(table, {
163163
name: 'you-fail',
164-
CPU: '4 vCPU',
164+
CPU: '4 vCPUs',
165165
Memory: '6 GiB',
166166
state: expect.stringMatching(/^failed\d+s$/),
167167
})
@@ -173,15 +173,15 @@ test('can resize a failed or stopped instance', async ({ page }) => {
173173
await resizeModal.getByRole('button', { name: 'Resize' }).click()
174174
await expectRowVisible(table, {
175175
name: 'you-fail',
176-
CPU: '10 vCPU',
176+
CPU: '10 vCPUs',
177177
Memory: '20 GiB',
178178
state: expect.stringMatching(/^failed\d+s$/),
179179
})
180180

181181
// resize 'db1', which needs to be stopped first
182182
await expectRowVisible(table, {
183183
name: 'db1',
184-
CPU: '2 vCPU',
184+
CPU: '2 vCPUs',
185185
Memory: '4 GiB',
186186
state: expect.stringMatching(/^running\d+s$/),
187187
})
@@ -200,7 +200,7 @@ test('can resize a failed or stopped instance', async ({ page }) => {
200200
await resizeModal.getByRole('button', { name: 'Resize' }).click()
201201
await expectRowVisible(table, {
202202
name: 'db1',
203-
CPU: '8 vCPU',
203+
CPU: '8 vCPUs',
204204
Memory: '16 GiB',
205205
state: expect.stringMatching(/^stopped\d+s$/),
206206
})
@@ -224,19 +224,19 @@ test('instance table', async ({ page }) => {
224224
const table = page.getByRole('table')
225225
await expectRowVisible(table, {
226226
name: 'db1',
227-
CPU: '2 vCPU',
227+
CPU: '2 vCPUs',
228228
Memory: '4 GiB',
229229
state: expect.stringMatching(/^running\d+s$/),
230230
})
231231
await expectRowVisible(table, {
232232
name: 'you-fail',
233-
CPU: '4 vCPU',
233+
CPU: '4 vCPUs',
234234
Memory: '6 GiB',
235235
state: expect.stringMatching(/^failed\d+s$/),
236236
})
237237
await expectRowVisible(table, {
238238
name: 'not-there-yet',
239-
CPU: '2 vCPU',
239+
CPU: '2 vCPUs',
240240
Memory: '8 GiB',
241241
state: expect.stringMatching(/^starting\d+s$/),
242242
})

0 commit comments

Comments
 (0)