ara-cli 0.1.9.69__py3-none-any.whl → 0.1.9.71__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. ara_cli/ara_command_action.py +16 -12
  2. ara_cli/ara_config.py +24 -10
  3. ara_cli/artefact_autofix.py +278 -23
  4. ara_cli/artefact_creator.py +3 -3
  5. ara_cli/artefact_fuzzy_search.py +9 -4
  6. ara_cli/artefact_link_updater.py +4 -4
  7. ara_cli/artefact_models/artefact_model.py +14 -7
  8. ara_cli/artefact_models/artefact_templates.py +1 -1
  9. ara_cli/artefact_models/feature_artefact_model.py +72 -18
  10. ara_cli/artefact_models/serialize_helper.py +1 -1
  11. ara_cli/artefact_reader.py +16 -38
  12. ara_cli/artefact_renamer.py +2 -2
  13. ara_cli/artefact_scan.py +28 -3
  14. ara_cli/chat.py +1 -1
  15. ara_cli/file_classifier.py +3 -3
  16. ara_cli/file_lister.py +1 -1
  17. ara_cli/list_filter.py +1 -1
  18. ara_cli/output_suppressor.py +1 -1
  19. ara_cli/prompt_extractor.py +3 -3
  20. ara_cli/prompt_handler.py +9 -10
  21. ara_cli/prompt_rag.py +2 -2
  22. ara_cli/template_manager.py +2 -2
  23. ara_cli/templates/prompt-modules/blueprints/complete_pytest_unittest.blueprint.md +1 -1
  24. ara_cli/update_config_prompt.py +2 -2
  25. ara_cli/version.py +1 -1
  26. {ara_cli-0.1.9.69.dist-info → ara_cli-0.1.9.71.dist-info}/METADATA +1 -1
  27. {ara_cli-0.1.9.69.dist-info → ara_cli-0.1.9.71.dist-info}/RECORD +39 -39
  28. tests/test_ara_command_action.py +7 -7
  29. tests/{test_ara_autofix.py → test_artefact_autofix.py} +163 -29
  30. tests/test_artefact_link_updater.py +3 -3
  31. tests/test_artefact_renamer.py +2 -2
  32. tests/test_artefact_scan.py +52 -19
  33. tests/test_file_classifier.py +1 -1
  34. tests/test_file_lister.py +1 -1
  35. tests/test_list_filter.py +2 -2
  36. tests/test_update_config_prompt.py +2 -2
  37. {ara_cli-0.1.9.69.dist-info → ara_cli-0.1.9.71.dist-info}/WHEEL +0 -0
  38. {ara_cli-0.1.9.69.dist-info → ara_cli-0.1.9.71.dist-info}/entry_points.txt +0 -0
  39. {ara_cli-0.1.9.69.dist-info → ara_cli-0.1.9.71.dist-info}/top_level.txt +0 -0
@@ -8,6 +8,8 @@ def test_check_file_valid():
8
8
  """Tests the happy path where the file is valid and the title matches."""
9
9
  mock_artefact_instance = MagicMock()
10
10
  mock_artefact_instance.title = "dummy_path"
11
+ # Mock contribution to be None to avoid contribution reference check
12
+ mock_artefact_instance.contribution = None
11
13
 
12
14
  mock_artefact_class = MagicMock()
13
15
  mock_artefact_class.deserialize.return_value = mock_artefact_instance
@@ -15,8 +17,8 @@ def test_check_file_valid():
15
17
  with patch("builtins.open", mock_open(read_data="valid content")):
16
18
  is_valid, reason = check_file("dummy_path.feature", mock_artefact_class)
17
19
 
18
- assert is_valid is True
19
- assert reason is None
20
+ assert reason is None, f"Reason for invalid found, expected none to be found. The reason found: {reason}"
21
+ assert is_valid is True, "File detected as invalid, expected to be valid"
20
22
 
21
23
 
22
24
  def test_check_file_title_mismatch():
@@ -80,31 +82,35 @@ def test_check_file_unexpected_error():
80
82
 
81
83
 
82
84
  def test_find_invalid_files():
