mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-20 09:30:59 +03:00
feat(meta-info): выводить «Представление типа» для ссылочных объектов
В шапке ссылочных объектов (справочники, документы, перечисления, ПВХ/ПВР, планы счетов, планы обмена, бизнес-процессы, задачи) теперь выводится строка «Представление типа» — имя ссылочного типа в диалогах выбора типа, с fallback ObjectPresentation -> Synonym -> Name. В режиме full дополнительно выводятся заданные сырые представления (объекта/списка и расширенные). Тесты: раннер принимает stdoutContains строкой или массивом, добавлен stdoutNotContains. Добавлены кейсы meta-info (ед.ч. ПВХ, full со всеми представлениями, fallback на синоним) и негативная проверка у регистра. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
7c9769c644
commit
b188d338f9
@@ -1,4 +1,4 @@
|
|||||||
# meta-info v1.1 — Compact summary of 1C metadata object
|
# meta-info v1.2 — Compact summary of 1C metadata object
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory=$true)][Alias('Path')][string]$ObjectPath,
|
[Parameter(Mandatory=$true)][Alias('Path')][string]$ObjectPath,
|
||||||
@@ -422,6 +422,22 @@ $objName = $props.SelectSingleNode("md:Name", $ns).InnerText
|
|||||||
$synNode = $props.SelectSingleNode("md:Synonym", $ns)
|
$synNode = $props.SelectSingleNode("md:Synonym", $ns)
|
||||||
$synonym = Get-MLText $synNode
|
$synonym = Get-MLText $synNode
|
||||||
|
|
||||||
|
# Presentations (type-choice dialogs show "Представление объекта" as the ref type name)
|
||||||
|
$objPresentation = Get-MLText $props.SelectSingleNode("md:ObjectPresentation", $ns)
|
||||||
|
$extObjPresentation = Get-MLText $props.SelectSingleNode("md:ExtendedObjectPresentation", $ns)
|
||||||
|
$listPresentation = Get-MLText $props.SelectSingleNode("md:ListPresentation", $ns)
|
||||||
|
$extListPresentation = Get-MLText $props.SelectSingleNode("md:ExtendedListPresentation", $ns)
|
||||||
|
|
||||||
|
# Reference (ref-typed) metadata objects — those with a ...Ref type
|
||||||
|
$refMdTypes = @("Catalog","Document","Enum","ChartOfAccounts","ChartOfCharacteristicTypes",
|
||||||
|
"ChartOfCalculationTypes","ExchangePlan","BusinessProcess","Task")
|
||||||
|
$isRefObject = $refMdTypes -contains $mdType
|
||||||
|
|
||||||
|
# Effective type presentation: ObjectPresentation -> Synonym -> Name
|
||||||
|
$typePresentation = if ($objPresentation) { $objPresentation }
|
||||||
|
elseif ($synonym) { $synonym }
|
||||||
|
else { $objName }
|
||||||
|
|
||||||
# --- Handle -Name drill-down ---
|
# --- Handle -Name drill-down ---
|
||||||
$drillDone = $false
|
$drillDone = $false
|
||||||
if ($Name -and $childObjs) {
|
if ($Name -and $childObjs) {
|
||||||
@@ -593,6 +609,17 @@ if (-not $drillDone) {
|
|||||||
$header += " ==="
|
$header += " ==="
|
||||||
Out $header
|
Out $header
|
||||||
|
|
||||||
|
# --- Type presentation (ref objects) ---
|
||||||
|
if ($isRefObject) {
|
||||||
|
Out "Представление типа: $typePresentation"
|
||||||
|
if ($Mode -eq "full") {
|
||||||
|
if ($objPresentation) { Out "Представление объекта: $objPresentation" }
|
||||||
|
if ($extObjPresentation) { Out "Расширенное представление объекта: $extObjPresentation" }
|
||||||
|
if ($listPresentation) { Out "Представление списка: $listPresentation" }
|
||||||
|
if ($extListPresentation) { Out "Расширенное представление списка: $extListPresentation" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# --- Mode: brief ---
|
# --- Mode: brief ---
|
||||||
if ($Mode -eq "brief") {
|
if ($Mode -eq "brief") {
|
||||||
# Attributes
|
# Attributes
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# meta-info v1.1 — Compact summary of 1C metadata object (Python port)
|
# meta-info v1.2 — Compact summary of 1C metadata object (Python port)
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
@@ -477,6 +477,21 @@ obj_name = inner_text(find(props, "md:Name"))
|
|||||||
syn_node = find(props, "md:Synonym")
|
syn_node = find(props, "md:Synonym")
|
||||||
synonym = get_ml_text(syn_node)
|
synonym = get_ml_text(syn_node)
|
||||||
|
|
||||||
|
# Presentations (type-choice dialogs show "Представление объекта" as the ref type name)
|
||||||
|
obj_presentation = get_ml_text(find(props, "md:ObjectPresentation"))
|
||||||
|
ext_obj_presentation = get_ml_text(find(props, "md:ExtendedObjectPresentation"))
|
||||||
|
list_presentation = get_ml_text(find(props, "md:ListPresentation"))
|
||||||
|
ext_list_presentation = get_ml_text(find(props, "md:ExtendedListPresentation"))
|
||||||
|
|
||||||
|
# Reference (ref-typed) metadata objects — those with a ...Ref type
|
||||||
|
ref_md_types = {"Catalog", "Document", "Enum", "ChartOfAccounts",
|
||||||
|
"ChartOfCharacteristicTypes", "ChartOfCalculationTypes",
|
||||||
|
"ExchangePlan", "BusinessProcess", "Task"}
|
||||||
|
is_ref_object = md_type in ref_md_types
|
||||||
|
|
||||||
|
# Effective type presentation: ObjectPresentation -> Synonym -> Name
|
||||||
|
type_presentation = obj_presentation or synonym or obj_name
|
||||||
|
|
||||||
# ── Handle -Name drill-down ──────────────────────────────────
|
# ── Handle -Name drill-down ──────────────────────────────────
|
||||||
|
|
||||||
drill_done = False
|
drill_done = False
|
||||||
@@ -636,6 +651,19 @@ if not drill_done:
|
|||||||
header += " ==="
|
header += " ==="
|
||||||
out(header)
|
out(header)
|
||||||
|
|
||||||
|
# Type presentation (ref objects)
|
||||||
|
if is_ref_object:
|
||||||
|
out(f"Представление типа: {type_presentation}")
|
||||||
|
if mode == "full":
|
||||||
|
if obj_presentation:
|
||||||
|
out(f"Представление объекта: {obj_presentation}")
|
||||||
|
if ext_obj_presentation:
|
||||||
|
out(f"Расширенное представление объекта: {ext_obj_presentation}")
|
||||||
|
if list_presentation:
|
||||||
|
out(f"Представление списка: {list_presentation}")
|
||||||
|
if ext_list_presentation:
|
||||||
|
out(f"Расширенное представление списка: {ext_list_presentation}")
|
||||||
|
|
||||||
if mode == "brief":
|
if mode == "brief":
|
||||||
# Attributes
|
# Attributes
|
||||||
attrs = get_attributes(child_objs) if child_objs is not None else []
|
attrs = get_attributes(child_objs) if child_objs is not None else []
|
||||||
|
|||||||
+15
-1
@@ -108,6 +108,20 @@ node tests/skills/verify-snapshots.mjs --help # полный
|
|||||||
|
|
||||||
`params` — параметры для навыка. Используются через `case.<field>` и `workPath` в `_skill.json`.
|
`params` — параметры для навыка. Используются через `case.<field>` и `workPath` в `_skill.json`.
|
||||||
|
|
||||||
|
`expect.stdoutContains` / `expect.stdoutNotContains` — строка **или массив строк**. Каждая подстрока проверяется на наличие (`stdoutContains`) или отсутствие (`stdoutNotContains`) в stdout навыка. Удобно для info-навыков: проверить, что нужная строка есть, а лишней — нет.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Представление типа у ПВХ",
|
||||||
|
"setup": "external:C:/WS/tasks/cfsrc/erp_8.3.24",
|
||||||
|
"params": { "objectPath": "ChartsOfCharacteristicTypes/ВидыСубконтоХозрасчетные" },
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": ["Представление типа: Вид субконто", "Представление объекта: Вид субконто"],
|
||||||
|
"stdoutNotContains": "Представление списка:"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### С дополнительными CLI-аргументами
|
### С дополнительными CLI-аргументами
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -175,7 +189,7 @@ node tests/skills/verify-snapshots.mjs --help # полный
|
|||||||
| `outputPath` | нет | Относительный путь для навыков с `-OutputPath` |
|
| `outputPath` | нет | Относительный путь для навыков с `-OutputPath` |
|
||||||
| `args_extra` | нет | Массив дополнительных CLI-аргументов |
|
| `args_extra` | нет | Массив дополнительных CLI-аргументов |
|
||||||
| `preRun` | нет | Массив шагов подготовки (создание объектов и т.п.) |
|
| `preRun` | нет | Массив шагов подготовки (создание объектов и т.п.) |
|
||||||
| `expect` | нет | Дополнительные проверки: `files`, `stdoutContains` |
|
| `expect` | нет | Дополнительные проверки: `files`, `stdoutContains` (строка/массив), `stdoutNotContains` (строка/массив) |
|
||||||
| `expectError` | нет | `true` или строка — ожидается ошибка |
|
| `expectError` | нет | `true` или строка — ожидается ошибка |
|
||||||
|
|
||||||
## Эталоны (snapshots)
|
## Эталоны (snapshots)
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "Представления объекта/списка/расширенные в full — БП СтатьиДвиженияДенежныхСредств",
|
||||||
|
"setup": "external:C:/WS/tasks/cfsrc/acc_8.3.24",
|
||||||
|
"params": { "objectPath": "Catalogs/СтатьиДвиженияДенежныхСредств" },
|
||||||
|
"args_extra": ["-Mode", "full"],
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": [
|
||||||
|
"Представление типа: Статья движения ден. средств",
|
||||||
|
"Представление объекта: Статья движения ден. средств",
|
||||||
|
"Расширенное представление объекта: Статья движения денежных средств",
|
||||||
|
"Представление списка: Статьи движения денежных средств"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,5 +2,8 @@
|
|||||||
"name": "Реальный регистр бухгалтерии Хозрасчетный (БП)",
|
"name": "Реальный регистр бухгалтерии Хозрасчетный (БП)",
|
||||||
"setup": "external:C:/WS/tasks/cfsrc/acc_8.3.24",
|
"setup": "external:C:/WS/tasks/cfsrc/acc_8.3.24",
|
||||||
"params": { "objectPath": "AccountingRegisters/Хозрасчетный" },
|
"params": { "objectPath": "AccountingRegisters/Хозрасчетный" },
|
||||||
"expect": { "stdoutContains": "Хозрасчетный" }
|
"expect": {
|
||||||
|
"stdoutContains": "Хозрасчетный",
|
||||||
|
"stdoutNotContains": "Представление типа:"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "Представление типа = синоним при пустом ObjectPresentation — ERP СтатьиБюджетов",
|
||||||
|
"setup": "external:C:/WS/tasks/cfsrc/erp_8.3.24",
|
||||||
|
"params": { "objectPath": "Catalogs/СтатьиБюджетов" },
|
||||||
|
"args_extra": ["-Mode", "full"],
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": "Представление типа: Статьи бюджетов",
|
||||||
|
"stdoutNotContains": "Представление объекта:"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "Представление типа (ед.ч.) у ПВХ — ERP ВидыСубконтоХозрасчетные",
|
||||||
|
"setup": "external:C:/WS/tasks/cfsrc/erp_8.3.24",
|
||||||
|
"params": { "objectPath": "ChartsOfCharacteristicTypes/ВидыСубконтоХозрасчетные" },
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": "Представление типа: Вид субконто"
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
-5
@@ -588,8 +588,17 @@ async function runCaseAsync(testCase, opts) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (caseData.expect?.stdoutContains) {
|
if (caseData.expect?.stdoutContains) {
|
||||||
if (!stdout.includes(caseData.expect.stdoutContains)) {
|
const needles = Array.isArray(caseData.expect.stdoutContains)
|
||||||
errors.push(`stdout does not contain "${caseData.expect.stdoutContains}"`);
|
? caseData.expect.stdoutContains : [caseData.expect.stdoutContains];
|
||||||
|
for (const needle of needles) {
|
||||||
|
if (!stdout.includes(needle)) errors.push(`stdout does not contain "${needle}"`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (caseData.expect?.stdoutNotContains) {
|
||||||
|
const needles = Array.isArray(caseData.expect.stdoutNotContains)
|
||||||
|
? caseData.expect.stdoutNotContains : [caseData.expect.stdoutNotContains];
|
||||||
|
for (const needle of needles) {
|
||||||
|
if (stdout.includes(needle)) errors.push(`stdout unexpectedly contains "${needle}"`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (errors.length === 0 && !caseData.expectError && !workspace.readOnly) {
|
if (errors.length === 0 && !caseData.expectError && !workspace.readOnly) {
|
||||||
@@ -754,10 +763,19 @@ function runCase(testCase, opts) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// expect.stdoutContains
|
// expect.stdoutContains / stdoutNotContains (string or array)
|
||||||
if (caseData.expect?.stdoutContains) {
|
if (caseData.expect?.stdoutContains) {
|
||||||
if (!stdout.includes(caseData.expect.stdoutContains)) {
|
const needles = Array.isArray(caseData.expect.stdoutContains)
|
||||||
errors.push(`stdout does not contain "${caseData.expect.stdoutContains}"`);
|
? caseData.expect.stdoutContains : [caseData.expect.stdoutContains];
|
||||||
|
for (const needle of needles) {
|
||||||
|
if (!stdout.includes(needle)) errors.push(`stdout does not contain "${needle}"`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (caseData.expect?.stdoutNotContains) {
|
||||||
|
const needles = Array.isArray(caseData.expect.stdoutNotContains)
|
||||||
|
? caseData.expect.stdoutNotContains : [caseData.expect.stdoutNotContains];
|
||||||
|
for (const needle of needles) {
|
||||||
|
if (stdout.includes(needle)) errors.push(`stdout unexpectedly contains "${needle}"`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user