prelude tests
This commit is contained in:
parent
339127e692
commit
de30d85304
|
|
@ -44,7 +44,7 @@ export const globalFunctions = {
|
|||
},
|
||||
|
||||
// strings
|
||||
join: (arr: any[], sep: string = ',') => arr.join(sep),
|
||||
join: (arr: string[], sep: string = ',') => arr.join(sep),
|
||||
split: (str: string, sep: string = ',') => str.split(sep),
|
||||
'to-upper': (str: string) => str.toUpperCase(),
|
||||
'to-lower': (str: string) => str.toLowerCase(),
|
||||
|
|
|
|||
256
src/prelude/tests/prelude.test.ts
Normal file
256
src/prelude/tests/prelude.test.ts
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
import { expect, describe, test, mock } from 'bun:test'
|
||||
import { globalFunctions, formatValue } from '#prelude'
|
||||
import { toValue } from 'reefvm'
|
||||
|
||||
describe('string operations', () => {
|
||||
test('to-upper converts to uppercase', () => {
|
||||
expect(globalFunctions['to-upper']('hello')).toBe('HELLO')
|
||||
expect(globalFunctions['to-upper']('Hello World!')).toBe('HELLO WORLD!')
|
||||
})
|
||||
|
||||
test('to-lower converts to lowercase', () => {
|
||||
expect(globalFunctions['to-lower']('HELLO')).toBe('hello')
|
||||
expect(globalFunctions['to-lower']('Hello World!')).toBe('hello world!')
|
||||
})
|
||||
|
||||
test('trim removes whitespace', () => {
|
||||
expect(globalFunctions.trim(' hello ')).toBe('hello')
|
||||
expect(globalFunctions.trim('\n\thello\t\n')).toBe('hello')
|
||||
})
|
||||
|
||||
test('split divides string by separator', () => {
|
||||
expect(globalFunctions.split('a,b,c', ',')).toEqual(['a', 'b', 'c'])
|
||||
expect(globalFunctions.split('hello', '')).toEqual(['h', 'e', 'l', 'l', 'o'])
|
||||
})
|
||||
|
||||
test('split uses comma as default separator', () => {
|
||||
expect(globalFunctions.split('a,b,c')).toEqual(['a', 'b', 'c'])
|
||||
})
|
||||
|
||||
test('join combines array elements', () => {
|
||||
expect(globalFunctions.join(['a', 'b', 'c'], '-')).toBe('a-b-c')
|
||||
expect(globalFunctions.join(['hello', 'world'], ' ')).toBe('hello world')
|
||||
})
|
||||
|
||||
test('join uses comma as default separator', () => {
|
||||
expect(globalFunctions.join(['a', 'b', 'c'])).toBe('a,b,c')
|
||||
})
|
||||
})
|
||||
|
||||
describe('introspection', () => {
|
||||
test('type returns proper types', () => {
|
||||
expect(globalFunctions.type(toValue('hello'))).toBe('string')
|
||||
expect(globalFunctions.type('hello')).toBe('string')
|
||||
|
||||
expect(globalFunctions.type(toValue(42))).toBe('number')
|
||||
expect(globalFunctions.type(42)).toBe('number')
|
||||
|
||||
expect(globalFunctions.type(toValue(true))).toBe('boolean')
|
||||
expect(globalFunctions.type(false)).toBe('boolean')
|
||||
|
||||
expect(globalFunctions.type(toValue(null))).toBe('null')
|
||||
|
||||
expect(globalFunctions.type(toValue([1, 2, 3]))).toBe('array')
|
||||
|
||||
const dict = new Map([['key', toValue('value')]])
|
||||
expect(globalFunctions.type({ type: 'dict', value: dict })).toBe('dict')
|
||||
})
|
||||
|
||||
test('length', () => {
|
||||
expect(globalFunctions.length(toValue('hello'))).toBe(5)
|
||||
expect(globalFunctions.length('hello')).toBe(5)
|
||||
|
||||
expect(globalFunctions.length(toValue([1, 2, 3]))).toBe(3)
|
||||
expect(globalFunctions.length([1, 2, 3])).toBe(3)
|
||||
|
||||
const dict = new Map([['a', toValue(1)], ['b', toValue(2)]])
|
||||
expect(globalFunctions.length({ type: 'dict', value: dict })).toBe(2)
|
||||
|
||||
expect(globalFunctions.length(toValue(42))).toBe(0)
|
||||
expect(globalFunctions.length(toValue(true))).toBe(0)
|
||||
expect(globalFunctions.length(toValue(null))).toBe(0)
|
||||
})
|
||||
|
||||
test('inspect formats values', () => {
|
||||
const result = globalFunctions.inspect(toValue('hello'))
|
||||
expect(result).toContain('hello')
|
||||
})
|
||||
})
|
||||
|
||||
describe('collections', () => {
|
||||
test('list creates array from arguments', () => {
|
||||
expect(globalFunctions.list(1, 2, 3)).toEqual([1, 2, 3])
|
||||
expect(globalFunctions.list('a', 'b')).toEqual(['a', 'b'])
|
||||
expect(globalFunctions.list()).toEqual([])
|
||||
})
|
||||
|
||||
test('dict creates object from named arguments', () => {
|
||||
expect(globalFunctions.dict({ a: 1, b: 2 })).toEqual({ a: 1, b: 2 })
|
||||
expect(globalFunctions.dict()).toEqual({})
|
||||
})
|
||||
|
||||
test('at retrieves element at index', () => {
|
||||
expect(globalFunctions.at([10, 20, 30], 0)).toBe(10)
|
||||
expect(globalFunctions.at([10, 20, 30], 2)).toBe(30)
|
||||
})
|
||||
|
||||
test('at retrieves property from object', () => {
|
||||
expect(globalFunctions.at({ name: 'test' }, 'name')).toBe('test')
|
||||
})
|
||||
|
||||
test('slice extracts array subset', () => {
|
||||
expect(globalFunctions.slice([1, 2, 3, 4, 5], 1, 3)).toEqual([2, 3])
|
||||
expect(globalFunctions.slice([1, 2, 3, 4, 5], 2)).toEqual([3, 4, 5])
|
||||
})
|
||||
|
||||
test('range creates number sequence', () => {
|
||||
expect(globalFunctions.range(0, 5)).toEqual([0, 1, 2, 3, 4, 5])
|
||||
expect(globalFunctions.range(3, 6)).toEqual([3, 4, 5, 6])
|
||||
})
|
||||
|
||||
test('range with single argument starts from 0', () => {
|
||||
expect(globalFunctions.range(3, null)).toEqual([0, 1, 2, 3])
|
||||
expect(globalFunctions.range(0, null)).toEqual([0])
|
||||
})
|
||||
})
|
||||
|
||||
describe('enumerables', () => {
|
||||
test('map transforms array elements', async () => {
|
||||
const double = (x: number) => x * 2
|
||||
const result = await globalFunctions.map([1, 2, 3], double)
|
||||
expect(result).toEqual([2, 4, 6])
|
||||
})
|
||||
|
||||
test('map works with async callbacks', async () => {
|
||||
const asyncDouble = async (x: number) => {
|
||||
await Promise.resolve()
|
||||
return x * 2
|
||||
}
|
||||
const result = await globalFunctions.map([1, 2, 3], asyncDouble)
|
||||
expect(result).toEqual([2, 4, 6])
|
||||
})
|
||||
|
||||
test('map handles empty array', async () => {
|
||||
const fn = (x: number) => x * 2
|
||||
const result = await globalFunctions.map([], fn)
|
||||
expect(result).toEqual([])
|
||||
})
|
||||
|
||||
test('each iterates over array', async () => {
|
||||
const results: number[] = []
|
||||
await globalFunctions.each([1, 2, 3], (x: number) => {
|
||||
results.push(x * 2)
|
||||
})
|
||||
expect(results).toEqual([2, 4, 6])
|
||||
})
|
||||
|
||||
test('each works with async callbacks', async () => {
|
||||
const results: number[] = []
|
||||
await globalFunctions.each([1, 2, 3], async (x: number) => {
|
||||
await Promise.resolve()
|
||||
results.push(x * 2)
|
||||
})
|
||||
expect(results).toEqual([2, 4, 6])
|
||||
})
|
||||
|
||||
test('each handles empty array', async () => {
|
||||
let called = false
|
||||
await globalFunctions.each([], () => {
|
||||
called = true
|
||||
})
|
||||
expect(called).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('echo', () => {
|
||||
test('echo logs arguments to console', () => {
|
||||
const spy = mock(() => { })
|
||||
const originalLog = console.log
|
||||
console.log = spy
|
||||
|
||||
globalFunctions.echo('hello', 'world')
|
||||
|
||||
expect(spy).toHaveBeenCalledWith('hello', 'world')
|
||||
console.log = originalLog
|
||||
})
|
||||
|
||||
test('echo returns null value', () => {
|
||||
const originalLog = console.log
|
||||
console.log = () => { }
|
||||
|
||||
const result = globalFunctions.echo('test')
|
||||
|
||||
expect(result).toEqual(toValue(null))
|
||||
console.log = originalLog
|
||||
})
|
||||
|
||||
test('echo formats array values', () => {
|
||||
const spy = mock(() => { })
|
||||
const originalLog = console.log
|
||||
console.log = spy
|
||||
|
||||
globalFunctions.echo(toValue([1, 2, 3]))
|
||||
|
||||
// Should format the array, not just log the raw value
|
||||
expect(spy).toHaveBeenCalled()
|
||||
// @ts-ignore
|
||||
const logged = spy.mock.calls[0][0]
|
||||
// @ts-ignore
|
||||
expect(logged).toContain('list')
|
||||
|
||||
console.log = originalLog
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatValue', () => {
|
||||
test('formats string with quotes', () => {
|
||||
const result = formatValue(toValue('hello'))
|
||||
expect(result).toContain('hello')
|
||||
expect(result).toContain("'")
|
||||
})
|
||||
|
||||
test('formats numbers', () => {
|
||||
const result = formatValue(toValue(42))
|
||||
expect(result).toContain('42')
|
||||
})
|
||||
|
||||
test('formats booleans', () => {
|
||||
expect(formatValue(toValue(true))).toContain('true')
|
||||
expect(formatValue(toValue(false))).toContain('false')
|
||||
})
|
||||
|
||||
test('formats null', () => {
|
||||
const result = formatValue(toValue(null))
|
||||
expect(result).toContain('null')
|
||||
})
|
||||
|
||||
test('formats arrays', () => {
|
||||
const result = formatValue(toValue([1, 2, 3]))
|
||||
expect(result).toContain('list')
|
||||
})
|
||||
|
||||
test('formats nested arrays with parentheses', () => {
|
||||
const inner = toValue([1, 2])
|
||||
const outer = toValue([inner])
|
||||
const result = formatValue(outer)
|
||||
expect(result).toContain('list')
|
||||
expect(result).toContain('(')
|
||||
expect(result).toContain(')')
|
||||
})
|
||||
|
||||
test('formats dicts', () => {
|
||||
const dict = new Map([
|
||||
['name', toValue('test')],
|
||||
['age', toValue(42)]
|
||||
])
|
||||
const result = formatValue({ type: 'dict', value: dict })
|
||||
expect(result).toContain('dict')
|
||||
expect(result).toContain('name=')
|
||||
expect(result).toContain('age=')
|
||||
})
|
||||
|
||||
test('escapes single quotes in strings', () => {
|
||||
const result = formatValue(toValue("it's"))
|
||||
expect(result).toContain("\\'")
|
||||
})
|
||||
})
|
||||
Loading…
Reference in New Issue
Block a user