diff --git a/packages/squiggle-lang/__tests__/TS/JS_test.ts b/packages/squiggle-lang/__tests__/TS/JS_test.ts index 871248da..733f31bd 100644 --- a/packages/squiggle-lang/__tests__/TS/JS_test.ts +++ b/packages/squiggle-lang/__tests__/TS/JS_test.ts @@ -1,5 +1,4 @@ -import { SqProject, SqValue } from "../../src/js"; -import { SqNumberValue } from "../../src/js/SqValue"; +import { run, SqProject, SqValue, SqValueTag } from "../../src/js"; import { testRun } from "./TestHelpers"; function Ok(x: b) { @@ -9,157 +8,121 @@ function Ok(x: b) { describe("Simple calculations and results", () => { test("mean(normal(5,2))", () => { const result = testRun("mean(normal(5,2))"); // FIXME - expect(result.value).toEqual(5); + expect(result.toString()).toEqual("5"); }); test("10+10", () => { - let result = testRun("10 + 10") as SqNumberValue; - expect(result.value).toEqual(20); + let result = testRun("10 + 10"); + expect(result.toString()).toEqual("20"); + }); +}); +describe("Log function", () => { + test("log(1) = 0", () => { + let foo = testRun("log(1)"); + expect(foo.toString()).toEqual("0"); }); }); -// describe("Log function", () => { -// test("log(1) = 0", () => { -// let foo = testRun("log(1)"); -// expect(foo).toEqual({ tag: "number", value: 0 }); -// }); -// }); -// describe("Array", () => { -// test("nested Array", () => { -// expect(testRun("[[1]]")).toEqual({ -// tag: "array", -// value: [ -// { -// tag: "array", -// value: [ -// { -// tag: "number", -// value: 1, -// }, -// ], -// }, -// ], -// }); -// }); -// }); +describe("Array", () => { + test("nested Array", () => { + expect(testRun("[[ 1 ]]").toString()).toEqual("[[1]]"); + }); +}); -// describe("Record", () => { -// test("Return record", () => { -// expect(testRun("{a: 1}")).toEqual({ -// tag: "record", -// value: { -// a: { -// tag: "number", -// value: 1, -// }, -// }, -// }); -// }); -// }); +describe("Record", () => { + test("Return record", () => { + expect(testRun("{a:1}").toString()).toEqual("{a: 1}"); + }); +}); -// describe("Partials", () => { -// test("Can pass variables between partials and cells", () => { -// const project = Project.create(); -// project.setSource("p1", "x = 5"); -// project.setSource("p2", "y = x + 2"); -// project.setSource("main", "y + 3"); -// project.run("main"); -// const result = project.getResult("main"); -// expect(result.tag).toEqual("Ok"); -// expect(result.value).toBeInstanceOf(SquiggleValue); -// expect(result.value).toHaveProperty("tag", "number"); -// failDefault(); // FIXME -// // let bindings = testRunPartial(`x = 5`); -// // let bindings2 = testRunPartial(`y = x + 2`, bindings); -// // expect(testRun(`y + 3`, bindings2)).toEqual({ -// // tag: "number", -// // value: 10, -// // }); -// }); -// test("Can merge bindings from three partials", () => { -// let bindings1 = testRunPartial(`x = 1`); -// let bindings2 = testRunPartial(`y = 2`); -// let bindings3 = testRunPartial(`z = 3`); -// expect( -// testRun(`x + y + z`, mergeBindings([bindings1, bindings2, bindings3])) -// ).toEqual({ -// tag: "number", -// value: 6, -// }); -// }); -// }); +describe("Continues", () => { + test("Bindings from continues are accessible", () => { + const project = SqProject.create(); + project.setSource("p1", "x = 5"); + project.setSource("p2", "y = x + 2"); + project.setSource("main", "y + 3"); + project.setContinues("main", ["p2"]); + project.setContinues("p2", ["p1"]); + project.run("main"); + const result = project.getResult("main"); + expect(result.tag).toEqual("Ok"); + expect(result.value.toString()).toEqual("10"); + }); + test("Can merge bindings from three partials", () => { + const project = SqProject.create(); + project.setSource("p1", "x = 1"); + project.setSource("p2", "y = 2"); + project.setSource("p3", "z = 3"); + project.setSource("main", "x + y + z"); + project.setContinues("main", ["p1", "p2", "p3"]); + project.run("main"); + const result = project.getResult("main"); + expect(result.tag).toEqual("Ok"); + expect(result.value.toString()).toEqual("6"); + }); +}); -// describe("JS Imports", () => { -// test("Can pass parameters into partials and cells", () => { -// let bindings = testRunPartial(`y = $x + 2`, defaultBindings, { x: 1 }); -// let bindings2 = testRunPartial(`z = y + $a`, bindings, { a: 3 }); -// expect(testRun(`z`, bindings2)).toEqual({ -// tag: "number", -// value: 6, -// }); -// }); -// test("Complicated deep parameters", () => { -// expect( -// testRun(`$x.y[0][0].w + $x.z + $u.v`, defaultBindings, { -// x: { y: [[{ w: 1 }]], z: 2 }, -// u: { v: 3 }, -// }) -// ).toEqual({ -// tag: "number", -// value: 6, -// }); -// }); -// }); +describe("Distribution", () => { + //It's important that sampleCount is less than 9. If it's more, than that will create randomness + //Also, note, the value should be created using makeSampleSetDist() later on. + let env = { sampleCount: 8, xyPointLength: 100 }; + let dist1Samples = [3, 4, 5, 6, 6, 7, 10, 15, 30]; + let dist1SampleCount = dist1Samples.length; -// describe("Distribution", () => { -// //It's important that sampleCount is less than 9. If it's more, than that will create randomness -// //Also, note, the value should be created using makeSampleSetDist() later on. -// let env = { sampleCount: 8, xyPointLength: 100 }; -// let dist1Samples = [3, 4, 5, 6, 6, 7, 10, 15, 30]; -// let dist1SampleCount = dist1Samples.length; -// let dist = new Distribution( -// { tag: "SampleSet", value: [3, 4, 5, 6, 6, 7, 10, 15, 30] }, -// env -// ); -// let dist2 = new Distribution( -// { tag: "SampleSet", value: [20, 22, 24, 29, 30, 35, 38, 44, 52] }, -// env -// ); + const buildDist = (samples: number[]) => { + const src = `SampleSet.fromList([${samples.join(",")}])`; + const { result } = run(src, { + environment: env, + }); + if (result.tag !== "Ok") { + throw new Error( + `Failed to build SampleSet: from ${src}: ${result.value}` + ); + } + const dist = result.value; + if (dist.tag !== SqValueTag.Distribution) { + throw new Error("Expected Distribution"); + } + return dist.value; + }; -// test("mean", () => { -// expect(dist.mean().value).toBeCloseTo(9.5555555); -// }); -// test("pdf", () => { -// expect(dist.pdf(5.0).value).toBeCloseTo(0.10499097598222966, 1); -// }); -// test("cdf", () => { -// expect(dist.cdf(5.0).value).toBeCloseTo( -// dist1Samples.filter((x) => x <= 5).length / dist1SampleCount, -// 1 -// ); -// }); -// test("inv", () => { -// expect(dist.inv(0.5).value).toBeCloseTo(6); -// }); -// test("toPointSet", () => { -// expect( -// resultMap(dist.toPointSet(), (r: Distribution) => r.toString()) -// ).toEqual(Ok("Point Set Distribution")); -// }); -// test("toSparkline", () => { -// expect(dist.toSparkline(20).value).toEqual("▁▁▃▇█▇▄▂▂▂▁▁▁▁▁▂▂▁▁▁"); -// }); -// test("algebraicAdd", () => { -// expect( -// resultMap(dist.algebraicAdd(dist2), (r: Distribution) => -// r.toSparkline(20) -// ).value -// ).toEqual(Ok("▁▁▂▄▆████▇▆▄▄▃▃▃▂▁▁▁")); -// }); -// test("pointwiseAdd", () => { -// expect( -// resultMap(dist.pointwiseAdd(dist2), (r: Distribution) => -// r.toSparkline(20) -// ).value -// ).toEqual(Ok("▁▂██▃▃▃▃▄▅▄▃▃▂▂▂▁▁▁▁")); -// }); -// }); + const dist = buildDist(dist1Samples); + const dist2 = buildDist([20, 22, 24, 29, 30, 35, 38, 44, 52]); + + test("mean", () => { + expect(dist.mean(env).value).toBeCloseTo(9.5555555); + }); + test("pdf", () => { + expect(dist.pdf(env, 5.0).value).toBeCloseTo(0.10499097598222966, 1); + }); + test("cdf", () => { + expect(dist.cdf(env, 5.0).value).toBeCloseTo( + dist1Samples.filter((x) => x <= 5).length / dist1SampleCount, + 1 + ); + }); + test("inv", () => { + expect(dist.inv(env, 0.5).value).toBeCloseTo(6); + }); + // test("toPointSet", () => { + // expect( + // resultMap(dist.toPointSet(), (r: Distribution) => r.toString()) + // ).toEqual(Ok("Point Set Distribution")); + // }); + // test("toSparkline", () => { + // expect(dist.toSparkline(20).value).toEqual("▁▁▃▇█▇▄▂▂▂▁▁▁▁▁▂▂▁▁▁"); + // }); + // test("algebraicAdd", () => { + // expect( + // resultMap(dist.algebraicAdd(dist2), (r: Distribution) => + // r.toSparkline(20) + // ).value + // ).toEqual(Ok("▁▁▂▄▆████▇▆▄▄▃▃▃▂▁▁▁")); + // }); + // test("pointwiseAdd", () => { + // expect( + // resultMap(dist.pointwiseAdd(dist2), (r: Distribution) => + // r.toSparkline(20) + // ).value + // ).toEqual(Ok("▁▂██▃▃▃▃▄▅▄▃▃▂▂▂▁▁▁▁")); + // }); +}); diff --git a/packages/squiggle-lang/__tests__/TS/Jstat_test.ts b/packages/squiggle-lang/__tests__/TS/Jstat_test.ts index 039c517a..f0e895a8 100644 --- a/packages/squiggle-lang/__tests__/TS/Jstat_test.ts +++ b/packages/squiggle-lang/__tests__/TS/Jstat_test.ts @@ -1,4 +1,3 @@ -// import { errorValueToString } from "../../src/js/index"; import * as fc from "fast-check"; import { testRun } from "./TestHelpers"; diff --git a/packages/squiggle-lang/__tests__/TS/Parser_test.ts b/packages/squiggle-lang/__tests__/TS/Parser_test.ts index 1a87a5ef..d2715c09 100644 --- a/packages/squiggle-lang/__tests__/TS/Parser_test.ts +++ b/packages/squiggle-lang/__tests__/TS/Parser_test.ts @@ -36,9 +36,9 @@ describe("Squiggle's parser is whitespace insensitive", () => { whitespaceGen(), whitespaceGen(), (a, b, c, d, e, f, g, h) => { - expect(testRun(squiggleString(a, b, c, d, e, f, g, h))).toEqual( - squiggleOutput - ); + expect( + testRun(squiggleString(a, b, c, d, e, f, g, h)) + ).toEqualSqValue(squiggleOutput); } ) ); diff --git a/packages/squiggle-lang/__tests__/TS/PointSet_test.ts b/packages/squiggle-lang/__tests__/TS/PointSet_test.ts index 60a8e4e4..73a4f9ab 100644 --- a/packages/squiggle-lang/__tests__/TS/PointSet_test.ts +++ b/packages/squiggle-lang/__tests__/TS/PointSet_test.ts @@ -1,4 +1,3 @@ -// import { errorValueToString } from "../../src/js/index"; import { testRun, expectErrorToBeBounded, SqValueTag } from "./TestHelpers"; import * as fc from "fast-check"; diff --git a/packages/squiggle-lang/__tests__/TS/TestHelpers.ts b/packages/squiggle-lang/__tests__/TS/TestHelpers.ts index ceb807e6..4f9516d7 100644 --- a/packages/squiggle-lang/__tests__/TS/TestHelpers.ts +++ b/packages/squiggle-lang/__tests__/TS/TestHelpers.ts @@ -1,16 +1,21 @@ import { run, SqValueTag } from "../../src/js"; export { SqValueTag }; +expect.extend({ + toEqualSqValue(x, y) { + // hack via https://github.com/facebook/jest/issues/10329#issuecomment-820656061 + const { getMatchers } = require("expect/build/jestMatchersObject"); + return getMatchers().toEqual.call(this, x.toString(), y.toString()); + }, +}); + export function testRun(x: string) { - const { result, bindings } = run(x); // FIXME - set environment - // x, - // bindings, - // { - // sampleCount: 1000, - // xyPointLength: 100, - // }, - // imports - // ); + const { result, bindings } = run(x, { + environment: { + sampleCount: 1000, + xyPointLength: 100, + }, + }); if (result.tag === "Ok") { return result.value; diff --git a/packages/squiggle-lang/src/js/SqValue.ts b/packages/squiggle-lang/src/js/SqValue.ts index f4e0b512..abb49ae8 100644 --- a/packages/squiggle-lang/src/js/SqValue.ts +++ b/packages/squiggle-lang/src/js/SqValue.ts @@ -32,6 +32,10 @@ export abstract class SqAbstractValue { } return value; }; + + toString() { + return RSValue.toString(this._value); + } } export class SqArrayValue extends SqAbstractValue {