Skip to content

Commit 70728cb

Browse files
committed
in work
1 parent 3a50ee0 commit 70728cb

File tree

3 files changed

+288
-0
lines changed

3 files changed

+288
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
pub mod cube_bridge;
2+
pub mod schemas;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub mod visitors_schema;
2+
3+
pub use visitors_schema::create_visitors_schema;
Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
use crate::test_fixtures::cube_bridge::{
2+
MockDimensionDefinition, MockMeasureDefinition, MockSchema, MockSchemaBuilder,
3+
MockSegmentDefinition,
4+
};
5+
6+
/// Creates a schema for visitors and visitor_checkins cubes
7+
///
8+
/// This schema demonstrates:
9+
/// - Basic dimensions with different types
10+
/// - Geo dimensions with latitude/longitude
11+
/// - Sub-query dimensions that reference other cubes
12+
/// - Dimensions with complex SQL including special characters (question marks)
13+
/// - Time dimensions
14+
pub fn create_visitors_schema() -> MockSchema {
15+
MockSchemaBuilder::new()
16+
// visitor_checkins cube - referenced by visitors cube
17+
.add_cube("visitor_checkins")
18+
.add_dimension(
19+
"id",
20+
MockDimensionDefinition::builder()
21+
.dimension_type("number".to_string())
22+
.sql("id".to_string())
23+
.build(),
24+
)
25+
.add_dimension(
26+
"visitor_id",
27+
MockDimensionDefinition::builder()
28+
.dimension_type("number".to_string())
29+
.sql("visitor_id".to_string())
30+
.build(),
31+
)
32+
.add_dimension(
33+
"minDate",
34+
MockDimensionDefinition::builder()
35+
.dimension_type("time".to_string())
36+
.sql("MIN(created_at)".to_string())
37+
.build(),
38+
)
39+
.add_dimension(
40+
"minDate1",
41+
MockDimensionDefinition::builder()
42+
.dimension_type("time".to_string())
43+
.sql("MIN(created_at) + INTERVAL '1 day'".to_string())
44+
.build(),
45+
)
46+
.add_measure(
47+
"count",
48+
MockMeasureDefinition::builder()
49+
.measure_type("count".to_string())
50+
.sql("COUNT(*)".to_string())
51+
.build(),
52+
)
53+
.finish_cube()
54+
// visitors cube - main cube with various dimension types
55+
.add_cube("visitors")
56+
.add_dimension(
57+
"id",
58+
MockDimensionDefinition::builder()
59+
.dimension_type("number".to_string())
60+
.sql("id".to_string())
61+
.build(),
62+
)
63+
.add_dimension(
64+
"visitor_id",
65+
MockDimensionDefinition::builder()
66+
.dimension_type("number".to_string())
67+
.sql("visitor_id".to_string())
68+
.build(),
69+
)
70+
.add_dimension(
71+
"source",
72+
MockDimensionDefinition::builder()
73+
.dimension_type("string".to_string())
74+
.sql("source".to_string())
75+
.build(),
76+
)
77+
.add_dimension(
78+
"created_at",
79+
MockDimensionDefinition::builder()
80+
.dimension_type("time".to_string())
81+
.sql("created_at".to_string())
82+
.build(),
83+
)
84+
// Sub-query dimension referencing visitor_checkins.minDate
85+
.add_dimension(
86+
"minVisitorCheckinDate",
87+
MockDimensionDefinition::builder()
88+
.dimension_type("time".to_string())
89+
.sql("{visitor_checkins.minDate}".to_string())
90+
.sub_query(Some(true))
91+
.build(),
92+
)
93+
// Sub-query dimension referencing visitor_checkins.minDate1
94+
.add_dimension(
95+
"minVisitorCheckinDate1",
96+
MockDimensionDefinition::builder()
97+
.dimension_type("time".to_string())
98+
.sql("{visitor_checkins.minDate1}".to_string())
99+
.sub_query(Some(true))
100+
.build(),
101+
)
102+
// Geo dimension with latitude and longitude
103+
.add_dimension(
104+
"location",
105+
MockDimensionDefinition::builder()
106+
.dimension_type("geo".to_string())
107+
.latitude("latitude".to_string())
108+
.longitude("longitude".to_string())
109+
.build(),
110+
)
111+
// Dimension with SQL containing question marks (special characters)
112+
.add_dimension(
113+
"questionMark",
114+
MockDimensionDefinition::builder()
115+
.dimension_type("string".to_string())
116+
.sql(
117+
"replace('some string question string ? ?? ???', 'string', 'with some ? ?? ???')"
118+
.to_string(),
119+
)
120+
.build(),
121+
)
122+
.add_measure(
123+
"count",
124+
MockMeasureDefinition::builder()
125+
.measure_type("count".to_string())
126+
.sql("COUNT(*)".to_string())
127+
.build(),
128+
)
129+
.add_measure(
130+
"total_revenue",
131+
MockMeasureDefinition::builder()
132+
.measure_type("sum".to_string())
133+
.sql("revenue".to_string())
134+
.build(),
135+
)
136+
.add_segment(
137+
"google",
138+
MockSegmentDefinition::builder()
139+
.sql("{CUBE.source} = 'google'".to_string())
140+
.build(),
141+
)
142+
.finish_cube()
143+
.build()
144+
}
145+
146+
#[cfg(test)]
147+
mod tests {
148+
use super::*;
149+
use crate::cube_bridge::dimension_definition::DimensionDefinition;
150+
use crate::cube_bridge::measure_definition::MeasureDefinition;
151+
use crate::cube_bridge::segment_definition::SegmentDefinition;
152+
153+
#[test]
154+
fn test_schema_has_both_cubes() {
155+
let schema = create_visitors_schema();
156+
157+
assert!(schema.get_cube("visitors").is_some());
158+
assert!(schema.get_cube("visitor_checkins").is_some());
159+
}
160+
161+
#[test]
162+
fn test_visitors_dimensions() {
163+
let schema = create_visitors_schema();
164+
165+
// Basic dimensions
166+
assert!(schema.get_dimension("visitors", "visitor_id").is_some());
167+
assert!(schema.get_dimension("visitors", "source").is_some());
168+
assert!(schema.get_dimension("visitors", "created_at").is_some());
169+
170+
// Sub-query dimensions
171+
let min_checkin = schema
172+
.get_dimension("visitors", "minVisitorCheckinDate")
173+
.unwrap();
174+
assert_eq!(min_checkin.static_data().dimension_type, "time");
175+
assert_eq!(min_checkin.static_data().sub_query, Some(true));
176+
177+
let min_checkin1 = schema
178+
.get_dimension("visitors", "minVisitorCheckinDate1")
179+
.unwrap();
180+
assert_eq!(min_checkin1.static_data().dimension_type, "time");
181+
assert_eq!(min_checkin1.static_data().sub_query, Some(true));
182+
183+
// Geo dimension
184+
let location = schema.get_dimension("visitors", "location").unwrap();
185+
assert_eq!(location.static_data().dimension_type, "geo");
186+
assert!(location.has_latitude().unwrap());
187+
assert!(location.has_longitude().unwrap());
188+
189+
// Dimension with special characters
190+
let question_mark = schema.get_dimension("visitors", "questionMark").unwrap();
191+
assert_eq!(question_mark.static_data().dimension_type, "string");
192+
let sql = question_mark.sql().unwrap().unwrap();
193+
// Verify SQL contains question marks
194+
use crate::cube_bridge::member_sql::MemberSql;
195+
use crate::test_fixtures::cube_bridge::{MockSecurityContext, MockSqlUtils};
196+
use std::rc::Rc;
197+
let (template, _args) = sql
198+
.compile_template_sql(Rc::new(MockSqlUtils), Rc::new(MockSecurityContext))
199+
.unwrap();
200+
match template {
201+
crate::cube_bridge::member_sql::SqlTemplate::String(s) => {
202+
assert!(s.contains("?"));
203+
}
204+
_ => panic!("Expected String template"),
205+
}
206+
}
207+
208+
#[test]
209+
fn test_visitor_checkins_dimensions() {
210+
let schema = create_visitors_schema();
211+
212+
assert!(schema
213+
.get_dimension("visitor_checkins", "visitor_id")
214+
.is_some());
215+
216+
let min_date = schema
217+
.get_dimension("visitor_checkins", "minDate")
218+
.unwrap();
219+
assert_eq!(min_date.static_data().dimension_type, "time");
220+
221+
let min_date1 = schema
222+
.get_dimension("visitor_checkins", "minDate1")
223+
.unwrap();
224+
assert_eq!(min_date1.static_data().dimension_type, "time");
225+
}
226+
227+
#[test]
228+
fn test_visitors_measures() {
229+
let schema = create_visitors_schema();
230+
231+
let count = schema.get_measure("visitors", "count").unwrap();
232+
assert_eq!(count.static_data().measure_type, "count");
233+
234+
let revenue = schema.get_measure("visitors", "total_revenue").unwrap();
235+
assert_eq!(revenue.static_data().measure_type, "sum");
236+
}
237+
238+
#[test]
239+
fn test_visitors_segments() {
240+
let schema = create_visitors_schema();
241+
242+
let google_segment = schema.get_segment("visitors", "google").unwrap();
243+
let sql = google_segment.sql().unwrap();
244+
245+
use crate::cube_bridge::member_sql::MemberSql;
246+
assert_eq!(sql.args_names(), &vec!["CUBE"]);
247+
}
248+
249+
#[test]
250+
fn test_subquery_dimension_references() {
251+
let schema = create_visitors_schema();
252+
253+
let min_checkin = schema
254+
.get_dimension("visitors", "minVisitorCheckinDate")
255+
.unwrap();
256+
let sql = min_checkin.sql().unwrap().unwrap();
257+
258+
use crate::cube_bridge::member_sql::MemberSql;
259+
// Should reference visitor_checkins.minDate
260+
assert_eq!(sql.args_names(), &vec!["visitor_checkins"]);
261+
}
262+
263+
#[test]
264+
fn test_geo_dimension_structure() {
265+
use crate::cube_bridge::geo_item::GeoItem;
266+
use crate::cube_bridge::member_sql::MemberSql;
267+
268+
let schema = create_visitors_schema();
269+
270+
let location = schema.get_dimension("visitors", "location").unwrap();
271+
272+
assert_eq!(location.static_data().dimension_type, "geo");
273+
274+
// Test using trait methods
275+
let latitude = location.latitude().unwrap().unwrap();
276+
let lat_sql = latitude.sql().unwrap();
277+
// Verify the SQL is correct - it should have no template parameters
278+
assert_eq!(lat_sql.args_names().len(), 0);
279+
280+
let longitude = location.longitude().unwrap().unwrap();
281+
let lon_sql = longitude.sql().unwrap();
282+
assert_eq!(lon_sql.args_names().len(), 0);
283+
}
284+
}

0 commit comments

Comments
 (0)