str.trim and friends, list.map and friends

This commit is contained in:
Chris Wanstrath 2025-10-29 10:21:20 -07:00
parent 3496b29072
commit 07ffc7df97
2 changed files with 35 additions and 34 deletions

View File

@ -44,20 +44,26 @@ export const globalFunctions = {
}, },
// strings // strings
str: {
join: (arr: string[], sep: string = ',') => arr.join(sep), join: (arr: string[], sep: string = ',') => arr.join(sep),
split: (str: string, sep: string = ',') => str.split(sep), split: (str: string, sep: string = ',') => str.split(sep),
'to-upper': (str: string) => str.toUpperCase(), 'to-upper': (str: string) => str.toUpperCase(),
'to-lower': (str: string) => str.toLowerCase(), 'to-lower': (str: string) => str.toLowerCase(),
trim: (str: string) => str.trim(), trim: (str: string) => str.trim(),
str: { },
trim: (str: string) => str.trim(),
// list
list: {
slice: (list: any[], start: number, end?: number) => list.slice(start, end),
map: async (list: any[], cb: Function) => {
let acc: any[] = []
for (const value of list) acc.push(await cb(value))
return acc
},
}, },
// collections // collections
at: (collection: any, index: number | string) => collection[index], at: (collection: any, index: number | string) => collection[index],
list: (...args: any[]) => args,
dict: (atNamed = {}) => atNamed,
slice: (list: any[], start: number, end?: number) => list.slice(start, end),
range: (start: number, end: number | null) => { range: (start: number, end: number | null) => {
if (end === null) { if (end === null) {
end = start end = start
@ -71,11 +77,6 @@ export const globalFunctions = {
}, },
// enumerables // enumerables
map: async (list: any[], cb: Function) => {
let acc: any[] = []
for (const value of list) acc.push(await cb(value))
return acc
},
each: async (list: any[], cb: Function) => { each: async (list: any[], cb: Function) => {
for (const value of list) await cb(value) for (const value of list) await cb(value)
return list return list

View File

@ -3,13 +3,13 @@ import { globalFunctions } from '#prelude'
describe('string operations', () => { describe('string operations', () => {
test('to-upper converts to uppercase', async () => { test('to-upper converts to uppercase', async () => {
await expect(`to-upper 'hello'`).toEvaluateTo('HELLO', globalFunctions) await expect(`str.to-upper 'hello'`).toEvaluateTo('HELLO', globalFunctions)
await expect(`to-upper 'Hello World!'`).toEvaluateTo('HELLO WORLD!', globalFunctions) await expect(`str.to-upper 'Hello World!'`).toEvaluateTo('HELLO WORLD!', globalFunctions)
}) })
test('to-lower converts to lowercase', async () => { test('to-lower converts to lowercase', async () => {
await expect(`to-lower 'HELLO'`).toEvaluateTo('hello', globalFunctions) await expect(`str.to-lower 'HELLO'`).toEvaluateTo('hello', globalFunctions)
await expect(`to-lower 'Hello World!'`).toEvaluateTo('hello world!', globalFunctions) await expect(`str.to-lower 'Hello World!'`).toEvaluateTo('hello world!', globalFunctions)
}) })
test('trim removes whitespace', async () => { test('trim removes whitespace', async () => {
@ -18,21 +18,21 @@ describe('string operations', () => {
}) })
test('split divides string by separator', async () => { test('split divides string by separator', async () => {
await expect(`split 'a,b,c' ','`).toEvaluateTo(['a', 'b', 'c'], globalFunctions) await expect(`str.split 'a,b,c' ','`).toEvaluateTo(['a', 'b', 'c'], globalFunctions)
await expect(`split 'hello' ''`).toEvaluateTo(['h', 'e', 'l', 'l', 'o'], globalFunctions) await expect(`str.split 'hello' ''`).toEvaluateTo(['h', 'e', 'l', 'l', 'o'], globalFunctions)
}) })
test('split with comma separator', async () => { test('split with comma separator', async () => {
await expect(`split 'a,b,c' ','`).toEvaluateTo(['a', 'b', 'c'], globalFunctions) await expect(`str.split 'a,b,c' ','`).toEvaluateTo(['a', 'b', 'c'], globalFunctions)
}) })
test('join combines array elements', async () => { test('join combines array elements', async () => {
await expect(`join ['a' 'b' 'c'] '-'`).toEvaluateTo('a-b-c', globalFunctions) await expect(`str.join ['a' 'b' 'c'] '-'`).toEvaluateTo('a-b-c', globalFunctions)
await expect(`join ['hello' 'world'] ' '`).toEvaluateTo('hello world', globalFunctions) await expect(`str.join ['hello' 'world'] ' '`).toEvaluateTo('hello world', globalFunctions)
}) })
test('join with comma separator', async () => { test('join with comma separator', async () => {
await expect(`join ['a' 'b' 'c'] ','`).toEvaluateTo('a,b,c', globalFunctions) await expect(`str.join ['a' 'b' 'c'] ','`).toEvaluateTo('a,b,c', globalFunctions)
}) })
}) })
@ -64,15 +64,15 @@ describe('introspection', () => {
}) })
describe('collections', () => { describe('collections', () => {
test('list creates array from arguments', async () => { test('literal array creates array from arguments', async () => {
await expect(`list 1 2 3`).toEvaluateTo([1, 2, 3], globalFunctions) await expect(`[ 1 2 3 ]`).toEvaluateTo([1, 2, 3], globalFunctions)
await expect(`list 'a' 'b'`).toEvaluateTo(['a', 'b'], globalFunctions) await expect(`['a' 'b']`).toEvaluateTo(['a', 'b'], globalFunctions)
await expect(`list`).toEvaluateTo([], globalFunctions) await expect(`[]`).toEvaluateTo([], globalFunctions)
}) })
test('dict creates object from named arguments', async () => { test('literal dict creates object from named arguments', async () => {
await expect(`dict a=1 b=2`).toEvaluateTo({ a: 1, b: 2 }, globalFunctions) await expect(`[ a=1 b=2 ]`).toEvaluateTo({ a: 1, b: 2 }, globalFunctions)
await expect(`dict`).toEvaluateTo({}, globalFunctions) await expect(`[=]`).toEvaluateTo({}, globalFunctions)
}) })
test('at retrieves element at index', async () => { test('at retrieves element at index', async () => {
@ -85,8 +85,8 @@ describe('collections', () => {
}) })
test('slice extracts array subset', async () => { test('slice extracts array subset', async () => {
await expect(`slice [1 2 3 4 5] 1 3`).toEvaluateTo([2, 3], globalFunctions) await expect(`list.slice [1 2 3 4 5] 1 3`).toEvaluateTo([2, 3], globalFunctions)
await expect(`slice [1 2 3 4 5] 2 5`).toEvaluateTo([3, 4, 5], globalFunctions) await expect(`list.slice [1 2 3 4 5] 2 5`).toEvaluateTo([3, 4, 5], globalFunctions)
}) })
test('range creates number sequence', async () => { test('range creates number sequence', async () => {
@ -104,14 +104,14 @@ describe('enumerables', () => {
test('map transforms array elements', async () => { test('map transforms array elements', async () => {
await expect(` await expect(`
double = do x: x * 2 end double = do x: x * 2 end
map [1 2 3] double list.map [1 2 3] double
`).toEvaluateTo([2, 4, 6], globalFunctions) `).toEvaluateTo([2, 4, 6], globalFunctions)
}) })
test('map handles empty array', async () => { test('map handles empty array', async () => {
await expect(` await expect(`
double = do x: x * 2 end double = do x: x * 2 end
map [] double list.map [] double
`).toEvaluateTo([], globalFunctions) `).toEvaluateTo([], globalFunctions)
}) })