Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: selectAll infinite recursion #948

Merged
merged 1 commit into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/templates/deno/api/example.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Policy, t, typegraph } from "jsr:@typegraph/[email protected].7";
import { Policy, t, typegraph } from "jsr:@typegraph/[email protected].9";
import { PythonRuntime } from "jsr:@typegraph/[email protected]/runtimes/python";
import { DenoRuntime } from "jsr:@typegraph/[email protected]/runtimes/deno";

Expand Down
3 changes: 1 addition & 2 deletions src/metagen-client-rs/src/selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,8 +393,7 @@ where
SelT: Selection + Into<CompositeSelection>,
{
fn all() -> Self {
let sel = SelT::all();
Self::Get(sel.into(), PhantomData)
Self::Skip
}
}
impl<ArgT, SelT, ATy> Selection for CompositeSelectArgs<ArgT, SelT, ATy>
Expand Down
21 changes: 16 additions & 5 deletions src/metagen/src/client_py/static/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ def selection_to_nodes(
parent_path: str,
) -> typing.List["SelectNode[typing.Any]"]:
out = []
flags = selection.get("_")
if flags is not None and not isinstance(flags, SelectionFlags):
sub_flags = selection.get("_")
if sub_flags is not None and not isinstance(sub_flags, SelectionFlags):
raise Exception(
f"selection field '_' should be of type SelectionFlags but found {type(flags)}"
f"selection field '_' should be of type SelectionFlags but found {type(sub_flags)}"
)
select_all = True if flags is not None and flags.select_all else False
select_all = True if sub_flags is not None and sub_flags.select_all else False
found_nodes = set(selection.keys())
for node_name, meta_fn in metas.items():
found_nodes.discard(node_name)
Expand Down Expand Up @@ -104,7 +104,7 @@ def selection_to_nodes(

# flags are recursive for any subnode that's not specified
if sub_selections is None:
sub_selections = {"_": flags}
sub_selections = {"_": sub_flags}

# selection types are always TypedDicts as well
if not isinstance(sub_selections, dict):
Expand All @@ -119,6 +119,17 @@ def selection_to_nodes(
raise Exception(
"unreachable: union/either NodeMetas can't have subnodes"
)

# skip non explicit composite selection when using select_all
sub_flags = sub_selections.get("_")

if (
isinstance(sub_flags, SelectionFlags)
and sub_flags.select_all
and instance_selection is None
):
continue

sub_nodes = selection_to_nodes(
typing.cast("SelectionErased", sub_selections),
meta.sub_nodes,
Expand Down
6 changes: 6 additions & 0 deletions src/metagen/src/client_ts/static/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ function _selectionToNodeSet(
"unreachable: union/either NodeMetas can't have subnodes",
);
}

// skip non explicit composite selection when using selectAll
if (subSelections?._ === "selectAll" && !instanceSelection) {
continue;
}

node.subNodes = _selectionToNodeSet(
// assume it's a Selection. If it's an argument
// object, mismatch between the node desc should hopefully
Expand Down
253 changes: 130 additions & 123 deletions tests/injection/random_injection_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,151 +17,158 @@ const cases = [
];

for (const testCase of cases) {
Meta.test({
name: testCase.testName,
only: false,
}, async (t) => {
const engine = await t.engine(testCase.typegraph);
Meta.test(
{
name: testCase.testName,
only: false,
},
async (t) => {
const engine = await t.engine(testCase.typegraph);

await t.should("generate random values", async () => {
await gql`
query {
randomUser {
id
ean
name
age
married
birthday
phone
gender
firstname
lastname
friends
occupation
street
city
postcode
country
uri
hostname
await t.should("generate random values", async () => {
await gql`
query {
randomUser {
id
ean
name
age
married
birthday
phone
gender
firstname
lastname
friends
occupation
street
city
postcode
country
uri
hostname
}
}
}
`
.expectData({
randomUser: {
id: "1069ace0-cdb1-5c1f-8193-81f53d29da35",
ean: "0497901391205",
name: "Landon Glover",
age: 38,
married: true,
birthday: "2124-06-22T22:00:07.302Z",
phone: "(587) 901-3720",
gender: "Male",
firstname: "Landon",
lastname: "Mengoni",
friends: ["Hettie", "Mary", "Lydia", "Ethel", "Jennie"],
occupation: "Health Care Manager",
street: "837 Wubju Drive",
city: "Urbahfec",
postcode: "IM9 9AD",
country: "Indonesia",
uri: "http://wubju.bs/ma",
hostname: "wubju.bs",
},
})
.on(engine);
});
});
`
.expectData({
randomUser: {
id: "1069ace0-cdb1-5c1f-8193-81f53d29da35",
ean: "0497901391205",
name: "Landon Glover",
age: 38,
married: true,
birthday: "2125-06-22T22:00:07.302Z",
phone: "(587) 901-3720",
gender: "Male",
firstname: "Landon",
lastname: "Mengoni",
friends: ["Hettie", "Mary", "Lydia", "Ethel", "Jennie"],
occupation: "Health Care Manager",
street: "837 Wubju Drive",
city: "Urbahfec",
postcode: "IM9 9AD",
country: "Indonesia",
uri: "http://wubju.bs/ma",
hostname: "wubju.bs",
},
})
.on(engine);
});
},
);
}

Meta.test("random injection on unions", async (t) => {
const engine = await t.engine("injection/random_injection.py");

await t.should("work on random lists", async () => {
await gql`
query {
randomList {
names
}
}
`.expectData({
randomList: {
names: [
"Hettie Huff",
"Ada Mills",
"Ethel Marshall",
"Emily Gonzales",
"Lottie Barber",
],
},
}).on(engine);
query {
randomList {
names
}
}
`
.expectData({
randomList: {
names: [
"Hettie Huff",
"Ada Mills",
"Ethel Marshall",
"Emily Gonzales",
"Lottie Barber",
],
},
})
.on(engine);
});

await t.should(
"generate random values for enums, either and union variants",
async () => {
await gql`
query {
testEnumStr {
educationLevel
},
testEnumInt {
bits
},
testEnumFloat {
cents
},
testEither {
toy {
... on Toygun {
color
}
... on Rubix {
name,
size
}
query {
testEnumStr {
educationLevel
}
},
testUnion {
field {
... on Rgb {
R
G
B
testEnumInt {
bits
}
testEnumFloat {
cents
}
testEither {
toy {
... on Toygun {
color
}
... on Rubix {
name
size
}
}
... on Vec {
x
y
z
}
testUnion {
field {
... on Rgb {
R
G
B
}
... on Vec {
x
y
z
}
}
}
}
}
`.expectData({
testEnumStr: {
educationLevel: "secondary",
},
testEnumInt: {
bits: 0,
},
testEnumFloat: {
cents: 0.5,
},
testEither: {
toy: {
name: "1*ajw]krgDnCzXD*N!Fx",
size: 3336617896968192,
`
.expectData({
testEnumStr: {
educationLevel: "secondary",
},
},
testUnion: {
field: {
B: 779226068287.488,
G: 396901315143.2704,
R: 895648526657.1263,
testEnumInt: {
bits: 0,
},
},
}).on(engine);
testEnumFloat: {
cents: 0.5,
},
testEither: {
toy: {
name: "1*ajw]krgDnCzXD*N!Fx",
size: 3336617896968192,
},
},
testUnion: {
field: {
B: 779226068287.488,
G: 396901315143.2704,
R: 895648526657.1263,
},
},
})
.on(engine);
},
);
});
19 changes: 19 additions & 0 deletions tests/metagen/metagen_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,24 @@ Meta.test(
compositeNoArgs: postSchema,
compositeArgs: postSchema,
});
const expectedSchemaC = zod.object({
scalarOnly: zod.object({ scalar: zod.number() }),
withStruct: zod.object({
scalar: zod.number(),
composite: zod.object({ value: zod.number() }),
}),
withStructNested: zod.object({
scalar: zod.number(),
composite: zod.object({
value: zod.number(),
nested: zod.object({ inner: zod.number() }),
}),
}),
withList: zod.object({
scalar: zod.number(),
list: zod.array(zod.object({ value: zod.number() })),
}),
});
const expectedSchema = zod.tuple([
expectedSchemaQ,
expectedSchemaQ,
Expand All @@ -604,6 +622,7 @@ Meta.test(
compositeUnion2: zod.object({}),
mixedUnion: zod.string(),
}),
expectedSchemaC,
]);
const cases = [
{
Expand Down
2 changes: 1 addition & 1 deletion tests/metagen/typegraphs/identities/rs/fdk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl Router {
}

pub fn init(&self, args: InitArgs) -> Result<InitResponse, InitError> {
static MT_VERSION: &str = "0.5.0-rc.8";
static MT_VERSION: &str = "0.5.0-rc.9";
luckasRanarison marked this conversation as resolved.
Show resolved Hide resolved
if args.metatype_version != MT_VERSION {
return Err(InitError::VersionMismatch(MT_VERSION.into()));
}
Expand Down
Loading
Loading