import { equal, isNull } from "./comparison"; import { assertResult } from "./env"; import { toJson } from "./formatPrint"; // @ts-ignore @inline const EXPECT_MAX_INDEX = 2147483647; export class Value { reversed: bool = false; data: T; constructor(_data: T) { this.data = _data; } private collect( result: bool, codeInfoIndex: number, actualValue: string, expectValue: string, ): void { assertResult.collectCheckResult( this.reversed ? !result : result, codeInfoIndex, actualValue, expectValue, ); } get not(): Value { this.reversed = !this.reversed; return this; } isNull(codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value { this.collect( isNull(this.data), codeInfoIndex, toJson(this.data), "to be null", ); return this; } notNull(codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value { this.collect( !isNull(this.data), codeInfoIndex, toJson(this.data), "notNull", ); return this; } equal(checkValue: T, codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value { this.collect( equal(this.data, checkValue), codeInfoIndex, toJson(this.data), "= " + toJson(checkValue), ); return this; } notEqual(checkValue: T, codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value { this.collect( !equal(this.data, checkValue), codeInfoIndex, toJson(this.data), " != " + toJson(checkValue), ); return this; } greaterThan(checkValue: T, codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value { this.collect( this.data > checkValue, codeInfoIndex, toJson(this.data), " > " + toJson(checkValue), ); return this; } greaterThanOrEqual( checkValue: T, codeInfoIndex: u32 = EXPECT_MAX_INDEX, ): Value { this.collect( this.data >= checkValue, codeInfoIndex, toJson(this.data), " >= " + toJson(checkValue), ); return this; } lessThan(checkValue: T, codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value { this.collect( this.data < checkValue, codeInfoIndex, toJson(this.data), " < " + toJson(checkValue), ); return this; } lessThanOrEqual( checkValue: T, codeInfoIndex: u32 = EXPECT_MAX_INDEX, ): Value { this.collect( this.data <= checkValue, codeInfoIndex, toJson(this.data), " <= " + toJson(checkValue), ); return this; } closeTo( checkValue: T, delta: number, codeInfoIndex: u32 = EXPECT_MAX_INDEX, ): Value { const data = this.data; if (isFloat(checkValue) && isFloat(data)) { this.collect( abs(data - checkValue) < delta, codeInfoIndex, toJson(this.data), " closeTo " + toJson(checkValue), ); } else { ERROR("closeTo should only be used in f32 | f64"); } return this; } isa(codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value { this.collect( // @ts-ignore this.data instanceof ExpectType, codeInfoIndex, // TODO: need extend chain information `RTID<${load(changetype(this.data) - 8)}>`, `RTID<${idof()}>`, ); return this; } isExactly(codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value { if (isNullable()) { if (this.data == null) { this.collect( false, codeInfoIndex, `<>`, `RTID<${idof()}>`, ); return this; } } const rtid = load(changetype(this.data) - 8); this.collect( rtid == idof(), codeInfoIndex, `RTID<${rtid}>`, `RTID<${idof()}>`, ); return this; } }