Skip to content

Commit

Permalink
test: alias tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Yohe-Am committed Aug 7, 2024
1 parent 8ff17ec commit 278bc09
Show file tree
Hide file tree
Showing 24 changed files with 1,288 additions and 900 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ repos:
- id: deno-fmt
name: Deno format
language: system
entry: bash -c 'cd typegate && deno fmt --ignore=native,src/typegraphs,tmp,tests/e2e/nextjs && cd ../dev && deno fmt && cd ../typegraph/deno && deno fmt --ignore=node_modules,dist'
entry: bash -c 'cd typegate && deno fmt --ignore=native,src/typegraphs,tmp,tests/e2e/nextjs && cd ../dev && deno fmt && cd ../typegraph/deno && deno fmt --ignore=node_modules,dist && cd ../../libs/metagen/src && deno fmt'
pass_filenames: false
types:
- ts
files: ^(typegate|dev|typegraph/deno)/
- id: deno-lint
name: Deno lint
language: system
entry: bash -c 'cd typegate && deno lint --rules-exclude=no-explicit-any --ignore=native,tmp,tests/e2e/nextjs && cd ../dev && deno lint'
entry: bash -c 'cd typegate && deno lint --rules-exclude=no-explicit-any --ignore=native,tmp,tests/e2e/nextjs && cd ../dev && deno lint && cd ../libs/metagen/src/ && deno lint'
pass_filenames: false
types:
- ts
Expand Down
28 changes: 17 additions & 11 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,24 @@
"website/.docusaurus": true,
"website/node_modules": true
},
"deno.enablePaths": [
"typegate",
"dev",
"examples/templates/deno",
"examples/typegraphs",
"typegraph/deno/dev",
"typegraph/deno/sdk",
"libs/metagen",
"ghjk.ts",
".ghjk"
"deno.disablePaths": [
"meta-lsp",
"typegraph/node",
"examples/templates/node",
"website"
],
"deno.importMap": "typegate/import_map.json",
// "deno.enablePaths": [
// "typegate",
// "dev",
// "examples/templates/deno",
// "examples/typegraphs",
// "typegraph/deno/dev",
// "typegraph/deno/sdk",
// "libs/metagen",
// "ghjk.ts",
// ".ghjk"
// ],
// "deno.config": "typegate/deno.jsonc",
"deno.unstable": true,
"typescript.suggest.completeFunctionCalls": true,
"typescript.inlayHints.variableTypes.enabled": true,
Expand Down
120 changes: 11 additions & 109 deletions libs/metagen/src/client_py/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: MPL-2.0

mod node_metas;

mod selections;
mod types;
mod utils;
Expand All @@ -13,6 +14,7 @@ use common::typegraph::EffectType;
use crate::interlude::*;
use crate::*;

use crate::shared::client::*;
use crate::shared::types::NameMemo;
use crate::shared::types::TypeRenderer;
use crate::utils::GenDestBuf;
Expand Down Expand Up @@ -166,17 +168,20 @@ class QueryGraph(QueryGraphBase):
(Some(arg_ty), None) => format!("self, args: {arg_ty}"),
// not all functions have args (empty struct arg)
(None, Some(select_ty)) => format!("self, select: {select_ty}"),
(None, None) => "".into(),
(None, None) => "self".into(),
};

let args_selection = match (fun.in_id, fun.select_ty) {
(Some(_), Some(_)) => "(args, select)",
(Some(_), None) => "args",
(None, Some(_)) => "select",
(None, None) => "true",
(None, None) => "True",
};

let meta_method = node_metas.get(&fun.id).unwrap();
let meta_method = node_metas
.get(&fun.id)
.map(|str| &str[..])
.unwrap_or_else(|| "scalar");

let node_type = match fun.effect {
EffectType::Read => "QueryNode",
Expand All @@ -189,10 +194,10 @@ class QueryGraph(QueryGraphBase):
def {method_name}({args_row}) -> {node_type}[{out_ty_name}]:
node = selection_to_nodes(
{{"{node_name}": {args_selection}}},
{{"{node_name}": NodeDescs.{meta_method}()}},
{{"{node_name}": NodeDescs.{meta_method}}},
"$q"
)[0]
return {node_type}(name=node.name, args=node.args, sub_nodes=node.sub_nodes)
return {node_type}(node.node_name, node.instance_name, node.args, node.sub_nodes)
"#
)?;
}
Expand All @@ -201,109 +206,6 @@ class QueryGraph(QueryGraphBase):
Ok(client_py.buf)
}

