Navegador

navegador / tests / test_hcl_parser.py
Source Blame History 503 lines
b45288f… lmata 1 """Tests for navegador.ingestion.hcl — HCLParser internal methods."""
b45288f… lmata 2
b45288f… lmata 3 from unittest.mock import MagicMock, patch
b45288f… lmata 4
b45288f… lmata 5 import pytest
b45288f… lmata 6
b45288f… lmata 7 from navegador.graph.schema import EdgeType, NodeLabel
b45288f… lmata 8
b45288f… lmata 9
b45288f… lmata 10 class MockNode:
b45288f… lmata 11 _id_counter = 0
b45288f… lmata 12
b45288f… lmata 13 def __init__(
b45288f… lmata 14 self,
b45288f… lmata 15 type_: str,
b45288f… lmata 16 text: bytes = b"",
b45288f… lmata 17 children: list = None,
b45288f… lmata 18 start_byte: int = 0,
b45288f… lmata 19 end_byte: int = 0,
b45288f… lmata 20 start_point: tuple = (0, 0),
b45288f… lmata 21 end_point: tuple = (0, 0),
b45288f… lmata 22 parent=None,
b45288f… lmata 23 ):
b45288f… lmata 24 MockNode._id_counter += 1
b45288f… lmata 25 self.id = MockNode._id_counter
b45288f… lmata 26 self.type = type_
b45288f… lmata 27 self._text = text
b45288f… lmata 28 self.children = children or []
b45288f… lmata 29 self.start_byte = start_byte
b45288f… lmata 30 self.end_byte = end_byte
b45288f… lmata 31 self.start_point = start_point
b45288f… lmata 32 self.end_point = end_point
b45288f… lmata 33 self.parent = parent
b45288f… lmata 34 self._fields: dict = {}
b45288f… lmata 35 for child in self.children:
b45288f… lmata 36 child.parent = self
b45288f… lmata 37
b45288f… lmata 38 def child_by_field_name(self, name: str):
b45288f… lmata 39 return self._fields.get(name)
b45288f… lmata 40
b45288f… lmata 41 def set_field(self, name: str, node):
b45288f… lmata 42 self._fields[name] = node
b45288f… lmata 43 node.parent = self
b45288f… lmata 44 return self
b45288f… lmata 45
b45288f… lmata 46
b45288f… lmata 47 def _text_node(text: bytes, type_: str = "identifier") -> MockNode:
b45288f… lmata 48 return MockNode(type_, text, start_byte=0, end_byte=len(text))
b45288f… lmata 49
b45288f… lmata 50
b45288f… lmata 51 def _make_store():
b45288f… lmata 52 store = MagicMock()
b45288f… lmata 53 store.query.return_value = MagicMock(result_set=[])
b45288f… lmata 54 return store
b45288f… lmata 55
b45288f… lmata 56
b45288f… lmata 57 def _make_parser():
b45288f… lmata 58 from navegador.ingestion.hcl import HCLParser
b45288f… lmata 59
b45288f… lmata 60 parser = HCLParser.__new__(HCLParser)
b45288f… lmata 61 parser._parser = MagicMock()
b45288f… lmata 62 return parser
b45288f… lmata 63
b45288f… lmata 64
b45288f… lmata 65 class TestHCLGetLanguage:
b45288f… lmata 66 def test_raises_when_not_installed(self):
b45288f… lmata 67 from navegador.ingestion.hcl import _get_hcl_language
b45288f… lmata 68
b45288f… lmata 69 with patch.dict(
b45288f… lmata 70 "sys.modules",
b45288f… lmata 71 {
b45288f… lmata 72 "tree_sitter_hcl": None,
b45288f… lmata 73 "tree_sitter": None,
b45288f… lmata 74 },
b45288f… lmata 75 ):
b45288f… lmata 76 with pytest.raises(ImportError, match="tree-sitter-hcl"):
b45288f… lmata 77 _get_hcl_language()
b45288f… lmata 78
b45288f… lmata 79 def test_returns_language_object(self):
b45288f… lmata 80 from navegador.ingestion.hcl import _get_hcl_language
b45288f… lmata 81
b45288f… lmata 82 mock_tshcl = MagicMock()
b45288f… lmata 83 mock_ts = MagicMock()
b45288f… lmata 84 with patch.dict(
b45288f… lmata 85 "sys.modules",
b45288f… lmata 86 {
b45288f… lmata 87 "tree_sitter_hcl": mock_tshcl,
b45288f… lmata 88 "tree_sitter": mock_ts,
b45288f… lmata 89 },
b45288f… lmata 90 ):
b45288f… lmata 91 result = _get_hcl_language()
b45288f… lmata 92 assert result is mock_ts.Language.return_value
b45288f… lmata 93
b45288f… lmata 94
b45288f… lmata 95 class TestHCLNodeText:
b45288f… lmata 96 def test_extracts_bytes(self):
b45288f… lmata 97 from navegador.ingestion.hcl import _node_text
b45288f… lmata 98
b45288f… lmata 99 source = b'resource "aws_instance" "web" {}'
b45288f… lmata 100 node = MockNode("identifier", start_byte=10, end_byte=22)
b45288f… lmata 101 assert _node_text(node, source) == "aws_instance"
b45288f… lmata 102
b45288f… lmata 103
b45288f… lmata 104 class TestHCLHandleResource:
b45288f… lmata 105 def test_creates_class_node_with_semantic_type(self):
b45288f… lmata 106 parser = _make_parser()
b45288f… lmata 107 store = _make_store()
b45288f… lmata 108 source = b'resource "aws_instance" "web" {}'
b45288f… lmata 109 node = MockNode(
b45288f… lmata 110 "block",
b45288f… lmata 111 start_point=(0, 0),
b45288f… lmata 112 end_point=(0, 30),
b45288f… lmata 113 )
b45288f… lmata 114 labels = ["aws_instance", "web"]
b45288f… lmata 115 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 116 parser._handle_resource(node, source, "main.tf", store, stats, labels, None)
b45288f… lmata 117 assert stats["classes"] == 1
b45288f… lmata 118 assert stats["edges"] == 1
b45288f… lmata 119 store.create_node.assert_called_once()
b45288f… lmata 120 label = store.create_node.call_args[0][0]
b45288f… lmata 121 props = store.create_node.call_args[0][1]
b45288f… lmata 122 assert label == NodeLabel.Class
b45288f… lmata 123 assert props["name"] == "aws_instance.web"
b45288f… lmata 124 assert props["semantic_type"] == "terraform_resource"
b45288f… lmata 125
b45288f… lmata 126 def test_extracts_references_from_body(self):
b45288f… lmata 127 parser = _make_parser()
b45288f… lmata 128 store = _make_store()
b45288f… lmata 129 source = b"var.region"
b45288f… lmata 130 body = MockNode("body", start_byte=0, end_byte=10)
b45288f… lmata 131 node = MockNode(
b45288f… lmata 132 "block",
b45288f… lmata 133 start_point=(0, 0),
b45288f… lmata 134 end_point=(0, 30),
b45288f… lmata 135 )
b45288f… lmata 136 labels = ["aws_instance", "web"]
b45288f… lmata 137 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 138 parser._handle_resource(node, source, "main.tf", store, stats, labels, body)
b45288f… lmata 139 # 1 CONTAINS edge + 1 REFERENCES edge from var.region
b45288f… lmata 140 assert stats["edges"] == 2
b45288f… lmata 141
b45288f… lmata 142
b45288f… lmata 143 class TestHCLHandleVariable:
b45288f… lmata 144 def test_creates_variable_node(self):
b45288f… lmata 145 parser = _make_parser()
b45288f… lmata 146 store = _make_store()
b45288f… lmata 147 source = b'variable "region" {}'
b45288f… lmata 148 node = MockNode(
b45288f… lmata 149 "block",
b45288f… lmata 150 start_point=(0, 0),
b45288f… lmata 151 end_point=(0, 19),
b45288f… lmata 152 )
b45288f… lmata 153 labels = ["region"]
b45288f… lmata 154 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 155 parser._handle_variable(node, source, "vars.tf", store, stats, labels, None)
b45288f… lmata 156 assert stats["functions"] == 1
b45288f… lmata 157 assert stats["edges"] == 1
b45288f… lmata 158 label = store.create_node.call_args[0][0]
b45288f… lmata 159 props = store.create_node.call_args[0][1]
b45288f… lmata 160 assert label == NodeLabel.Variable
b45288f… lmata 161 assert props["name"] == "region"
b45288f… lmata 162 assert props["semantic_type"] == "terraform_variable"
b45288f… lmata 163
b45288f… lmata 164
b45288f… lmata 165 class TestHCLHandleModule:
b45288f… lmata 166 def test_creates_module_node(self):
b45288f… lmata 167 parser = _make_parser()
b45288f… lmata 168 store = _make_store()
b45288f… lmata 169 source = b'module "vpc" {}'
b45288f… lmata 170 node = MockNode(
b45288f… lmata 171 "block",
b45288f… lmata 172 start_point=(0, 0),
b45288f… lmata 173 end_point=(0, 14),
b45288f… lmata 174 )
b45288f… lmata 175 labels = ["vpc"]
b45288f… lmata 176 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 177 parser._handle_module(node, source, "main.tf", store, stats, labels, None)
b45288f… lmata 178 assert stats["classes"] == 1
b45288f… lmata 179 assert stats["edges"] == 1
b45288f… lmata 180 label = store.create_node.call_args[0][0]
b45288f… lmata 181 props = store.create_node.call_args[0][1]
b45288f… lmata 182 assert label == NodeLabel.Module
b45288f… lmata 183 assert props["name"] == "vpc"
b45288f… lmata 184 assert props["semantic_type"] == "terraform_module"
b45288f… lmata 185
b45288f… lmata 186 def test_extracts_source_attribute(self):
b45288f… lmata 187 parser = _make_parser()
b45288f… lmata 188 store = _make_store()
b45288f… lmata 189 full_src = b"source./modules/vpc"
b45288f… lmata 190 ident_node = MockNode(
b45288f… lmata 191 "identifier",
b45288f… lmata 192 start_byte=0,
b45288f… lmata 193 end_byte=6,
b45288f… lmata 194 )
b45288f… lmata 195 expr_node = MockNode(
b45288f… lmata 196 "expression",
b45288f… lmata 197 start_byte=6,
b45288f… lmata 198 end_byte=19,
b45288f… lmata 199 )
b45288f… lmata 200 expr_node.is_named = True
b45288f… lmata 201 attr_node = MockNode(
b45288f… lmata 202 "attribute",
b45288f… lmata 203 children=[ident_node, expr_node],
b45288f… lmata 204 )
b45288f… lmata 205 body_node = MockNode("body", children=[attr_node])
b45288f… lmata 206 node = MockNode(
b45288f… lmata 207 "block",
b45288f… lmata 208 start_point=(0, 0),
b45288f… lmata 209 end_point=(0, 30),
b45288f… lmata 210 )
b45288f… lmata 211 labels = ["vpc"]
b45288f… lmata 212 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 213 parser._handle_module(node, full_src, "main.tf", store, stats, labels, body_node)
b45288f… lmata 214 props = store.create_node.call_args[0][1]
b45288f… lmata 215 assert props["source"] == "./modules/vpc"
b45288f… lmata 216
b45288f… lmata 217
b45288f… lmata 218 class TestHCLHandleOutput:
b45288f… lmata 219 def test_creates_variable_node(self):
b45288f… lmata 220 parser = _make_parser()
b45288f… lmata 221 store = _make_store()
b45288f… lmata 222 source = b'output "vpc_id" {}'
b45288f… lmata 223 node = MockNode(
b45288f… lmata 224 "block",
b45288f… lmata 225 start_point=(0, 0),
b45288f… lmata 226 end_point=(0, 17),
b45288f… lmata 227 )
b45288f… lmata 228 labels = ["vpc_id"]
b45288f… lmata 229 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 230 parser._handle_output(node, source, "outputs.tf", store, stats, labels, None)
b45288f… lmata 231 assert stats["functions"] == 1
b45288f… lmata 232 assert stats["edges"] == 1
b45288f… lmata 233 label = store.create_node.call_args[0][0]
b45288f… lmata 234 props = store.create_node.call_args[0][1]
b45288f… lmata 235 assert label == NodeLabel.Variable
b45288f… lmata 236 assert props["semantic_type"] == "terraform_output"
b45288f… lmata 237
b45288f… lmata 238 def test_extracts_references_from_body(self):
b45288f… lmata 239 parser = _make_parser()
b45288f… lmata 240 store = _make_store()
b45288f… lmata 241 source = b"module.vpc"
b45288f… lmata 242 body = MockNode("body", start_byte=0, end_byte=10)
b45288f… lmata 243 node = MockNode(
b45288f… lmata 244 "block",
b45288f… lmata 245 start_point=(0, 0),
b45288f… lmata 246 end_point=(0, 17),
b45288f… lmata 247 )
b45288f… lmata 248 labels = ["vpc_id"]
b45288f… lmata 249 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 250 parser._handle_output(node, source, "outputs.tf", store, stats, labels, body)
b45288f… lmata 251 # 1 CONTAINS + 1 REFERENCES (module.vpc)
b45288f… lmata 252 assert stats["edges"] == 2
b45288f… lmata 253
b45288f… lmata 254
b45288f… lmata 255 class TestHCLHandleProvider:
b45288f… lmata 256 def test_creates_class_node(self):
b45288f… lmata 257 parser = _make_parser()
b45288f… lmata 258 store = _make_store()
b45288f… lmata 259 source = b'provider "aws" {}'
b45288f… lmata 260 node = MockNode(
b45288f… lmata 261 "block",
b45288f… lmata 262 start_point=(0, 0),
b45288f… lmata 263 end_point=(0, 16),
b45288f… lmata 264 )
b45288f… lmata 265 labels = ["aws"]
b45288f… lmata 266 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 267 parser._handle_provider(node, source, "provider.tf", store, stats, labels, None)
b45288f… lmata 268 assert stats["classes"] == 1
b45288f… lmata 269 assert stats["edges"] == 1
b45288f… lmata 270 label = store.create_node.call_args[0][0]
b45288f… lmata 271 props = store.create_node.call_args[0][1]
b45288f… lmata 272 assert label == NodeLabel.Class
b45288f… lmata 273 assert props["name"] == "aws"
b45288f… lmata 274 assert props["semantic_type"] == "terraform_provider"
b45288f… lmata 275
b45288f… lmata 276
b45288f… lmata 277 class TestHCLHandleLocals:
b45288f… lmata 278 def test_creates_variable_nodes(self):
b45288f… lmata 279 parser = _make_parser()
b45288f… lmata 280 store = _make_store()
b45288f… lmata 281 source = b"region"
b45288f… lmata 282 ident = MockNode(
b45288f… lmata 283 "identifier",
b45288f… lmata 284 start_byte=0,
b45288f… lmata 285 end_byte=6,
b45288f… lmata 286 )
b45288f… lmata 287 attr = MockNode(
b45288f… lmata 288 "attribute",
b45288f… lmata 289 children=[ident],
b45288f… lmata 290 start_point=(1, 0),
b45288f… lmata 291 end_point=(1, 20),
b45288f… lmata 292 )
b45288f… lmata 293 body = MockNode("body", children=[attr])
b45288f… lmata 294 node = MockNode(
b45288f… lmata 295 "block",
b45288f… lmata 296 start_point=(0, 0),
b45288f… lmata 297 end_point=(2, 1),
b45288f… lmata 298 )
b45288f… lmata 299 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 300 parser._handle_locals(node, source, "locals.tf", store, stats, body)
b45288f… lmata 301 assert stats["functions"] == 1
b45288f… lmata 302 assert stats["edges"] >= 1
b45288f… lmata 303 label = store.create_node.call_args[0][0]
b45288f… lmata 304 props = store.create_node.call_args[0][1]
b45288f… lmata 305 assert label == NodeLabel.Variable
b45288f… lmata 306 assert props["semantic_type"] == "terraform_local"
b45288f… lmata 307
b45288f… lmata 308 def test_skips_when_no_body(self):
b45288f… lmata 309 parser = _make_parser()
b45288f… lmata 310 store = _make_store()
b45288f… lmata 311 node = MockNode("block", start_point=(0, 0), end_point=(0, 5))
b45288f… lmata 312 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 313 parser._handle_locals(node, b"", "locals.tf", store, stats, None)
b45288f… lmata 314 assert stats["functions"] == 0
b45288f… lmata 315 store.create_node.assert_not_called()
b45288f… lmata 316
b45288f… lmata 317
b45288f… lmata 318 class TestHCLWalkDispatch:
b45288f… lmata 319 def test_walk_dispatches_block_in_body(self):
b45288f… lmata 320 parser = _make_parser()
b45288f… lmata 321 store = _make_store()
b45288f… lmata 322 # Build: root > body > block(variable "region")
b45288f… lmata 323 source = b'variable "region" {}'
b45288f… lmata 324 ident = MockNode(
b45288f… lmata 325 "identifier",
b45288f… lmata 326 start_byte=0,
b45288f… lmata 327 end_byte=8,
b45288f… lmata 328 )
b45288f… lmata 329 string_lit_inner = MockNode(
b45288f… lmata 330 "template_literal",
b45288f… lmata 331 start_byte=10,
b45288f… lmata 332 end_byte=16,
b45288f… lmata 333 )
b45288f… lmata 334 string_lit = MockNode(
b45288f… lmata 335 "string_lit",
b45288f… lmata 336 children=[string_lit_inner],
b45288f… lmata 337 start_byte=9,
b45288f… lmata 338 end_byte=17,
b45288f… lmata 339 )
b45288f… lmata 340 block = MockNode(
b45288f… lmata 341 "block",
b45288f… lmata 342 children=[ident, string_lit],
b45288f… lmata 343 start_point=(0, 0),
b45288f… lmata 344 end_point=(0, 19),
b45288f… lmata 345 )
b45288f… lmata 346 body = MockNode("body", children=[block])
b45288f… lmata 347 root = MockNode("config_file", children=[body])
b45288f… lmata 348 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 349 parser._walk(root, source, "vars.tf", store, stats)
b45288f… lmata 350 assert stats["functions"] == 1
b45288f… lmata 351
b45288f… lmata 352 def test_walk_dispatches_top_level_block(self):
b45288f… lmata 353 parser = _make_parser()
b45288f… lmata 354 store = _make_store()
b45288f… lmata 355 source = b'provider "aws" {}'
b45288f… lmata 356 ident = MockNode(
b45288f… lmata 357 "identifier",
b45288f… lmata 358 start_byte=0,
b45288f… lmata 359 end_byte=8,
b45288f… lmata 360 )
b45288f… lmata 361 string_lit_inner = MockNode(
b45288f… lmata 362 "template_literal",
b45288f… lmata 363 start_byte=10,
b45288f… lmata 364 end_byte=13,
b45288f… lmata 365 )
b45288f… lmata 366 string_lit = MockNode(
b45288f… lmata 367 "string_lit",
b45288f… lmata 368 children=[string_lit_inner],
b45288f… lmata 369 start_byte=9,
b45288f… lmata 370 end_byte=14,
b45288f… lmata 371 )
b45288f… lmata 372 block = MockNode(
b45288f… lmata 373 "block",
b45288f… lmata 374 children=[ident, string_lit],
b45288f… lmata 375 start_point=(0, 0),
b45288f… lmata 376 end_point=(0, 16),
b45288f… lmata 377 )
b45288f… lmata 378 root = MockNode("config_file", children=[block])
b45288f… lmata 379 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 380 parser._walk(root, source, "main.tf", store, stats)
b45288f… lmata 381 assert stats["classes"] == 1
b45288f… lmata 382
b45288f… lmata 383
b45288f… lmata 384 class TestHCLExtractReferences:
b45288f… lmata 385 def test_finds_var_reference(self):
b45288f… lmata 386 parser = _make_parser()
b45288f… lmata 387 store = _make_store()
b45288f… lmata 388 source = b"var.region"
b45288f… lmata 389 node = MockNode("body", start_byte=0, end_byte=10)
b45288f… lmata 390 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 391 parser._extract_references(
b45288f… lmata 392 node,
b45288f… lmata 393 source,
b45288f… lmata 394 "main.tf",
b45288f… lmata 395 "aws_instance.web",
b45288f… lmata 396 NodeLabel.Class,
b45288f… lmata 397 store,
b45288f… lmata 398 stats,
b45288f… lmata 399 )
b45288f… lmata 400 assert stats["edges"] == 1
b45288f… lmata 401 edge_call = store.create_edge.call_args[0]
b45288f… lmata 402 assert edge_call[2] == EdgeType.REFERENCES
b45288f… lmata 403 assert edge_call[4]["name"] == "region"
b45288f… lmata 404
b45288f… lmata 405 def test_finds_resource_reference(self):
b45288f… lmata 406 parser = _make_parser()
b45288f… lmata 407 store = _make_store()
b45288f… lmata 408 source = b"aws_security_group.default"
b45288f… lmata 409 node = MockNode("body", start_byte=0, end_byte=25)
b45288f… lmata 410 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 411 parser._extract_references(
b45288f… lmata 412 node,
b45288f… lmata 413 source,
b45288f… lmata 414 "main.tf",
b45288f… lmata 415 "aws_instance.web",
b45288f… lmata 416 NodeLabel.Class,
b45288f… lmata 417 store,
b45288f… lmata 418 stats,
b45288f… lmata 419 )
b45288f… lmata 420 assert stats["edges"] == 1
b45288f… lmata 421 edge_call = store.create_edge.call_args[0]
b45288f… lmata 422 assert edge_call[2] == EdgeType.DEPENDS_ON
b45288f… lmata 423
b45288f… lmata 424 def test_finds_local_reference(self):
b45288f… lmata 425 parser = _make_parser()
b45288f… lmata 426 store = _make_store()
b45288f… lmata 427 source = b"local.common_tags"
b45288f… lmata 428 node = MockNode("body", start_byte=0, end_byte=17)
b45288f… lmata 429 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 430 parser._extract_references(
b45288f… lmata 431 node,
b45288f… lmata 432 source,
b45288f… lmata 433 "main.tf",
b45288f… lmata 434 "aws_instance.web",
b45288f… lmata 435 NodeLabel.Class,
b45288f… lmata 436 store,
b45288f… lmata 437 stats,
b45288f… lmata 438 )
b45288f… lmata 439 assert stats["edges"] == 1
b45288f… lmata 440
b45288f… lmata 441 def test_finds_module_reference(self):
b45288f… lmata 442 parser = _make_parser()
b45288f… lmata 443 store = _make_store()
b45288f… lmata 444 source = b"module.vpc"
b45288f… lmata 445 node = MockNode("body", start_byte=0, end_byte=10)
b45288f… lmata 446 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 447 parser._extract_references(
b45288f… lmata 448 node,
b45288f… lmata 449 source,
b45288f… lmata 450 "main.tf",
b45288f… lmata 451 "output_vpc",
b45288f… lmata 452 NodeLabel.Variable,
b45288f… lmata 453 store,
b45288f… lmata 454 stats,
b45288f… lmata 455 )
b45288f… lmata 456 assert stats["edges"] == 1
b45288f… lmata 457 edge_call = store.create_edge.call_args[0]
b45288f… lmata 458 assert edge_call[3] == NodeLabel.Module
b45288f… lmata 459
b45288f… lmata 460 def test_finds_data_reference(self):
b45288f… lmata 461 parser = _make_parser()
b45288f… lmata 462 store = _make_store()
b45288f… lmata 463 source = b"data.http.myip"
b45288f… lmata 464 node = MockNode("body", start_byte=0, end_byte=14)
b45288f… lmata 465 stats = {"functions": 0, "classes": 0, "edges": 0}
b45288f… lmata 466 parser._extract_references(
b45288f… lmata 467 node,
b45288f… lmata 468 source,
b45288f… lmata 469 "main.tf",
b45288f… lmata 470 "aws_instance.web",
b45288f… lmata 471 NodeLabel.Class,
b45288f… lmata 472 store,
b45288f… lmata 473 stats,
b45288f… lmata 474 )
b45288f… lmata 475 assert stats["edges"] == 1
b45288f… lmata 476 edge_call = store.create_edge.call_args[0]
b45288f… lmata 477 assert edge_call[2] == EdgeType.DEPENDS_ON
b45288f… lmata 478 assert edge_call[4]["name"] == "http.myip"
b45288f… lmata 479
b45288f… lmata 480
b45288f… lmata 481 class TestHCLParseFile:
b45288f… lmata 482 def test_creates_file_node(self):
b45288f… lmata 483 import tempfile
b45288f… lmata 484 from pathlib import Path
b45288f… lmata 485
b45288f… lmata 486 parser = _make_parser()
b45288f… lmata 487 store = _make_store()
b45288f… lmata 488 mock_tree = MagicMock()
b45288f… lmata 489 mock_tree.root_node.type = "config_file"
b45288f… lmata 490 mock_tree.root_node.children = []
b45288f… lmata 491 parser._parser.parse.return_value = mock_tree
b45288f… lmata 492 with tempfile.NamedTemporaryFile(suffix=".tf", delete=False) as f:
b45288f… lmata 493 f.write(b'resource "aws_instance" "web" {}\n')
b45288f… lmata 494 fpath = Path(f.name)
b45288f… lmata 495 try:
b45288f… lmata 496 parser.parse_file(fpath, fpath.parent, store)
b45288f… lmata 497 store.create_node.assert_called_once()
b45288f… lmata 498 label = store.create_node.call_args[0][0]
b45288f… lmata 499 props = store.create_node.call_args[0][1]
b45288f… lmata 500 assert label == NodeLabel.File
b45288f… lmata 501 assert props["language"] == "hcl"
b45288f… lmata 502 finally:
b45288f… lmata 503 fpath.unlink()

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button