Repository navigation
Expand file tree
/
Copy pathtest_metadata.py
More file actions
184 lines (159 loc) · 10.1 KB
/
Copy pathtest_metadata.py
File metadata and controls
184 lines (159 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import json
import os
import pathlib
import subprocess
import tempfile
import unittest
from unittest.mock import patch
import controller
class ReadmeDescriptionTests(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.addCleanup(self.temp.cleanup)
self.root = pathlib.Path(self.temp.name)
self.readme = self.root / 'README.md'
self.metadata = {'sourceDir': str(self.root),
'manifestPath': str(self.root / 'manifest.json'),
'description': 'Manifest fallback.'}
def test_explicit_section_overrides_manifest_and_stops_at_next_paragraph(self):
self.readme.write_text('# Plugin\n\n## Description for Agents\n\n'
'Adjust the camera.\nPreview changes live.\n\n'
'Developer instructions do not belong in the tooltip.\n')
self.assertEqual(controller.plugin_description(self.metadata),
'Adjust the camera. Preview changes live.')
def test_heading_is_case_insensitive_and_next_heading_ends_description(self):
self.readme.write_text('## description FOR agents ###\nShows the weather.\n## Install\nRun setup.\n')
self.assertEqual(controller.plugin_description(self.metadata), 'Shows the weather.')
def test_examples_inside_backtick_and_tilde_fences_are_ignored(self):
for fence in ('```', '~~~~'):
with self.subTest(fence=fence):
self.readme.write_text(f'{fence}markdown\n## Description for Agents\n'
f'Example only.\n{fence}\n\n'
'## Description for Agents\nActual description.\n')
self.assertEqual(controller.plugin_description(self.metadata), 'Actual description.')
def test_missing_empty_duplicate_and_nonparagraph_sections_fall_back(self):
for text in ('# Plugin\nA general introduction.',
'## Description for Agents\n\n## Install\nOther content.',
'## Description for Agents\nOne.\n## Description for Agents\nTwo.',
'## Description for Agents\n- A list item.',
'## Description for Agents\n```\nAn example.\n```',
'## Description for Agents\n An indented example.'):
with self.subTest(text=text):
self.readme.write_text(text)
self.assertEqual(controller.plugin_description(self.metadata), 'Manifest fallback.')
def test_invalid_encoding_and_oversized_readmes_fall_back(self):
for data in (b'## Description for Agents\n\xff',
b'## Description for Agents\n' + b'x' * (256 * 1024)):
with self.subTest(size=len(data)):
self.readme.write_bytes(data)
self.assertEqual(controller.plugin_description(self.metadata), 'Manifest fallback.')
def test_description_is_bounded_and_markup_stays_literal(self):
markup = '<img src="https://example.invalid/tracker">'
self.readme.write_text('## Description for Agents\n' + markup)
self.assertEqual(controller.plugin_description(self.metadata), markup)
self.readme.write_text('## Description for Agents\n' + 'x' * 2000)
value = controller.plugin_description(self.metadata)
self.assertEqual(len(value), 1200)
self.assertTrue(value.endswith('…'))
def test_symlinked_checkout_works_but_readme_symlinks_are_not_followed(self):
self.readme.write_text('## Description for Agents\nControls the light.')
link = self.root / 'installed'
link.symlink_to(self.root, target_is_directory=True)
self.assertEqual(controller.plugin_description({**self.metadata, 'sourceDir': str(link)}),
'Controls the light.')
other = self.root / 'outside.md'
self.readme.rename(other)
self.readme.symlink_to(other)
self.assertEqual(controller.plugin_description(self.metadata), 'Manifest fallback.')
def test_nonregular_files_do_not_block(self):
os.mkfifo(self.readme)
self.assertEqual(controller.plugin_description(self.metadata), 'Manifest fallback.')
def test_shared_builtin_directory_does_not_supply_another_plugins_description(self):
self.readme.write_text('## Description for Agents\nShared directory description.')
metadata = {**self.metadata, 'manifestPath': str(self.root / 'audio.json')}
self.assertEqual(controller.plugin_description(metadata), 'Manifest fallback.')
def test_inventory_reads_readme_description_without_network(self):
home = self.root / 'home'
config = home / '.config/omarchy/shell.json'
config.parent.mkdir(parents=True)
config.write_text('{"bar":{"layout":{}}}')
self.readme.write_text('## Description for Agents\nControls the light.')
plugin = {'id': 'test.light', 'name': 'Light', 'kinds': ['bar-widget'], 'firstParty': False}
metadata = {**self.metadata, 'id': plugin['id']}
with patch.object(controller.pathlib.Path, 'home', return_value=home), \
patch.object(controller, 'run', side_effect=[json.dumps([plugin]), json.dumps([metadata])]), \
patch.object(controller.urllib.request, 'urlopen') as network:
self.assertEqual(controller.inventory()[0]['description'], 'Controls the light.')
network.assert_not_called()
class AuthorHistoryTests(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.addCleanup(self.temp.cleanup)
self.root = pathlib.Path(self.temp.name) / 'source'
self.git('init', '--initial-branch=master', str(self.root), outside=True)
self.git('config', 'user.name', 'Later Maintainer')
self.git('config', 'user.email', 'maintainer@example.invalid')
(self.root / 'Old.qml').write_text('Item {}\n')
self.commit('Original plugin', 'Original Author', '2025-01-01T00:00:00Z')
self.original = self.git('rev-parse', 'HEAD')
self.git('mv', 'Old.qml', 'Widget.qml')
self.commit('Rename widget', 'Later Maintainer', '2025-02-01T00:00:00Z')
(self.root / 'manifest.json').write_text(json.dumps({'author': 'Omarchy'}))
self.commit('Add manifest', 'Later Maintainer', '2025-03-01T00:00:00Z')
self.metadata = {'sourceDir': str(self.root), 'manifestPath': str(self.root / 'manifest.json'),
'entryPoints': {'barWidget': 'Widget.qml'}, 'firstParty': True}
def git(self, *args, outside=False, env=None):
argv = ['git'] + ([] if outside else ['-C', str(self.root)]) + list(args)
return subprocess.check_output(argv, text=True, stderr=subprocess.DEVNULL, env=env).strip()
def commit(self, message, author, date):
self.git('add', '.')
self.git('commit', '-m', message, env=dict(os.environ, GIT_AUTHOR_NAME=author,
GIT_AUTHOR_EMAIL='author@example.invalid', GIT_AUTHOR_DATE=date, GIT_COMMITTER_DATE=date))
def test_default_plugin_author_follows_renames_to_first_file_commit(self):
value = controller.plugin_details(self.metadata, {})
self.assertEqual(value['author'], 'Original Author')
self.assertEqual(value['authorCommit'], self.original)
self.assertEqual(value['authorSource'], 'first-commit')
self.assertFalse(value['authorHistoryShallow'])
def test_explicit_person_attribution_is_preserved(self):
(self.root / 'manifest.json').write_text('{"author":"Explicit Author"}')
value = controller.plugin_details(self.metadata, {})
self.assertEqual(value['author'], 'Explicit Author')
self.assertNotIn('authorSource', value)
def test_history_cache_avoids_repeating_log_walk(self):
cache = {}
first = controller.first_commit_author(self.metadata, cache)
with patch.object(controller.updates, 'git', wraps=controller.updates.git) as git:
self.assertEqual(controller.first_commit_author(self.metadata, cache), first)
self.assertFalse(any('log' in call.args for call in git.call_args_list))
def test_shallow_history_is_explicitly_identified(self):
clone = pathlib.Path(self.temp.name) / 'shallow'
self.git('clone', '--depth=1', self.root.as_uri(), str(clone), outside=True)
metadata = {**self.metadata, 'sourceDir': str(clone), 'manifestPath': str(clone / 'manifest.json')}
value = controller.first_commit_author(metadata, {})
self.assertTrue(value['authorHistoryShallow'])
self.assertEqual(value['author'], 'Later Maintainer')
def test_untracked_clone_credits_upstream_history_and_local_customization(self):
clone = pathlib.Path(self.temp.name) / 'local-clone'
clone.mkdir()
(clone / 'manifest.json').write_text(json.dumps({'author': 'Omarchy', 'omarchy': {
'clonedFrom': 'omarchy.workspaces', 'clonedAtCommit': 'b' * 40,
'customizedBy': 'Local Maintainer'}}))
metadata = {'sourceDir': str(clone), 'manifestPath': str(clone / 'manifest.json')}
with patch.object(controller, 'builtin_metadata', return_value=self.metadata):
value = controller.plugin_details(metadata, {})
self.assertEqual(value['author'], 'Original Author')
self.assertEqual(value['authorSource'], 'upstream-first-commit')
self.assertEqual(value['authorCommit'], self.original)
self.assertEqual(value['sourceCommit'], 'b' * 40)
self.assertEqual(value['customizedBy'], 'Local Maintainer')
def test_clone_without_original_history_does_not_invent_authorship(self):
(self.root / 'manifest.json').write_text(json.dumps({'author': 'Omarchy', 'omarchy': {
'clonedFrom': 'omarchy.missing', 'clonedAtCommit': 'not-a-commit'}}))
with patch.object(controller, 'first_commit_author', return_value={}), patch.object(controller, 'builtin_metadata', return_value={}):
value = controller.plugin_details(self.metadata, {})
self.assertEqual(value['author'], 'Omarchy')
self.assertNotIn('sourceCommit', value)
self.assertNotIn('authorCommit', value)
if __name__ == '__main__':
unittest.main()