mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
* feat(utils): add record guards and pure helpers to @sim/utils Add isRecordLike (loose, non-prototype-checked record guard) and sortObjectKeysDeep; relocate isPlainRecord (strict) and normalizeEmail into @sim/utils so they are reusable across apps and packages. Unit tests cover the loose-vs-strict distinction, deep key sorting, and email normalization. * refactor(sim): consolidate record guards and normalize helpers onto @sim/utils Replace ~55 re-implemented loose record guards with the canonical @sim/utils isRecordLike (and one strict site with isPlainRecord), and dedupe three normalize clusters: sortObjectKeysDeep (sanitization + copilot builders), normalizeToken (salesforce + servicenow triggers), and normalizeEmail. Array-allowing guards and domain-specific normalizers are intentionally left untouched. Pure refactor — identical predicates and transforms, no behavior change.
68 lines
2.1 KiB
TypeScript
68 lines
2.1 KiB
TypeScript
/**
|
|
* @vitest-environment node
|
|
*/
|
|
import { describe, expect, it } from 'vitest'
|
|
import { isVersionedType, normalizeEmail, stripVersionSuffix, truncate } from './string.js'
|
|
|
|
describe('truncate', () => {
|
|
it('appends the suffix when the string exceeds the slice length', () => {
|
|
expect(truncate('hello world', 8)).toBe('hello wo...')
|
|
})
|
|
|
|
it('uses a custom suffix when provided', () => {
|
|
expect(truncate('hello world', 8, ' …')).toBe('hello wo …')
|
|
})
|
|
|
|
it('returns the original string when within the slice length', () => {
|
|
expect(truncate('hi', 10)).toBe('hi')
|
|
})
|
|
})
|
|
|
|
describe('stripVersionSuffix', () => {
|
|
it('strips a trailing _vN suffix', () => {
|
|
expect(stripVersionSuffix('notion_search_v2')).toBe('notion_search')
|
|
expect(stripVersionSuffix('github_create_pr_v3')).toBe('github_create_pr')
|
|
})
|
|
|
|
it('strips multi-digit versions', () => {
|
|
expect(stripVersionSuffix('x_v10')).toBe('x')
|
|
})
|
|
|
|
it('leaves plain values unchanged', () => {
|
|
expect(stripVersionSuffix('plain')).toBe('plain')
|
|
})
|
|
|
|
it('does not strip a non-version trailing token', () => {
|
|
expect(stripVersionSuffix('a_version')).toBe('a_version')
|
|
})
|
|
|
|
it('only strips the single trailing suffix', () => {
|
|
expect(stripVersionSuffix('a_v2_v3')).toBe('a_v2')
|
|
})
|
|
})
|
|
|
|
describe('isVersionedType', () => {
|
|
it('returns true for trailing _vN suffixes', () => {
|
|
expect(isVersionedType('notion_search_v2')).toBe(true)
|
|
expect(isVersionedType('github_create_pr_v3')).toBe(true)
|
|
expect(isVersionedType('x_v10')).toBe(true)
|
|
expect(isVersionedType('a_v2_v3')).toBe(true)
|
|
})
|
|
|
|
it('returns false when there is no trailing version suffix', () => {
|
|
expect(isVersionedType('plain')).toBe(false)
|
|
expect(isVersionedType('a_version')).toBe(false)
|
|
expect(isVersionedType('x')).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('normalizeEmail', () => {
|
|
it('trims surrounding whitespace and lowercases', () => {
|
|
expect(normalizeEmail(' USER@Example.COM ')).toBe('user@example.com')
|
|
})
|
|
|
|
it('leaves an already-normalized email unchanged', () => {
|
|
expect(normalizeEmail('user@example.com')).toBe('user@example.com')
|
|
})
|
|
})
|