85
+ """Tests finding invalid files with proper mocking of check_file."""
83
86
  mock_artefact_class = MagicMock()
84
- with patch("ara_cli.artefact_models.artefact_mapping.artefact_type_mapping", {"test_classifier": mock_artefact_class}):
85
- artefact_files = {
86
- "test_classifier": [
87
- {"file_path": "file1.txt"}, # Should be checked
88
- {"file_path": "file2.txt"}, # Should be checked
89
- {"file_path": "templates/file3.txt"}, # Should be skipped
90
- {"file_path": "some/path/file.data"} # Should be skipped
91
- ]
92
- }
93
-
87
+ classified_info = {
88
+ "test_classifier": [
89
+ {"file_path": "file1.txt"}, # Should be checked
90
+ {"file_path": "file2.txt"}, # Should be checked
91
+ {"file_path": "templates/file3.txt"}, # Should be skipped
92
+ {"file_path": "some/path/file.data"} # Should be skipped
93
+ ]
94
+ }
95
+
96
+ with patch("ara_cli.artefact_models.artefact_mapping.artefact_type_mapping",
97
+ {"test_classifier": mock_artefact_class}):
94
98
  with patch("ara_cli.artefact_scan.check_file") as mock_check_file:
95
99
  mock_check_file.side_effect = [
96
100
  (True, None), # for file1.txt
97
101
  (False, "Invalid content") # for file2.txt
98
102
  ]
99
103
 
100
- invalid_files = find_invalid_files(
101
- artefact_files, "test_classifier")
104
+ invalid_files = find_invalid_files(classified_info, "test_classifier")
105
+
102
106
  assert len(invalid_files) == 1
103
107
  assert invalid_files[0] == ("file2.txt", "Invalid content")
104
108
  assert mock_check_file.call_count == 2
109
+
110
+ # Check that check_file was called with the correct parameters
105
111
  mock_check_file.assert_has_calls([
106
- call("file1.txt", mock_artefact_class),
107
- call("file2.txt", mock_artefact_class)
112
+ call("file1.txt", mock_artefact_class, classified_info),
113
+ call("file2.txt", mock_artefact_class, classified_info)
108
114
  ], any_order=False)
109
115
 
110
116
 
@@ -114,7 +120,7 @@ def test_show_results_no_issues(capsys):
114
120
  show_results(invalid_artefacts)
115
121
  captured = capsys.readouterr()
116
122
  assert captured.out == "All files are good!\n"
117
- m.assert_called_once_with("incompatible_artefacts_report.md", "w")
123
+ m.assert_called_once_with("incompatible_artefacts_report.md", "w", encoding="utf-8")
118
124
  handle = m()
119
125
  handle.write.assert_has_calls([
120
126
  call("# Artefact Check Report\n\n"),
@@ -141,7 +147,7 @@ def test_show_results_with_issues(capsys):
141
147
  "\t\treason3\n"
142
148
  )
143
149
  assert captured.out == expected_output
144
- m.assert_called_once_with("incompatible_artefacts_report.md", "w")
150
+ m.assert_called_once_with("incompatible_artefacts_report.md", "w", encoding="utf-8")
145
151
  handle = m()
146
152
  expected_writes = [
147
153
  call("# Artefact Check Report\n\n"),
@@ -153,4 +159,31 @@ def test_show_results_with_issues(capsys):
153
159
  call("- `file3.txt`: reason3\n"),
154
160
  call("\n")
155
161
  ]
156
- handle.write.assert_has_calls(expected_writes, any_order=False)
162
+ handle.write.assert_has_calls(expected_writes, any_order=False)
163
+
164
+
165
+ def test_check_file_with_invalid_contribution():
166
+ """Tests file with invalid contribution reference."""
167
+ mock_artefact_instance = MagicMock()
168
+ mock_artefact_instance.title = "dummy_path"
169
+
170
+ # Set up invalid contribution
171
+ mock_contribution = MagicMock()
172
+ mock_contribution.classifier = "test_classifier"
173
+ mock_contribution.artefact_name = "non_existing_artefact"
174
+ mock_artefact_instance.contribution = mock_contribution
175
+
176
+ mock_artefact_class = MagicMock()
177
+ mock_artefact_class.deserialize.return_value = mock_artefact_instance
178
+
179
+ # Mock classified_artefact_info
180
+ classified_info = {"test_classifier": [{"name": "existing_artefact"}]}
181
+
182
+ # Mock extract_artefact_names_of_classifier to return a list without the referenced artefact
183
+ with patch("builtins.open", mock_open(read_data="valid content")):
184
+ with patch("ara_cli.artefact_fuzzy_search.extract_artefact_names_of_classifier",
185
+ return_value=["existing_artefact"]):
186
+ is_valid, reason = check_file("dummy_path.feature", mock_artefact_class, classified_info)
187
+
188
+ assert is_valid is False
189
+ assert "Invalid Contribution Reference" in reason
@@ -241,7 +241,7 @@ def test_find_closest_artefact_name_match(mock_file_system):
241
241
  'file1', 'py') == 'file1'
