302 lines
6.9 KiB
TypeScript
302 lines
6.9 KiB
TypeScript
import { describe, test, expect } from 'bun:test'
|
|
import '../../testSetup'
|
|
|
|
describe('DotGet', () => {
|
|
test('readme.txt is Word when readme not in scope', () => {
|
|
expect('readme.txt').toMatchTree(`Word readme.txt`)
|
|
})
|
|
|
|
test('readme.txt is Word when used in function', () => {
|
|
expect('echo readme.txt').toMatchTree(`
|
|
FunctionCall
|
|
Identifier echo
|
|
PositionalArg
|
|
Word readme.txt`)
|
|
})
|
|
|
|
test('obj.prop is DotGet when obj is assigned', () => {
|
|
expect('obj = 5; obj.prop').toMatchTree(`
|
|
Assign
|
|
AssignableIdentifier obj
|
|
Eq =
|
|
Number 5
|
|
FunctionCallOrIdentifier
|
|
DotGet
|
|
IdentifierBeforeDot obj
|
|
Identifier prop
|
|
`)
|
|
})
|
|
|
|
test('function parameters are in scope within function body', () => {
|
|
expect('do config: config.path end').toMatchTree(`
|
|
FunctionDef
|
|
Do do
|
|
Params
|
|
Identifier config
|
|
colon :
|
|
FunctionCallOrIdentifier
|
|
DotGet
|
|
IdentifierBeforeDot config
|
|
Identifier path
|
|
keyword end
|
|
`)
|
|
})
|
|
|
|
test('parameters out of scope outside function', () => {
|
|
expect('do x: x.prop end; x.prop').toMatchTree(`
|
|
FunctionDef
|
|
Do do
|
|
Params
|
|
Identifier x
|
|
colon :
|
|
FunctionCallOrIdentifier
|
|
DotGet
|
|
IdentifierBeforeDot x
|
|
Identifier prop
|
|
keyword end
|
|
Word x.prop
|
|
`)
|
|
})
|
|
|
|
test('multiple parameters work correctly', () => {
|
|
expect(`do x y:
|
|
x.foo
|
|
y.bar
|
|
end`).toMatchTree(`
|
|
FunctionDef
|
|
Do do
|
|
Params
|
|
Identifier x
|
|
Identifier y
|
|
colon :
|
|
FunctionCallOrIdentifier
|
|
DotGet
|
|
IdentifierBeforeDot x
|
|
Identifier foo
|
|
FunctionCallOrIdentifier
|
|
DotGet
|
|
IdentifierBeforeDot y
|
|
Identifier bar
|
|
keyword end
|
|
`)
|
|
})
|
|
|
|
test('nested functions with scope isolation', () => {
|
|
expect(`do x:
|
|
x.outer
|
|
do y: y.inner end
|
|
end`).toMatchTree(`
|
|
FunctionDef
|
|
Do do
|
|
Params
|
|
Identifier x
|
|
colon :
|
|
FunctionCallOrIdentifier
|
|
DotGet
|
|
IdentifierBeforeDot x
|
|
Identifier outer
|
|
FunctionDef
|
|
Do do
|
|
Params
|
|
Identifier y
|
|
colon :
|
|
FunctionCallOrIdentifier
|
|
DotGet
|
|
IdentifierBeforeDot y
|
|
Identifier inner
|
|
keyword end
|
|
keyword end
|
|
`)
|
|
})
|
|
|
|
test('dot get works as function argument', () => {
|
|
expect('config = 42; echo config.path').toMatchTree(`
|
|
Assign
|
|
AssignableIdentifier config
|
|
Eq =
|
|
Number 42
|
|
FunctionCall
|
|
Identifier echo
|
|
PositionalArg
|
|
DotGet
|
|
IdentifierBeforeDot config
|
|
Identifier path
|
|
`)
|
|
})
|
|
|
|
test('dot get works as bare function', () => {
|
|
expect('io = dict print=echo; io.print').toMatchTree(`
|
|
Assign
|
|
AssignableIdentifier io
|
|
Eq =
|
|
FunctionCall
|
|
Identifier dict
|
|
NamedArg
|
|
NamedArgPrefix print=
|
|
Identifier echo
|
|
FunctionCallOrIdentifier
|
|
DotGet
|
|
IdentifierBeforeDot io
|
|
Identifier print
|
|
`)
|
|
})
|
|
|
|
test('dot get works as function w/ args', () => {
|
|
expect('io = dict print=echo; io.print heya').toMatchTree(`
|
|
Assign
|
|
AssignableIdentifier io
|
|
Eq =
|
|
FunctionCall
|
|
Identifier dict
|
|
NamedArg
|
|
NamedArgPrefix print=
|
|
Identifier echo
|
|
FunctionCall
|
|
DotGet
|
|
IdentifierBeforeDot io
|
|
Identifier print
|
|
PositionalArg
|
|
Identifier heya
|
|
`)
|
|
})
|
|
|
|
test('dot get works as function in parens', () => {
|
|
expect('io = dict print=echo; (io.print heya)').toMatchTree(`
|
|
Assign
|
|
AssignableIdentifier io
|
|
Eq =
|
|
FunctionCall
|
|
Identifier dict
|
|
NamedArg
|
|
NamedArgPrefix print=
|
|
Identifier echo
|
|
ParenExpr
|
|
FunctionCall
|
|
DotGet
|
|
IdentifierBeforeDot io
|
|
Identifier print
|
|
PositionalArg
|
|
Identifier heya
|
|
`)
|
|
})
|
|
|
|
test('mixed file paths and dot get', () => {
|
|
expect('config = 42; cat readme.txt; echo config.path').toMatchTree(`
|
|
Assign
|
|
AssignableIdentifier config
|
|
Eq =
|
|
Number 42
|
|
FunctionCall
|
|
Identifier cat
|
|
PositionalArg
|
|
Word readme.txt
|
|
FunctionCall
|
|
Identifier echo
|
|
PositionalArg
|
|
DotGet
|
|
IdentifierBeforeDot config
|
|
Identifier path
|
|
`)
|
|
})
|
|
|
|
test("dot get doesn't work with spaces", () => {
|
|
expect('obj . prop').toMatchTree(`
|
|
FunctionCall
|
|
Identifier obj
|
|
PositionalArg
|
|
Word .
|
|
PositionalArg
|
|
Identifier prop`)
|
|
})
|
|
|
|
test('readme.1 is Word when readme not in scope', () => {
|
|
expect('readme.1').toMatchTree(`Word readme.1`)
|
|
})
|
|
|
|
test('readme.1 is Word when used in function', () => {
|
|
expect('echo readme.1').toMatchTree(`
|
|
FunctionCall
|
|
Identifier echo
|
|
PositionalArg
|
|
Word readme.1`)
|
|
})
|
|
|
|
test('obj.1 is DotGet when obj is assigned', () => {
|
|
expect('obj = 5; obj.1').toMatchTree(`
|
|
Assign
|
|
AssignableIdentifier obj
|
|
Eq =
|
|
Number 5
|
|
FunctionCallOrIdentifier
|
|
DotGet
|
|
IdentifierBeforeDot obj
|
|
Number 1
|
|
`)
|
|
})
|
|
|
|
test('obj.1 arg is DotGet when obj is assigned', () => {
|
|
expect('obj = 5; obj.1').toMatchTree(`
|
|
Assign
|
|
AssignableIdentifier obj
|
|
Eq =
|
|
Number 5
|
|
FunctionCallOrIdentifier
|
|
DotGet
|
|
IdentifierBeforeDot obj
|
|
Number 1
|
|
`)
|
|
})
|
|
|
|
test('dot get index works as function w/ args', () => {
|
|
expect(`io = list (do x: echo x end); io.0 heya`).toMatchTree(`
|
|
Assign
|
|
AssignableIdentifier io
|
|
Eq =
|
|
FunctionCall
|
|
Identifier list
|
|
PositionalArg
|
|
ParenExpr
|
|
FunctionDef
|
|
Do do
|
|
Params
|
|
Identifier x
|
|
colon :
|
|
FunctionCall
|
|
Identifier echo
|
|
PositionalArg
|
|
Identifier x
|
|
keyword end
|
|
FunctionCall
|
|
DotGet
|
|
IdentifierBeforeDot io
|
|
Number 0
|
|
PositionalArg
|
|
Identifier heya
|
|
`)
|
|
})
|
|
|
|
test('can use the result of a parens expression as the property of dot get', () => {
|
|
expect('obj = list 1 2 3; obj.(1 + 2)').toMatchTree(`
|
|
Assign
|
|
AssignableIdentifier obj
|
|
Eq =
|
|
FunctionCall
|
|
Identifier list
|
|
PositionalArg
|
|
Number 1
|
|
PositionalArg
|
|
Number 2
|
|
PositionalArg
|
|
Number 3
|
|
FunctionCallOrIdentifier
|
|
DotGet
|
|
IdentifierBeforeDot obj
|
|
ParenExpr
|
|
BinOp
|
|
Number 1
|
|
Plus +
|
|
Number 2
|
|
`)
|
|
})
|
|
})
|