Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Commit

Permalink
Arbitrary: fix issue with generating optional tuple elements
Browse files Browse the repository at this point in the history
  • Loading branch information
gcanti committed Oct 19, 2023
1 parent db5b5a3 commit 27cfd34
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .changeset/strange-bananas-repair.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect/schema": patch
---

Arbitrary: fix issue with generating optional tuple elements
32 changes: 22 additions & 10 deletions src/Arbitrary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,22 +127,34 @@ export const go = (ast: AST.AST, constraints?: Constraints): Arbitrary<any> => {
}
}
case "Tuple": {
const elements = ast.elements.map((e) => go(e.type))
const elements: Array<Arbitrary<any>> = []
let hasOptionals = false
for (const element of ast.elements) {
elements.push(go(element.type))
if (element.isOptional) {
hasOptionals = true
}
}
const rest = pipe(ast.rest, Option.map(ReadonlyArray.mapNonEmpty((e) => go(e))))
return (fc) => {
// ---------------------------------------------
// handle elements
// ---------------------------------------------
let output = fc.tuple(...elements.map((arb) => arb(fc)))
if (elements.length > 0 && Option.isNone(rest)) {
const firstOptionalIndex = ast.elements.findIndex((e) => e.isOptional)
if (firstOptionalIndex !== -1) {
output = output.chain((as) =>
fc.integer({ min: firstOptionalIndex, max: elements.length - 1 }).map((i) =>
as.slice(0, i)
)
)
}
if (hasOptionals) {
const indexes = fc.tuple(
...ast.elements.map((element) => element.isOptional ? fc.boolean() : fc.constant(true))
)
output = output.chain((tuple) =>
indexes.map((booleans) => {
for (const [i, b] of booleans.reverse().entries()) {
if (!b) {
tuple.splice(booleans.length - i, 1)
}
}
return tuple
})
)
}

// ---------------------------------------------
Expand Down
10 changes: 0 additions & 10 deletions test/compiler/JSONSchema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,16 +371,6 @@ describe("jsonSchemaFor", () => {
property(schema)
})

it("tuple. optional element", () => {
const schema = S.tuple().pipe(S.optionalElement(S.number))
property(schema)
})

it("tuple. e + e?", () => {
const schema = S.tuple(S.string).pipe(S.optionalElement(S.number))
property(schema)
})

it("tuple. e + r", () => {
const schema = S.tuple(S.string).pipe(S.rest(S.number))
property(schema)
Expand Down

0 comments on commit 27cfd34

Please sign in to comment.