fix: resolve remaining 19 Python test failures — 285/285 on both runtimes

Script logic fixes (PY mirroring PS1):
- skd-compile: fix (?i) regex flag placement for Python 3.11+
- mxl-compile: handle list-of-lists row format (PS1 silently ignores)
- subsystem-compile: add "objects" → "content" synonym alias
- role-compile: add "rights" → "objects" synonym alias
- meta-compile: sort HTTP/Web service method/operation iteration
- form-edit: insert ChildItems after Events/AutoCommandBar (not at end)
- mxl-compile: sort colWidthMap iteration in both PS1 and PY for
  deterministic format indices

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-03-28 20:30:45 +03:00
parent 4565808b77
commit 972cd5061d
10 changed files with 42 additions and 20 deletions
+10 -2
View File
@@ -973,8 +973,16 @@ if elements_list:
target_ci = root_ci
if target_ci is None:
# Create ChildItems section in form
target_ci = etree.SubElement(root, f"{{{FORM_NS}}}ChildItems")
# Create ChildItems section in form — insert after Events or AutoCommandBar
target_ci = etree.Element(f"{{{FORM_NS}}}ChildItems")
insert_after = root.find("f:Events", NS)
if insert_after is None:
insert_after = root.find("f:AutoCommandBar", NS)
if insert_after is not None:
idx = list(root).index(insert_after) + 1
root.insert(idx, target_ci)
else:
root.append(target_ci)
root_ci = target_ci
# Detect indent level
@@ -2000,7 +2000,7 @@ def emit_url_template(indent, tmpl_name, tmpl_def):
X(f'{indent}\t</Properties>')
if methods:
X(f'{indent}\t<ChildObjects>')
for method_name, http_method in methods.items():
for method_name, http_method in sorted(methods.items()):
method_uuid = new_uuid()
method_synonym = split_camel_case(method_name)
handler = f'{tmpl_name}{method_name}'
@@ -2051,7 +2051,7 @@ def emit_operation(indent, op_name, op_def):
X(f'{indent}\t</Properties>')
if params:
X(f'{indent}\t<ChildObjects>')
for param_name, param_def in params.items():
for param_name, param_def in sorted(params.items()):
param_uuid = new_uuid()
param_synonym = split_camel_case(param_name)
param_type = 'xs:string'
@@ -2312,7 +2312,7 @@ if obj_type == 'HTTPService':
if url_templates:
has_children = True
X('\t\t<ChildObjects>')
for tmpl_name in url_tmpl_order:
for tmpl_name in sorted(url_tmpl_order):
emit_url_template('\t\t\t', tmpl_name, url_templates[tmpl_name])
X('\t\t</ChildObjects>')
else:
@@ -2329,7 +2329,7 @@ if obj_type == 'WebService':
if operations:
has_children = True
X('\t\t<ChildObjects>')
for op_name in op_order:
for op_name in sorted(op_order):
emit_operation('\t\t\t', op_name, operations[op_name])
X('\t\t</ChildObjects>')
else:
@@ -294,7 +294,7 @@ $defaultFormatIndex = Register-Format -key $defaultFormatKey -props @{ Width = $
# 6b. Column width formats
$colFormatMap = @{} # 1-based col -> format index
foreach ($col in $colWidthMap.Keys) {
foreach ($col in ($colWidthMap.Keys | Sort-Object)) {
$w = $colWidthMap[$col]
$key = Get-FormatKey -width $w
$idx = Register-Format -key $key -props @{ Width = $w }
@@ -249,7 +249,7 @@ def main():
# 6b. Column width formats
col_format_map = {} # 1-based col -> format index
for col in col_width_map:
for col in sorted(col_width_map):
w = col_width_map[col]
key = get_format_key(width=w)
idx = register_format(key, {'Width': w})
@@ -288,6 +288,9 @@ def main():
# Pre-register all formats from areas
for area in defn['areas']:
for row in area.get('rows', []):
# Skip list-of-values shorthand rows (treated as empty rows like PS1)
if isinstance(row, list):
continue
# Skip empty row placeholder
if row.get('empty'):
continue
@@ -356,6 +359,9 @@ def main():
local_row = 0
for row in area.get('rows', []):
# List-of-values shorthand: treat as row with no properties (like PS1)
if isinstance(row, list):
row = {}
# Empty row placeholder: emit N empty rows
if row.get('empty'):
count = int(row['empty'])
@@ -1,4 +1,4 @@
# role-compile v1.1 — Compile 1C role from JSON
# role-compile v1.2 — Compile 1C role from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# role-compile v1.1 — Compile 1C role from JSON
# role-compile v1.2 — Compile 1C role from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -455,6 +455,10 @@ def main():
synonym = str(defn['synonym']) if defn.get('synonym') else role_name
comment = str(defn['comment']) if defn.get('comment') else ''
# Synonym: accept "rights" as alias for "objects"
if not defn.get('objects') and defn.get('rights'):
defn['objects'] = defn['rights']
# --- 2. Parse all object entries ---
parsed_objects = []
if defn.get('objects'):
@@ -1160,9 +1160,9 @@ def emit_order(lines, items, indent, skip_auto=False):
parts = item.split()
field = parts[0]
direction = 'Asc'
if len(parts) > 1 and re.match(r'^(?i)desc$', parts[1]):
if len(parts) > 1 and re.match(r'(?i)^desc$', parts[1]):
direction = 'Desc'
elif len(parts) > 1 and re.match(r'^(?i)asc$', parts[1]):
elif len(parts) > 1 and re.match(r'(?i)^asc$', parts[1]):
direction = 'Asc'
lines.append(f'{indent}\t<dcsset:item xsi:type="dcsset:OrderItemField">')
lines.append(f'{indent}\t\t<dcsset:field>{esc_xml(field)}</dcsset:field>')
@@ -1369,7 +1369,7 @@ def parse_structure_shorthand(s):
seg = segments[i].strip()
group = {'type': 'group'}
if re.match(r'^(?i)(details|\u0434\u0435\u0442\u0430\u043b\u0438)$', seg):
if re.match(r'(?i)^(details|\u0434\u0435\u0442\u0430\u043b\u0438)$', seg):
group['groupBy'] = []
else:
group['groupBy'] = [seg]
@@ -97,6 +97,10 @@ def main():
explanation = str(defn['explanation']) if defn.get('explanation') else ''
picture = str(defn['picture']) if defn.get('picture') else ''
# Synonym: accept "objects" as alias for "content"
if not defn.get('content') and defn.get('objects'):
defn['content'] = defn['objects']
content_items = []
if defn.get('content'):
for c in defn['content']:
@@ -14,7 +14,7 @@
<columnsItem>
<index>0</index>
<column>
<formatIndex>4</formatIndex>
<formatIndex>2</formatIndex>
</column>
</columnsItem>
<columnsItem>
@@ -38,13 +38,13 @@
<columnsItem>
<index>4</index>
<column>
<formatIndex>2</formatIndex>
<formatIndex>4</formatIndex>
</column>
</columnsItem>
<columnsItem>
<index>5</index>
<column>
<formatIndex>2</formatIndex>
<formatIndex>4</formatIndex>
</column>
</columnsItem>
</columns>
@@ -147,13 +147,13 @@
<width>20</width>
</format>
<format>
<width>30</width>
<width>10</width>
</format>
<format>
<width>40</width>
</format>
<format>
<width>10</width>
<width>30</width>
</format>
<format>
<font>0</font>
+2 -2
View File
@@ -356,8 +356,8 @@ function compareSnapshot(workDir, snapshotDir, snapshotConfig) {
file: relFile,
type: 'content',
line: diffLine,
expected: expectedLines[diffLine - 1]?.substring(0, 120),
actual: actualLines[diffLine - 1]?.substring(0, 120),
expected: expectedLines[diffLine - 1]?.substring(0, 600),
actual: actualLines[diffLine - 1]?.substring(0, 600),
});
}
}