UNPKG

ipsased

Version:

UI toolkit monorepo containing a React component library, UI utilities, a drag-and-drop library, and more

453 lines (401 loc) 13.9 kB
import { describe, expect, it } from 'vitest'; import uniquify from './uniquify.js'; describe('uniquify', () => { const baseItems = ['bear', 'chickaree', 'coyote', 'marmot', 'pika']; const baseItemObjects = [{ slug: 'home' }, { slug: 'about' }]; it('creates a unique string that starts numbering at 2 separated by ‘-’', () => { expect( uniquify({ items: baseItems, value: 'bear', }), ).toBe('bear 2'); expect( uniquify({ items: baseItems.concat('coyote 2'), value: 'coyote', }), ).toBe('coyote 3'); expect( uniquify({ items: baseItems .slice(0, 1) .concat(baseItems.slice(2)) .concat('chickaree 2'), value: 'chickaree', }), ).toBe('chickaree'); expect( uniquify({ items: baseItems.concat('marmot-2'), value: 'marmot', }), ).toBe('marmot 2'); expect( uniquify({ items: baseItems.concat('bear 2', 'bear 2 14'), value: 'bear 2', }), ).toBe('bear 3'); expect( uniquify({ items: baseItems.concat('chickaree 2 2', 'chickaree 2 13'), value: 'chickaree 2 13', }), ).toBe('chickaree 2 14'); expect( uniquify({ items: baseItems.concat('chickaree 2 2', 'chickaree 2 13'), value: 'chickaree 2 12', }), ).toBe('chickaree 2 12'); }); it('handles arrays of objects as items when passed a propertyPath', () => { expect( uniquify({ items: baseItemObjects, propertyPath: ['slug'], separator: '-', value: 'about', }), ).toBe('about-2'); expect( uniquify({ items: baseItemObjects.concat({ slug: 'about-2' }), propertyPath: ['slug'], separator: '-', value: 'about', }), ).toBe('about-3'); const nestedItems = [ { content: { name: 'I ❤️ the Smell of Napalm in the Morning 2' }, id: '04a1', }, { content: { name: 'Hardcore History' }, id: '17e1', }, { content: { name: 'I ❤️ the Smell of Napalm in the Morning' }, id: 'b883', }, ]; expect( uniquify({ items: nestedItems, propertyPath: ['content', 'name'], value: 'I ❤️ the Smell of Napalm in the Morning', }), ).toBe('I ❤️ the Smell of Napalm in the Morning 3'); // If using baseItemObjects, there will be no matching item expect( uniquify({ items: baseItemObjects, propertyPath: ['content', 'name'], value: 'I ❤️ the Smell of Napalm in the Morning', }), ).toBe('I ❤️ the Smell of Napalm in the Morning'); }); describe('logic to determine if number at end of string is counter or content', () => { it('assumes any number with more than two digits is content', () => { const name = 'keeping-it-real-since-1949'; expect( uniquify({ items: baseItems.concat(name), separator: '-', value: name, }), ).toBe('keeping-it-real-since-1949-2'); const slug = 'the-highest-percent-is-100'; expect( uniquify({ items: baseItemObjects.concat({ slug }), propertyPath: ['slug'], separator: '-', value: slug, }), ).toBe('the-highest-percent-is-100-2'); }); it('checks any number less than 100 for another counter based on same stem', () => { const slug = 'but-this-one-goes-to-11'; expect( uniquify({ items: baseItemObjects.concat({ slug }), propertyPath: ['slug'], separator: '-', value: slug, }), ).toBe('but-this-one-goes-to-11-2'); expect( uniquify({ items: baseItemObjects.concat( { slug }, { slug: 'but-this-one-goes-to-2' }, ), propertyPath: ['slug'], separator: '-', value: slug, }), ).toBe('but-this-one-goes-to-12'); const name = 'testing the limits 99'; expect( uniquify({ items: baseItems.concat(name, 'testing the limits'), value: name, }), ).toBe('testing the limits 100'); expect( uniquify({ items: baseItems.concat(name, 'testing the limits 2'), value: name, }), ).toBe('testing the limits 100'); expect( uniquify({ items: baseItems.concat(name, 'testing the limits 98'), value: name, }), ).toBe('testing the limits 100'); // Check should ignore 1 as a counter expect( uniquify({ items: baseItems.concat(name, 'testing the limits 1'), value: name, }), ).toBe('testing the limits 99 2'); }); it('disregards 1 when determining if number at end of string is counter or content', () => { const slugBase = 'things-that-are-divisible-by'; expect( uniquify({ items: baseItemObjects.concat( { slug: `${slugBase}-2` }, { slug: `${slugBase}-7` }, ), propertyPath: ['slug'], separator: '-', value: `${slugBase}-7`, }), ).toBe('things-that-are-divisible-by-8'); expect( uniquify({ items: baseItemObjects.concat( { slug: `${slugBase}-1` }, { slug: `${slugBase}-7` }, ), propertyPath: ['slug'], separator: '-', value: `${slugBase}-7`, }), ).toBe('things-that-are-divisible-by-7-2'); }); }); it('handles a custom separator string of any length', () => { expect( uniquify({ items: baseItemObjects.concat({ slug: 'about-2' }), propertyPath: ['slug'], separator: '-', value: 'about', }), ).toBe('about-3'); expect( uniquify({ items: baseItemObjects.concat({ slug: 'about-2' }), propertyPath: ['slug'], separator: '_', value: 'about', }), ).toBe('about_2'); expect( uniquify({ items: baseItemObjects.concat({ slug: 'about_2' }), propertyPath: ['slug'], separator: '_', value: 'about', }), ).toBe('about_3'); const separator = ' 🌮—🥑asdœ__–¢™º•ø¨∆as_____dbnm______ds®†ª™¢•b√awekj#Bfsªç∆å'; expect( uniquify({ items: baseItemObjects.concat({ slug: `about${separator}2` }), propertyPath: ['slug'], separator, value: 'about', }), ).toBe(`about${separator}3`); }); it('handles a custom property path along with an alternate property path', () => { const items = [ { content: { name: 'I ❤️ the Smell of Napalm in the Morning 2' }, id: '04a1', }, { content: { name: 'Hardcore History' }, id: '17e1', }, { id: 'b883', title: 'I ❤️ the Smell of Napalm in the Morning', }, ]; expect( uniquify({ items, propertyPath: ['content', 'name'], propertyPathAlternate: ['title'], value: 'I ❤️ the Smell of Napalm in the Morning', }), ).toBe('I ❤️ the Smell of Napalm in the Morning 3'); }); it('handles adding a suffix before applying counter', () => { expect( uniquify({ items: baseItems, suffix: 'copy', value: 'marmot', }), ).toBe('marmot copy'); expect( uniquify({ items: baseItems.concat('marmot copy'), suffix: 'copy', value: 'marmot copy', }), ).toBe('marmot copy 2'); // Defaults to being case insensitive expect( uniquify({ items: baseItems.concat('marmot Copy', 'marmot Copy 2', 'marmot copy 3'), suffix: 'copy', value: 'marmot', }), ).toBe('marmot copy 4'); // Respects caseSensitive: true expect( uniquify({ caseSensitive: true, items: baseItems.concat('marmot Copy', 'marmot Copy 2', 'marmot copy 3'), suffix: 'copy', value: 'marmot', }), ).toBe('marmot copy'); expect( uniquify({ items: baseItems.concat('copy me'), suffix: 'copy', value: 'copy me', }), ).toBe('copy me copy'); }); it('when isSuffixOptional is true, only adds the suffix if needed', () => { expect( uniquify({ isSuffixOptional: true, items: baseItemObjects, propertyPath: ['slug'], suffix: 'copy', value: 'contact', }), ).toBe('contact'); expect( uniquify({ isSuffixOptional: false, items: baseItemObjects, propertyPath: ['slug'], suffix: 'copy', value: 'contact', }), ).toBe('contact copy'); expect( uniquify({ isSuffixOptional: true, items: baseItemObjects, propertyPath: ['slug'], suffix: 'copy', value: 'about', }), ).toBe('about copy'); }); it('handles option to make it identify counters that begin at 1', () => { expect( uniquify({ identify1AsCounter: true, items: baseItemObjects .slice(0, 1) .concat(baseItemObjects.slice(2)) .concat({ slug: 'about-1' }), propertyPath: ['slug'], separator: '-', value: 'about-1', }), ).toBe('about-2'); }); it('handles empty string as any other value', () => { expect( uniquify({ items: baseItems, value: '', }), ).toBe(''); expect( uniquify({ items: baseItems.concat(''), value: '', }), ).toBe(' 2'); }); it('handles sibling lists with null or undefined values', () => { expect( uniquify({ items: [baseItems[0], null, baseItems[1], baseItems[2]], value: 'chickaree', }), ).toBe('chickaree 2'); expect( uniquify({ items: [undefined, baseItemObjects[0], baseItemObjects[1]], propertyPath: ['slug'], separator: '-', value: 'about', }), ).toBe('about-2'); }); describe('locale-friendly case sensitivity options', () => { it('defaults to case insensitive, overrideable via props', () => { expect( uniquify({ items: baseItemObjects, propertyPath: ['slug'], value: 'Home', }), ).toBe('Home 2'); expect( uniquify({ caseSensitive: true, items: baseItemObjects, propertyPath: ['slug'], value: 'Home', }), ).toBe('Home'); }); it('handles non-english locales for case insensitive checks', () => { const name = 'État «œil»'; expect( uniquify({ items: baseItems.concat(name), value: 'état «Œil»', }), ).toBe('état «Œil» 2'); expect( uniquify({ caseSensitive: true, items: baseItems.concat(name), value: 'état «Œil»', }), ).toBe('état «Œil»'); }); }); });