squiggle/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res

87 lines
3.2 KiB
Plaintext
Raw Normal View History

2022-03-24 12:41:31 +00:00
open Jest
open Reducer_TestHelpers
2022-04-05 17:36:19 +00:00
2022-04-05 17:18:10 +00:00
let testParseToBe = (expr, answer) =>
test(expr, () => expectParseToBe(expr, answer))
2022-04-05 17:36:19 +00:00
let testDescParseToBe = (desc, expr, answer) =>
test(desc, () => expectParseToBe(expr, answer))
2022-04-05 17:18:10 +00:00
let testEvalToBe = (expr, answer) =>
test(expr, () => expectEvalToBe(expr, answer))
2022-04-05 17:36:19 +00:00
let testDescEvalToBe = (desc, expr, answer) =>
test(desc, () => expectEvalToBe(expr, answer))
2022-03-24 12:41:31 +00:00
describe("reducer using mathjs parse", () => {
// Test the MathJs parser compatibility
2022-03-30 10:53:36 +00:00
// Those tests toString that there is a semantic mapping from MathJs to Expression
2022-03-24 12:41:31 +00:00
// Reducer.parse is called by Reducer.eval
// See https://mathjs.org/docs/expressions/syntax.html
// See https://mathjs.org/docs/reference/functions.html
2022-03-30 10:53:36 +00:00
// Those tests toString that we are converting mathjs parse tree to what we need
2022-03-24 12:41:31 +00:00
describe("expressions", () => {
2022-04-05 17:18:10 +00:00
testParseToBe("1", "Ok(1)")
testParseToBe("(1)", "Ok(1)")
testParseToBe("1+2", "Ok((:add 1 2))")
testParseToBe("1+2", "Ok((:add 1 2))")
testParseToBe("1+2", "Ok((:add 1 2))")
testParseToBe("1+2*3", "Ok((:add 1 (:multiply 2 3)))")
2022-03-24 12:41:31 +00:00
})
describe("arrays", () => {
//Note. () is a empty list in Lisp
// The only builtin structure in Lisp is list. There are no arrays
// [1,2,3] becomes (1 2 3)
2022-04-05 17:36:19 +00:00
testDescParseToBe("empty", "[]", "Ok(())")
2022-04-05 17:18:10 +00:00
testParseToBe("[1, 2, 3]", "Ok((1 2 3))")
testParseToBe("['hello', 'world']", "Ok(('hello' 'world'))")
2022-04-05 17:36:19 +00:00
testDescParseToBe("index", "([0,1,2])[1]", "Ok((:$atIndex (0 1 2) (1)))")
2022-03-24 12:41:31 +00:00
})
describe("records", () => {
2022-04-05 17:36:19 +00:00
testDescParseToBe("define",
"{a: 1, b: 2}", "Ok((:$constructRecord (('a' 1) ('b' 2))))")
testDescParseToBe("use",
2022-03-29 09:09:59 +00:00
"{a: 1, b: 2}.a",
2022-04-05 17:36:19 +00:00
"Ok((:$atIndex (:$constructRecord (('a' 1) ('b' 2))) ('a')))")
2022-03-24 12:41:31 +00:00
})
})
describe("eval", () => {
// All MathJs operators and functions are builtin for string, float and boolean
// .e.g + - / * > >= < <= == /= not and or
// See https://mathjs.org/docs/expressions/syntax.html
// See https://mathjs.org/docs/reference/functions.html
describe("expressions", () => {
2022-04-05 17:18:10 +00:00
testEvalToBe("1", "Ok(1)")
testEvalToBe("1+2", "Ok(3)")
testEvalToBe("(1+2)*3", "Ok(9)")
testEvalToBe("2>1", "Ok(true)")
testEvalToBe("concat('a ', 'b')", "Ok('a b')")
testEvalToBe("log(10)", "Ok(2.302585092994046)")
testEvalToBe("cos(10)", "Ok(-0.8390715290764524)")
2022-03-24 12:41:31 +00:00
// TODO more built ins
})
describe("arrays", () => {
2022-03-29 09:09:59 +00:00
test("empty array", () => expectEvalToBe("[]", "Ok([])"))
2022-04-05 17:18:10 +00:00
testEvalToBe("[1, 2, 3]", "Ok([1, 2, 3])")
testEvalToBe("['hello', 'world']", "Ok(['hello', 'world'])")
testEvalToBe("([0,1,2])[1]", "Ok(1)")
2022-04-05 17:36:19 +00:00
testDescEvalToBe("index not found",
"([0,1,2])[10]", "Error(Array index not found: 10)")
2022-03-24 12:41:31 +00:00
})
describe("records", () => {
2022-03-29 09:09:59 +00:00
test("define", () => expectEvalToBe("{a: 1, b: 2}", "Ok({a: 1, b: 2})"))
test("index", () => expectEvalToBe("{a: 1}.a", "Ok(1)"))
test("index not found", () => expectEvalToBe("{a: 1}.b", "Error(Record property not found: b)"))
2022-03-24 12:41:31 +00:00
})
})
describe("test exceptions", () => {
2022-04-05 17:36:19 +00:00
testDescEvalToBe("javascript exception",
"jsraise('div by 0')", "Error(JS Exception: Error: 'div by 0')")
testDescEvalToBe("rescript exception",
"resraise()", "Error(TODO: unhandled rescript exception)")
2022-03-24 12:41:31 +00:00
})