Coverage for lobster/common/level_definition.py: 100%

26 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2026-09-22 04:43 +0000

1# LOBSTER - Lightweight Open BMW Software Traceability Evidence Report 

2# Copyright (C) 2025-2026 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) 

3# 

4# This program is free software: you can redistribute it and/or modify 

5# it under the terms of the GNU Affero General Public License as 

6# published by the Free Software Foundation, either version 3 of the 

7# License, or (at your option) any later version. 

8# 

9# This program is distributed in the hope that it will be useful, but 

10# WITHOUT ANY WARRANTY; without even the implied warranty of 

11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 

12# Affero General Public License for more details. 

13# 

14# You should have received a copy of the GNU Affero General Public 

15# License along with this program. If not, see 

16# <https://www.gnu.org/licenses/>. 

17 

18from dataclasses import dataclass, field 

19from typing import List, Any 

20 

21 

22@dataclass 

23class LevelDefinition: 

24 name: str 

25 kind: str 

26 traces: List[str] = field(default_factory=list) 

27 source: List[Any] = field(default_factory=list) 

28 needs_tracing_up: bool = False 

29 needs_tracing_down: bool = False 

30 breakdown_requirements: List[Any] = field(default_factory=list) 

31 

32 # Flags for serialization - they are a workaround due to the fact that the system 

33 # tests do a text comparison of a generated LOBSTER file against a reference file. 

34 # The serialization pattern should be updated such that empty lists are not 

35 # serialized, but that means to update all system tests. 

36 # This is a temporary solution to avoid breaking existing tests. 

37 serialize_needs_tracing_up: bool = True 

38 serialize_needs_tracing_down: bool = True 

39 serialize_breakdown_requirements: bool = True 

40 

41 def to_json(self) -> dict: 

42 """Convert the Level instance to a JSON-compatible dictionary.""" 

43 result = { 

44 "name": self.name, 

45 "kind": self.kind, 

46 "traces": self.traces, 

47 "source": self.source, 

48 } 

49 if self.serialize_needs_tracing_up: 

50 result["needs_tracing_up"] = self.needs_tracing_up 

51 if self.serialize_needs_tracing_down: 

52 result["needs_tracing_down"] = self.needs_tracing_down 

53 if self.serialize_breakdown_requirements: 

54 result["breakdown_requirements"] = self.breakdown_requirements 

55 return result 

56 

57 @classmethod 

58 def from_json(cls, data: dict) -> 'LevelDefinition': 

59 """Create a Level instance from a JSON-compatible dictionary.""" 

60 return cls( 

61 name=data["name"], 

62 kind=data["kind"], 

63 traces=data.get("traces", []), 

64 source=data.get("source", []), 

65 needs_tracing_up=data.get("needs_tracing_up", False), 

66 needs_tracing_down=data.get("needs_tracing_down", False), 

67 breakdown_requirements=data.get("breakdown_requirements", []), 

68 serialize_needs_tracing_up="needs_tracing_up" in data, 

69 serialize_needs_tracing_down="needs_tracing_down" in data, 

70 serialize_breakdown_requirements="breakdown_requirements" in data, 

71 )