Skip to content

Commit c6e4c01

Browse files
committed
Add fixture-based tests for a comprehensive schema
Expands the test suite with more complex, realistic schemas. This fixture-based test validates the parser against a comprehensive blog schema that uses a wider range of features, ensuring that the various parsing components integrate correctly.
1 parent 03c563d commit c6e4c01

File tree

2 files changed

+294
-0
lines changed

2 files changed

+294
-0
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Blog schema with models, enums, and relationships
2+
3+
generator client {
4+
provider = "prisma-client-js"
5+
}
6+
7+
datasource db {
8+
provider = "postgresql"
9+
url = env("DATABASE_URL")
10+
}
11+
12+
/// User model with authentication and profile information
13+
model User {
14+
id String @id @default(cuid())
15+
email String @unique
16+
username String @unique
17+
name String?
18+
bio String?
19+
avatar String?
20+
role UserRole @default(USER)
21+
createdAt DateTime @default(now())
22+
updatedAt DateTime @updatedAt
23+
24+
// Relations
25+
posts Post[]
26+
comments Comment[]
27+
likes Like[]
28+
29+
@@map("users")
30+
}
31+
32+
/// Blog post model
33+
model Post {
34+
id String @id @default(cuid())
35+
title String
36+
slug String @unique
37+
content String
38+
excerpt String?
39+
published Boolean @default(false)
40+
publishedAt DateTime?
41+
createdAt DateTime @default(now())
42+
updatedAt DateTime @updatedAt
43+
44+
// Relations
45+
authorId String
46+
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
47+
categories Category[]
48+
comments Comment[]
49+
likes Like[]
50+
51+
@@map("posts")
52+
}
53+
54+
/// Comment model for post discussions
55+
model Comment {
56+
id String @id @default(cuid())
57+
content String
58+
createdAt DateTime @default(now())
59+
updatedAt DateTime @updatedAt
60+
61+
// Relations
62+
postId String
63+
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
64+
authorId String
65+
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
66+
parentId String?
67+
parent Comment? @relation("CommentThread", fields: [parentId], references: [id])
68+
replies Comment[] @relation("CommentThread")
69+
70+
@@map("comments")
71+
}
72+
73+
/// Post category model
74+
model Category {
75+
id String @id @default(cuid())
76+
name String @unique
77+
slug String @unique
78+
description String?
79+
color String @default("#6B7280")
80+
81+
// Relations
82+
posts Post[]
83+
84+
@@map("categories")
85+
}
86+
87+
/// Like model for post engagement
88+
model Like {
89+
id String @id @default(cuid())
90+
userId String
91+
postId String
92+
93+
// Relations
94+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
95+
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
96+
97+
@@unique([userId, postId])
98+
@@map("likes")
99+
}
100+
101+
/// User role enumeration
102+
enum UserRole {
103+
ADMIN
104+
MODERATOR
105+
USER
106+
107+
@@map("user_roles")
108+
}
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
//! Fixture-based Integration Tests
2+
//!
3+
//! Tests using predefined schema fixtures to validate end-to-end parsing
4+
//! of realistic Prisma schemas.
5+
6+
use crate::scanner_parser::{assert_ast_structure, parse_schema_end_to_end};
7+
use std::fs;
8+
9+
fn load_fixture(path: &str) -> String {
10+
fs::read_to_string(format!("tests/fixtures/schemas/{path}"))
11+
.unwrap_or_else(|_| panic!("Failed to load fixture: {path}"))
12+
}
13+
14+
#[test]
15+
fn empty_fixture() {
16+
let schema_content = load_fixture("minimal/empty.prisma");
17+
let result = parse_schema_end_to_end(&schema_content);
18+
19+
assert!(
20+
result.schema.is_some(),
21+
"Empty fixture should parse successfully"
22+
);
23+
let schema = result.schema.unwrap();
24+
assert_eq!(
25+
schema.declarations.len(),
26+
0,
27+
"Empty schema should have no declarations"
28+
);
29+
}
30+
31+
#[test]
32+
fn single_model_fixture() {
33+
let schema_content = load_fixture("minimal/single_model.prisma");
34+
let result = parse_schema_end_to_end(&schema_content);
35+
36+
assert!(
37+
result.schema.is_some(),
38+
"Single model fixture should parse successfully"
39+
);
40+
let schema = result.schema.unwrap();
41+
assert_ast_structure(&schema, 1, 0, 0);
42+
43+
// Verify the model structure
44+
if let Some(prisma_rs::core::parser::ast::Declaration::Model(model)) =
45+
schema.declarations.first()
46+
{
47+
assert_eq!(model.name.text, "User");
48+
assert_eq!(model.members.len(), 3, "User model should have 3 fields");
49+
} else {
50+
panic!("Expected first declaration to be a model");
51+
}
52+
}
53+
54+
#[test]
55+
fn single_enum_fixture() {
56+
let schema_content = load_fixture("minimal/single_enum.prisma");
57+
let result = parse_schema_end_to_end(&schema_content);
58+
59+
assert!(
60+
result.schema.is_some(),
61+
"Single enum fixture should parse successfully"
62+
);
63+
let schema = result.schema.unwrap();
64+
assert_ast_structure(&schema, 0, 1, 0);
65+
66+
// Verify the enum structure
67+
if let Some(prisma_rs::core::parser::ast::Declaration::Enum(enum_decl)) =
68+
schema.declarations.first()
69+
{
70+
assert_eq!(enum_decl.name.text, "Status");
71+
assert_eq!(
72+
enum_decl.members.len(),
73+
3,
74+
"Status enum should have 3 values"
75+
);
76+
} else {
77+
panic!("Expected first declaration to be an enum");
78+
}
79+
}
80+
81+
#[test]
82+
fn comprehensive_blog_schema() {
83+
let schema_content = load_fixture("comprehensive/blog_schema.prisma");
84+
let result = parse_schema_end_to_end(&schema_content);
85+
86+
assert!(
87+
result.schema.is_some(),
88+
"Blog schema should parse successfully"
89+
);
90+
let schema = result.schema.unwrap();
91+
92+
println!(
93+
"Blog schema parsed {} declarations",
94+
schema.declarations.len()
95+
);
96+
println!("Diagnostics: {:?}", result.diagnostics);
97+
98+
// Count different declaration types
99+
let mut models = 0;
100+
let mut enums = 0;
101+
let mut datasources = 0;
102+
let mut generators = 0;
103+
104+
for declaration in &schema.declarations {
105+
match declaration {
106+
prisma_rs::core::parser::ast::Declaration::Model(_) => models += 1,
107+
prisma_rs::core::parser::ast::Declaration::Enum(_) => enums += 1,
108+
prisma_rs::core::parser::ast::Declaration::Datasource(_) => {
109+
datasources += 1;
110+
}
111+
prisma_rs::core::parser::ast::Declaration::Generator(_) => {
112+
generators += 1;
113+
}
114+
prisma_rs::core::parser::ast::Declaration::Type(_) => {}
115+
}
116+
}
117+
118+
// The blog schema should have multiple models and at least one enum
119+
assert!(
120+
models >= 3,
121+
"Blog schema should have at least 3 models, found: {models}"
122+
);
123+
assert!(
124+
enums >= 1,
125+
"Blog schema should have at least 1 enum, found: {enums}"
126+
);
127+
// Report what we found
128+
println!(
129+
"Found: {models} models, {enums} enums, {datasources} datasources, {generators} generators"
130+
);
131+
132+
// Note: datasource and generator parsing may not be fully implemented yet
133+
134+
// Performance check - complex schema should still parse reasonably quickly
135+
assert!(
136+
result.parse_time.as_millis() < 500,
137+
"Complex schema should parse under 500ms"
138+
);
139+
}
140+
141+
#[test]
142+
fn token_counts() {
143+
let fixtures = [
144+
("minimal/empty.prisma", 1, 10), // Should have at least EOF, maybe some comment tokens
145+
("minimal/single_model.prisma", 15, 50), // Should have reasonable token count
146+
("minimal/single_enum.prisma", 5, 15), // Should have reasonable token count
147+
];
148+
149+
for (fixture_path, min_tokens, max_tokens) in fixtures {
150+
let schema_content = load_fixture(fixture_path);
151+
let result = parse_schema_end_to_end(&schema_content);
152+
153+
assert!(
154+
result.token_count >= min_tokens
155+
&& result.token_count <= max_tokens,
156+
"Fixture {} should have between {} and {} tokens, found: {}",
157+
fixture_path,
158+
min_tokens,
159+
max_tokens,
160+
result.token_count
161+
);
162+
}
163+
}
164+
165+
#[test]
166+
fn parse_times_reasonable() {
167+
let fixtures = [
168+
"minimal/empty.prisma",
169+
"minimal/single_model.prisma",
170+
"minimal/single_enum.prisma",
171+
"comprehensive/blog_schema.prisma",
172+
];
173+
174+
for fixture_path in fixtures {
175+
let schema_content = load_fixture(fixture_path);
176+
let result = parse_schema_end_to_end(&schema_content);
177+
178+
// All fixtures should parse in under 100ms (very generous for small schemas)
179+
assert!(
180+
result.parse_time.as_millis() < 100,
181+
"Fixture {} took too long to parse: {}ms",
182+
fixture_path,
183+
result.parse_time.as_millis()
184+
);
185+
}
186+
}

0 commit comments

Comments
 (0)