Skip to content

Commit 433cc13

Browse files
committed
test: cover translatable nested rules and ANY two-group composition
Add unit tests for a rule carrying both conditions and a nested rule, and for an ANY rule with both groups, asserting the full translated SQL. These exercise the previously-uncovered nested-rule and two-group-AND paths in translate_rule. beep boop
1 parent bf7b01a commit 433cc13

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

tests/test_translator_unit.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,86 @@ def test_translate_segment__rule_with_no_conditions_or_nested_rules__matches_all
294294
assert translate_segment(seg, _ctx()) == "(TRUE)"
295295

296296

297+
def test_translate_segment__rule_with_conditions_and_nested_rule__ands_the_two_groups() -> None:
298+
# Given a rule carrying both a condition and a (translatable) nested rule
299+
seg: SegmentContext = {
300+
"key": "11",
301+
"name": "s",
302+
"rules": [
303+
{
304+
"type": "ALL",
305+
"conditions": [{"operator": "EQUAL", "property": "plan", "value": "growth"}],
306+
"rules": [
307+
{
308+
"type": "ALL",
309+
"conditions": [{"operator": "EQUAL", "property": "country", "value": "GB"}],
310+
}
311+
],
312+
}
313+
],
314+
}
315+
316+
# When translated
317+
sql = translate_segment(seg, _ctx())
318+
319+
# Then the condition group and the nested-rule group are AND-ed together
320+
# (mirroring the engine: matches_conditions AND matches_rules)
321+
assert sql == (
322+
"(((("
323+
"if(i.traits.`plan` IS NULL, NULL, toString(i.traits.`plan`)) IS NOT NULL"
324+
" AND ((toString(i.traits.`plan`) = 'growth') OR (i.traits.`plan`.:Bool = true))"
325+
"))) AND (((("
326+
"if(i.traits.`country` IS NULL, NULL, toString(i.traits.`country`)) IS NOT NULL"
327+
" AND ((toString(i.traits.`country`) = 'GB') OR (i.traits.`country`.:Bool = true))"
328+
")))))"
329+
)
330+
331+
332+
def test_translate_segment__any_rule_with_conditions_and_nested_rule__ors_within_ands_across() -> (
333+
None
334+
):
335+
# Given an ANY rule with two conditions and a nested rule. The engine
336+
# evaluates this as `any(conditions) AND any(rules)`, NOT a single OR over
337+
# the merged set — so the two conditions OR together but the groups AND.
338+
seg: SegmentContext = {
339+
"key": "12",
340+
"name": "s",
341+
"rules": [
342+
{
343+
"type": "ANY",
344+
"conditions": [
345+
{"operator": "EQUAL", "property": "plan", "value": "growth"},
346+
{"operator": "EQUAL", "property": "plan", "value": "scale"},
347+
],
348+
"rules": [
349+
{
350+
"type": "ALL",
351+
"conditions": [{"operator": "EQUAL", "property": "country", "value": "GB"}],
352+
}
353+
],
354+
}
355+
],
356+
}
357+
358+
# When translated
359+
sql = translate_segment(seg, _ctx())
360+
361+
# Then the two conditions OR together within their group, and that group is
362+
# AND-ed with the nested-rule group — `any(conditions) AND any(rules)`.
363+
assert sql == (
364+
"(((("
365+
"if(i.traits.`plan` IS NULL, NULL, toString(i.traits.`plan`)) IS NOT NULL"
366+
" AND ((toString(i.traits.`plan`) = 'growth') OR (i.traits.`plan`.:Bool = true))"
367+
")) OR (("
368+
"if(i.traits.`plan` IS NULL, NULL, toString(i.traits.`plan`)) IS NOT NULL"
369+
" AND ((toString(i.traits.`plan`) = 'scale') OR (i.traits.`plan`.:Bool = true))"
370+
"))) AND (((("
371+
"if(i.traits.`country` IS NULL, NULL, toString(i.traits.`country`)) IS NOT NULL"
372+
" AND ((toString(i.traits.`country`) = 'GB') OR (i.traits.`country`.:Bool = true))"
373+
")))))"
374+
)
375+
376+
297377
def test_translate_segment__trait_key_with_hyphens__quotes_subcolumn_path() -> None:
298378
# Given a trait key with a hyphen (illegal as an unquoted SQL identifier)
299379
seg: SegmentContext = {

0 commit comments

Comments
 (0)