struct RootFn {
id: u32,
name: String,
in_id: Option<u32>,
out_id: u32,
effect: EffectType,
select_ty: Option<u32>,
}

struct RenderManifest {
data_types: HashSet<u32>,
// arg_types: HashSet<u32>,
// arg_types: HashSet<u32>,
selections: HashSet<u32>,
root_fns: Vec<RootFn>,
}

/// Collect upfront all the items we need to render
fn get_manifest(tg: &Typegraph) -> Result<RenderManifest> {
let mut root_fns = vec![];
let mut selections = HashSet::new();
let mut data_types = HashSet::new();
// let mut arg_types = HashSet::new();

let (_root_base, root) = tg.root().map_err(anyhow_to_eyre!())?;
for (key, &func_id) in &root.properties {
let TypeNode::Function { data, .. } = &tg.types[func_id as usize] else {
bail!(
"invalid typegraph: node of type {} instead of a root function",
tg.types[func_id as usize].type_name()
);
};
let mat = &tg.materializers[data.materializer as usize];

fn is_composite(types: &[TypeNode], id: u32) -> bool {
match &types[id as usize] {
TypeNode::Function { .. } => unreachable!(),
TypeNode::Any { .. } => unimplemented!("unexpected Any type as output"),
TypeNode::Boolean { .. }
| TypeNode::Float { .. }
| TypeNode::Integer { .. }
| TypeNode::String { .. }
| TypeNode::File { .. } => false,
TypeNode::Object { .. } => true,
TypeNode::Optional { data, .. } => is_composite(types, data.item),
TypeNode::List { data, .. } => is_composite(types, data.items),
TypeNode::Union { data, .. } => {
data.any_of.iter().any(|&id| is_composite(types, id))
}
TypeNode::Either { data, .. } => {
data.one_of.iter().any(|&id| is_composite(types, id))
}
}
}

data_types.insert(data.output);

let in_id = if matches!(
&tg.types[data.input as usize],
TypeNode::Object { data, .. } if !data.properties.is_empty()
) {
data_types.insert(data.input);
// arg_types.insert(data.input);
Some(data.input)
} else {
None
};
root_fns.push(RootFn {
id: func_id,
name: key.clone(),
effect: mat.effect.effect.unwrap_or(EffectType::Read),
// empty struct arguments don't need arguments
in_id,
out_id: data.output,
// scalar return types don't need selections
select_ty: if is_composite(&tg.types, data.output) {
selections.insert(func_id);
Some(data.output)
} else {
None
},
});
}

for node in &tg.types {
if let TypeNode::Function { data, .. } = node {
if matches!(
&tg.types[data.input as usize],
TypeNode::Object { data, .. } if !data.properties.is_empty()
) {
data_types.insert(data.input);
}
}
}

Ok(RenderManifest {
root_fns,
selections,
data_types,
// arg_types,
})
}

