shrimp/src/compiler/tests/pipe.test.ts

121 lines
3.1 KiB
TypeScript

import { describe, test, expect } from 'bun:test'
describe('pipe expressions', () => {
test('simple pipe passes result as first argument', () => {
const code = `
double = do x: x * 2 end
double 2 | double`
expect(code).toEvaluateTo(8)
})
test('pipe chain with three stages', () => {
const code = `
add-one = do x: x + 1 end
double = do x: x * 2 end
minus-point-one = do x: x - 0.1 end
add-one 3 | double | minus-point-one`
// 4 8 7.9
expect(code).toEvaluateTo(7.9)
})
test('pipe with function that has additional arguments', () => {
const code = `
multiply = do a b: a * b end
get-five = do: 5 end
get-five | multiply 3`
expect(code).toEvaluateTo(15)
})
test('pipe with bare identifier', () => {
const code = `
get-value = 42
process = do x: x + 10 end
get-value | process`
expect(code).toEvaluateTo(52)
})
test('pipe in assignment', () => {
const code = `
add-ten = do x: x + 10 end
result = add-ten 5 | add-ten
result`
// 5 + 10 = 15, then 15 + 10 = 25
expect(code).toEvaluateTo(25)
})
test('pipe with named underscore arg', () => {
expect(`
divide = do a b: a / b end
get-ten = do: 10 end
get-ten | divide 2 b=_`).toEvaluateTo(0.2)
expect(`
divide = do a b: a / b end
get-ten = do: 10 end
get-ten | divide b=_ 2`).toEvaluateTo(0.2)
expect(`
divide = do a b: a / b end
get-ten = do: 10 end
get-ten | divide 2 a=_`).toEvaluateTo(5)
expect(`
divide = do a b: a / b end
get-ten = do: 10 end
get-ten | divide a=_ 2`).toEvaluateTo(5)
})
test('nested pipes', () => {
// This is complicated, but the idea is to make sure the underscore
// handling logic works correctly when there are multiple pipe stages
// in a single expression.
expect(`
sub = do a b: a - b end
div = do a b: a / b end
sub 3 1 | div (sub 110 9 | sub 1) _ | div 5`).toEvaluateTo(10)
})
test('pipe with prelude functions (list.reverse and list.map)', () => {
expect(`
double = do x: x * 2 end
range 1 3 | list.reverse | list.map double
`).toEvaluateTo([6, 4, 2])
})
test('pipe with prelude function (echo)', () => {
expect(`
get-msg = do: 'hello' end
get-msg | length
`).toEvaluateTo(5)
})
test('string literals can be piped', () => {
expect(`'hey there' | str.to-upper`).toEvaluateTo('HEY THERE')
})
test('number literals can be piped', () => {
expect(`42 | str.trim`).toEvaluateTo('42')
expect(`4.22 | str.trim`).toEvaluateTo('4.22')
})
test('null literals can be piped', () => {
expect(`null | type`).toEvaluateTo('null')
})
test('boolean literals can be piped', () => {
expect(`true | str.to-upper`).toEvaluateTo('TRUE')
})
test('array literals can be piped', () => {
expect(`[1 2 3] | str.join '-'`).toEvaluateTo('1-2-3')
})
test('dict literals can be piped', () => {
expect(`[a=1 b=2 c=3] | dict.values | list.sort | str.join '-'`).toEvaluateTo('1-2-3')
})
})