def test__templater_jinja_error_catatrophic(): """Test error handling in the jinja templater.""" t = JinjaTemplater(override_context=dict(blah=7)) instr = JINJA_STRING outstr, vs = t.process(in_str=instr, config=FluffConfig()) assert not outstr assert len(vs) > 0
def test__templater_jinja_slice_file(raw_file, override_context, result, caplog): """Test slice_file.""" templater = JinjaTemplater(override_context=override_context) env, live_context, make_template = templater.template_builder( config=FluffConfig.from_path( "test/fixtures/templater/jinja_slice_template_macros")) templated_file = make_template(raw_file).render() with caplog.at_level(logging.DEBUG, logger="sqlfluff.templater"): _, resp, _ = templater.slice_file(raw_file, templated_file, make_template=make_template) # Check contiguous on the TEMPLATED VERSION print(resp) prev_slice = None for elem in resp: print(elem) if prev_slice: assert elem[2].start == prev_slice.stop prev_slice = elem[2] # Check that all literal segments have a raw slice for elem in resp: if elem[0] == "literal": assert elem[1] is not None # check result actual = [( templated_file_slice.slice_type, templated_file_slice.source_slice, templated_file_slice.templated_slice, ) for templated_file_slice in resp] assert actual == result
def test__templater_jinja(instr, expected_outstr): """Test jinja templating and the treatment of whitespace.""" t = JinjaTemplater(override_context=dict(blah="foo", condition="a < 10")) outstr, _ = t.process( in_str=instr, fname="test", config=FluffConfig(overrides={"dialect": "ansi"}) ) assert str(outstr) == expected_outstr
def test_templater_set_block_handling(): """Test handling of literals in {% set %} blocks. Specifically, verify they are not modified in the alternate template. """ def run_query(sql): # Prior to the bug fix, this assertion failed. This was bad because, # inside JinjaTracer, dbt templates similar to the one in this test # would call the database with funky SQL (including weird strings it # uses internally like: 00000000000000000000000000000002. assert sql == "\n\nselect 1 from foobarfoobarfoobarfoobar_dev\n\n" return sql t = JinjaTemplater(override_context=dict(run_query=run_query)) instr = """{% set my_query1 %} select 1 from foobarfoobarfoobarfoobar_{{ "dev" }} {% endset %} {% set my_query2 %} {{ my_query1 }} {% endset %} {{ run_query(my_query2) }} """ outstr, vs = t.process( in_str=instr, fname="test", config=FluffConfig(overrides={"dialect": "ansi"}) ) assert str(outstr) == "\n\n\n\n\nselect 1 from foobarfoobarfoobarfoobar_dev\n\n\n" assert len(vs) == 0
def test__templater_jinja_large_file_check(): """Test large file skipping. The check is seperately called on each .process() method so it makes sense to test a few templaters. """ # First check we can process the file normally without specific config. # i.e. check the defaults work and the default is high. JinjaTemplater().process( in_str="SELECT 1", fname="<string>", config=FluffConfig(overrides={"dialect": "ansi"}), ) # Second check setting the value low disables the check JinjaTemplater().process( in_str="SELECT 1", fname="<string>", config=FluffConfig( overrides={"dialect": "ansi", "large_file_skip_char_limit": 0} ), ) # Finally check we raise a skip exception when config is set low. with pytest.raises(SQLFluffSkipFile) as excinfo: JinjaTemplater().process( in_str="SELECT 1", fname="<string>", config=FluffConfig( overrides={"dialect": "ansi", "large_file_skip_char_limit": 2}, ), ) assert "Length of file" in str(excinfo.value)
def test__templater_jinja_error_variable(): """Test missing variable error handling in the jinja templater.""" t = JinjaTemplater(override_context=dict(blah="foo")) instr = JINJA_STRING outstr, vs = t.process(in_str=instr, config=FluffConfig()) assert str(outstr) == "SELECT * FROM f, o, o WHERE \n\n" # Check we have violations. assert len(vs) > 0 # Check one of them is a templating error on line 1 assert any(v.rule_code() == "TMP" and v.line_no() == 1 for v in vs)
def test__templater_jinja_error_syntax(): """Test syntax problems in the jinja templater.""" t = JinjaTemplater() instr = "SELECT {{foo} FROM jinja_error\n" outstr, vs = t.process(in_str=instr, config=FluffConfig()) # Check we just skip templating. assert str(outstr) == instr # Check we have violations. assert len(vs) > 0 # Check one of them is a templating error on line 1 assert any(v.rule_code() == "TMP" and v.line_no() == 1 for v in vs)
def test__templater_jinja_dynamic_variable_no_violations(): """Test no templater violation for variable defined within template.""" t = JinjaTemplater(override_context=dict(blah="foo")) instr = """{% if True %} {% set some_var %}1{% endset %} SELECT {{some_var}} {% endif %} """ outstr, vs = t.process( in_str=instr, fname="test", config=FluffConfig(overrides={"dialect": "ansi"}) ) assert str(outstr) == "\n \n SELECT 1\n\n" # Check we have no violations. assert len(vs) == 0
def test__templater_jinja_slice_template(test, result): """Test _slice_template.""" templater = JinjaTemplater() env, live_context, make_template = templater.template_builder() tracer = JinjaTracer(test, env, make_template) resp = list(tracer._slice_template()) # check contiguous (unless there's a comment in it) if "{#" not in test: assert "".join(elem.raw for elem in resp) == test # check indices idx = 0 for raw_slice in resp: assert raw_slice.source_idx == idx idx += len(raw_slice.raw) # Check total result assert [(raw_slice.raw, raw_slice.slice_type, raw_slice.source_idx) for raw_slice in resp] == result
def test__templater_jinja_error_macro_path_does_not_exist(): """Tests that an error is raised if macro path doesn't exist.""" with pytest.raises(ValueError) as e: JinjaTemplater().template_builder( config=FluffConfig.from_path( "test/fixtures/templater/jinja_macro_path_does_not_exist" ) ) assert str(e.value).startswith("Path does not exist")
def test__templater_jinja_slice_template(test, result): """Test _slice_template.""" resp = list(JinjaTemplater._slice_template(test)) # check contigious (unless there's a comment in it) if "{#" not in test: assert "".join(elem[0] for elem in resp) == test # check indices idx = 0 for literal, _, pos in resp: assert pos == idx idx += len(literal) # Check total result assert resp == result
def test__templater_jinja_slice_file(raw_file, templated_file, result, caplog): """Test slice_file.""" with caplog.at_level(logging.DEBUG, logger="sqlfluff.templater"): _, resp = JinjaTemplater.slice_file( raw_file, templated_file, ) # Check contigious on the TEMPLATED VERSION print(resp) prev_slice = None for elem in resp: print(elem) if prev_slice: assert elem[2].start == prev_slice.stop prev_slice = elem[2] # Check that all literal segments have a raw slice for elem in resp: if elem[0] == "literal": assert elem[1] is not None # check result assert resp == result
def test__templater_jinja(): """Test jinja templating and the treatment of whitespace.""" t = JinjaTemplater(override_context=dict(blah="foo", condition="a < 10")) instr = JINJA_STRING outstr, _ = t.process(in_str=instr, config=FluffConfig()) assert str(outstr) == "SELECT * FROM f, o, o WHERE a < 10\n\n"
"{% if not loop.last -%}", " ", "UNION ALL", " ", "{%- endif %}", "\n", "{% endfor %}", "\n", ], ), ], ids=lambda case: case.name, ) def test__templater_jinja_slices(case: RawTemplatedTestCase): """Test that Jinja templater slices raw and templated file correctly.""" t = JinjaTemplater() templated_file, _ = t.process(in_str=case.instr, fname="test", config=FluffConfig()) assert templated_file assert templated_file.source_str == case.instr assert templated_file.templated_str == case.templated_str # Build and check the list of source strings referenced by "sliced_file". actual_ts_source_list = [ case.instr[ts.source_slice] for ts in templated_file.sliced_file ] assert actual_ts_source_list == case.expected_templated_sliced__source_list # Build and check the list of templated strings referenced by "sliced_file". actual_ts_templated_list = [ templated_file.templated_str[ts.templated_slice]