/// Render the common sections like the transports
fn render_static(dest: &mut GenDestBuf) -> core::fmt::Result {
let client_py = include_str!("static/client.py");
Expand Down Expand Up @@ -360,7 +262,7 @@ fn render_node_metas(
name_mapper.nodes.clone(),
Rc::new(node_metas::PyNodeMetasRenderer { name_mapper }),
);
for &id in &manifest.selections {
for &id in &manifest.node_metas {
_ = renderer.render(id)?;
}
let (methods, memo) = renderer.finalize();
Expand Down
2 changes: 1 addition & 1 deletion libs/metagen/src/client_py/node_metas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl PyNodeMetasRenderer {
write!(
dest,
r#"
"{key}": NodeDescs.{node_ref}(),"#
"{key}": NodeDescs.{node_ref},"#
)?;
}
write!(
Expand Down
74 changes: 16 additions & 58 deletions libs/metagen/src/client_py/selections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,13 @@ use std::fmt::Write;

use common::typegraph::*;

use super::utils::normalize_type_title;
use crate::{interlude::*, shared::types::*};
use super::utils::*;
use crate::{interlude::*, shared::client::*, shared::types::*};

pub struct PyNodeSelectionsRenderer {
pub arg_ty_names: Rc<NameMemo>,
}

enum SelectionTy {
Scalar,
ScalarArgs { arg_ty: Rc<str> },
CompositeArgs { arg_ty: Rc<str>, select_ty: Rc<str> },
Composite { select_ty: Rc<str> },
}

impl PyNodeSelectionsRenderer {
/// `props` is a map of prop_name -> (SelectionType, ArgumentType)
fn render_for_object(
Expand All @@ -27,64 +20,29 @@ impl PyNodeSelectionsRenderer {
ty_name: &str,
props: IndexMap<String, SelectionTy>,
) -> std::fmt::Result {
writeln!(dest, "class {ty_name}(Selection, total=False):")?;
writeln!(dest, r#"{ty_name} = typing.TypedDict("{ty_name}", {{"#)?;
writeln!(dest, r#" "_": SelectionFlags,"#)?;
for (name, select_ty) in props {
use SelectionTy::*;
match select_ty {
Scalar => writeln!(dest, " {name}: ScalarSelectNoArgs")?,
ScalarArgs { arg_ty } => writeln!(dest, " {name}: ScalarSelectArgs[{arg_ty}]")?,
Composite { select_ty } => {
writeln!(dest, " {name}: CompositeSelectNoArgs[{select_ty}]")?
Scalar => writeln!(dest, r#" "{name}": ScalarSelectNoArgs,"#)?,
ScalarArgs { arg_ty } => {
writeln!(dest, r#" "{name}": ScalarSelectArgs["{arg_ty}"],"#)?
}
Composite { select_ty } => writeln!(
dest,
r#" "{name}": CompositeSelectNoArgs["{select_ty}"],"#
)?,
CompositeArgs { arg_ty, select_ty } => writeln!(
dest,
" {name}: CompositeSelectArgs[{arg_ty}, {select_ty}]"
r#" "{name}": CompositeSelectArgs["{arg_ty}", "{select_ty}"],"#
)?,
};
}
writeln!(dest, "}}, total=False)")?;
writeln!(dest)?;
Ok(())
}

fn selection_for_field(
&self,
ty: u32,
renderer: &mut TypeRenderer,
cursor: &mut VisitCursor,
) -> Result<SelectionTy> {
Ok(match renderer.nodes[ty as usize].deref() {
TypeNode::Boolean { .. }
| TypeNode::Float { .. }
| TypeNode::Integer { .. }
| TypeNode::String { .. }
| TypeNode::File { .. } => SelectionTy::Scalar,
TypeNode::Function { data, .. } => {
let arg_ty = self.arg_ty_names.get(&data.input).unwrap().clone();
match self.selection_for_field(data.output, renderer, cursor)? {
SelectionTy::Scalar => SelectionTy::ScalarArgs { arg_ty },
SelectionTy::Composite { select_ty } => {
SelectionTy::CompositeArgs { select_ty, arg_ty }
}
SelectionTy::CompositeArgs { .. } | SelectionTy::ScalarArgs { .. } => {
unreachable!("function can not return a function")
}
}
}
TypeNode::Optional {
data: OptionalTypeData { item, .. },
..
}
| TypeNode::List {
data: ListTypeData { items: item, .. },
..
} => self.selection_for_field(*item, renderer, cursor)?,
TypeNode::Object { .. } => SelectionTy::Composite {
select_ty: renderer.render_subgraph(ty, cursor)?.0.unwrap(),
},
TypeNode::Union { .. } | TypeNode::Either { .. } => todo!("unions are wip"),
TypeNode::Any { .. } => unimplemented!("Any type support not implemented"),
})
}
}

impl RenderType for PyNodeSelectionsRenderer {
Expand All @@ -96,7 +54,7 @@ impl RenderType for PyNodeSelectionsRenderer {
| TypeNode::Float { .. }
| TypeNode::Integer { .. }
| TypeNode::String { .. }
| TypeNode::File { .. } => unreachable!("scalars don't get to have selections"),
| TypeNode::File { .. } => "scalar".into(), // unreachable!("scalars don't get to have selections"),
TypeNode::Any { .. } => unimplemented!("Any type support not implemented"),
TypeNode::Optional { data: OptionalTypeData { item, .. }, .. }
| TypeNode::List { data: ListTypeData { items: item, .. }, .. }
Expand All @@ -110,8 +68,8 @@ impl RenderType for PyNodeSelectionsRenderer {
.map(|(name, &dep_id)| {
eyre::Ok(
(
name.clone(),
self.selection_for_field(dep_id, renderer, cursor)?
normalize_struct_prop_name(name),
selection_for_field(dep_id, &self.arg_ty_names, renderer, cursor)?
)
)
})
Expand Down
Loading

0 comments on commit 278bc09

Please sign in to comment.