242
242
 
243
243
  # Fuzzy match
244
- with patch('ara_cli.file_classifier.find_closest_name_match', return_value='file2') as mock_fuzzy:
244
+ with patch('ara_cli.file_classifier.find_closest_name_matches', return_value='file2') as mock_fuzzy:
245
245
  assert classifier.find_closest_artefact_name_match(
246
246
  'file3', 'py') == 'file2'
247
247
  mock_fuzzy.assert_called_once_with('file3', ['file1', 'file2'])
tests/test_file_lister.py CHANGED
@@ -55,7 +55,7 @@ def test_generate_markdown_listing_multiple_directories(setup_test_environment):
55
55
 
56
56
  generate_markdown_listing([temp_dir, another_temp_dir], ['*.py'], output_file_path)
57
57
 
58
- with open(output_file_path, 'r') as f:
58
+ with open(output_file_path, 'r', encoding='utf-8') as f:
59
59
  output_content = f.read().splitlines()
60
60
 
61
61
  assert output_content == expected_content
tests/test_list_filter.py CHANGED
@@ -65,7 +65,7 @@ def test_default_content_retrieval():
65
65
  with patch("builtins.open", mock_open(read_data=mock_data)) as mocked_file:
66
66
  content = ListFilterMonad.default_content_retrieval("dummy_path")
67
67
  assert content == mock_data
68
- mocked_file.assert_called_once_with("dummy_path", 'r')
68
+ mocked_file.assert_called_once_with("dummy_path", 'r', encoding='utf-8')
69
69
 
70
70
 
71
71
  def test_default_tag_retrieval():
@@ -77,7 +77,7 @@ def test_default_content_retrieval_exception():
77
77
  with patch("builtins.open", side_effect=Exception("Mocked exception")) as mocked_file:
78
78
  content = ListFilterMonad.default_content_retrieval("dummy_path")
79
79
  assert content == "" # Expect empty string on exception
80
- mocked_file.assert_called_once_with("dummy_path", 'r')
80
+ mocked_file.assert_called_once_with("dummy_path", 'r', encoding='utf-8')
81
81
 
82
82
 
83
83
  @pytest.mark.parametrize("include, exclude, expected", [
@@ -34,13 +34,13 @@ mock_content_updated = """
34
34
  def test_read_file():
35
35
  with patch('builtins.open', mock_open(read_data="data")) as mocked_file:
36
36
  result = read_file('dummy_path')
37
- mocked_file.assert_called_once_with('dummy_path', 'r')
37
+ mocked_file.assert_called_once_with('dummy_path', 'r', encoding='utf-8')
38
38
  assert result == "data"
39
39
 
40
40
  def test_write_file():
41
41
  with patch('builtins.open', mock_open()) as mocked_file:
42
42
  write_file('dummy_path', 'data')
43
- mocked_file.assert_called_once_with('dummy_path', 'w')
43
+ mocked_file.assert_called_once_with('dummy_path', 'w', encoding='utf-8')
44
44
  mocked_file().write.assert_called_once_with('data')
45
45
 
46
46
  def test_find_checked_items():