mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-30 05:55:53 +03:00
feat(skd-validate): проверка схемы компоновки по XSD платформы (#101)
Если в проекте есть схемы /v8-xsd-fetch, skd-validate дополнительно
проверяет порядок элементов, типы и значения по XSD версии формата
выгрузки (штамп Configuration.xml или корня внешнего отчёта). Схемы
точной версии — ошибки, только более новой — предупреждения, иначе
проверка пропускается. Места, которые платформа пишет иначе, чем
описывает XSD, отсекаются по месту нарушения: на 2606 схемах компоновки
выгрузок БП, УНФ и ERP (форматы 2.17–2.21) — ни одного срабатывания в
обоих портах.
Runner: поле кейса requires (путь от корня репозитория, нет — skipped)
и плейсхолдер {repoRoot} — кейсы на настоящих схемах, которые в
репозиторий не входят.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018dc2yLQfw6wppbopM1Y4Ps
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
9293305a12
commit
5465a7803c
@@ -12,6 +12,8 @@ allowed-tools:
|
||||
|
||||
Проверяет структурную корректность Template.xml схемы компоновки данных. Выявляет ошибки формата, битые ссылки, дубликаты имён.
|
||||
|
||||
Если в проекте есть XSD-схемы платформы (`/v8-xsd-fetch`), дополнительно проверяет порядок элементов, типы и значения по схеме версии формата выгрузки.
|
||||
|
||||
## Параметры
|
||||
|
||||
| Параметр | Обяз. | Умолч. | Описание |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# skd-validate v1.4 — Validate 1C DCS structure
|
||||
# skd-validate v1.5 — Validate 1C DCS structure
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
[CmdletBinding(PositionalBinding=$false)]
|
||||
param(
|
||||
@@ -926,6 +926,222 @@ if ($vChecked -gt 0 -and $vOk) {
|
||||
|
||||
if ($script:stopped) { & $finalize; exit 1 }
|
||||
|
||||
# --- 18. XSD (schemas of the platform, /v8-xsd-fetch) ---
|
||||
# Порядок элементов, типы и значения — по XSD платформы, если они есть в проекте. Нет схем —
|
||||
# нет проверки. Схемы XDTO совпадают с выгрузкой конфигуратора только в СКД, и то кроме
|
||||
# нескольких мест, которые платформа пишет иначе, — они отсекаются ниже (Test-XsdPlatformNoise).
|
||||
|
||||
# Копия общего эталона (семья find_v8project, авторитет — cf-edit).
|
||||
function Find-V8Project([string]$startDir) {
|
||||
$d = $startDir
|
||||
for ($i = 0; $i -lt 20 -and $d; $i++) {
|
||||
$pj = Join-Path $d ".v8-project.json"
|
||||
if (Test-Path $pj) { return $pj }
|
||||
$parent = [System.IO.Path]::GetDirectoryName($d)
|
||||
if ($parent -eq $d) { break }
|
||||
$d = $parent
|
||||
}
|
||||
return $null
|
||||
}
|
||||
|
||||
# Штамп версии формата — атрибут version КОРНЕВОГО элемента файла. Именно корневого: в Form.xml
|
||||
# расширения ниже стоит <BaseForm version=…>. Читается только заголовок, без разбора файла.
|
||||
function Get-RootVersion([string]$xmlPath) {
|
||||
if (-not (Test-Path -LiteralPath $xmlPath -PathType Leaf)) { return $null }
|
||||
$buf = New-Object byte[] 4096
|
||||
$fs = [System.IO.File]::OpenRead($xmlPath)
|
||||
try { $len = $fs.Read($buf, 0, $buf.Length) } finally { $fs.Dispose() }
|
||||
$head = [System.Text.Encoding]::UTF8.GetString($buf, 0, $len)
|
||||
$m = [regex]::Match($head, '<[A-Za-z_][\w.:-]*(\s[^>]*)?/?>')
|
||||
if (-not $m.Success) { return $null }
|
||||
$v = [regex]::Match($m.Groups[1].Value, '(?:^|\s)version="([^"]*)"')
|
||||
if ($v.Success) { return $v.Groups[1].Value }
|
||||
return $null
|
||||
}
|
||||
|
||||
# Корень автономной внешней обработки/отчёта. Копия общего эталона (семья is_external_root,
|
||||
# авторитет — cf-edit).
|
||||
function Test-ExternalObjectRoot([string]$xmlPath) {
|
||||
if (-not (Test-Path $xmlPath)) { return $false }
|
||||
try {
|
||||
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
|
||||
$el = $mx.DocumentElement.FirstChild
|
||||
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
|
||||
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
|
||||
} catch {}
|
||||
return $false
|
||||
}
|
||||
|
||||
# Якорь выгрузки, в чьём дереве лежит файл: корень автономной EPF/ERF либо Configuration.xml,
|
||||
# ближайший вверх. Корень обработки проверяется первым — иначе обработка, лежащая в дереве
|
||||
# конфигурации, сверялась бы с конфигурацией. Нет якоря — сверять не с чем.
|
||||
function Find-DumpAnchor([string]$startDir) {
|
||||
$d = $startDir
|
||||
for ($i = 0; $i -lt 15 -and $d; $i++) {
|
||||
if (Test-ExternalObjectRoot "$d.xml") { return "$d.xml" }
|
||||
$cfg = Join-Path $d "Configuration.xml"
|
||||
if (Test-Path $cfg) { return $cfg }
|
||||
$parent = [System.IO.Path]::GetDirectoryName($d)
|
||||
if (-not $parent -or $parent -eq $d) { break }
|
||||
$d = $parent
|
||||
}
|
||||
return $null
|
||||
}
|
||||
|
||||
function Get-FormatRank([string]$ver) {
|
||||
if ($ver -match '^(\d+)\.(\d+)$') { return [int]$Matches[1] * 100 + [int]$Matches[2] }
|
||||
return 0
|
||||
}
|
||||
|
||||
$xsdDcsNs = "http://v8.1c.ru/8.1/data-composition-system/schema"
|
||||
|
||||
# targetNamespace схемы — из заголовка файла, без разбора
|
||||
function Get-XsdTargetNs([string]$path) {
|
||||
$buf = New-Object byte[] 4096
|
||||
$fs = [System.IO.File]::OpenRead($path)
|
||||
try { $len = $fs.Read($buf, 0, $buf.Length) } finally { $fs.Dispose() }
|
||||
$m = [regex]::Match([System.Text.Encoding]::UTF8.GetString($buf, 0, $len), 'targetNamespace="([^"]*)"')
|
||||
if ($m.Success) { return $m.Groups[1].Value }
|
||||
return $null
|
||||
}
|
||||
|
||||
# Каталог версии годится, если в нём есть схема СКД (в 2.10–2.11 её нет)
|
||||
function Test-XsdVersionDir([string]$dir) {
|
||||
foreach ($f in Get-ChildItem -LiteralPath $dir -Filter *.xsd -File -ErrorAction SilentlyContinue) {
|
||||
if ((Get-XsdTargetNs $f.FullName) -ceq $xsdDcsNs) { return $true }
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
# Каталог схем: .v8-project.json — сначала от шаблона (проект, которому он принадлежит), потом
|
||||
# от текущего каталога; xsdPath из него, иначе .v8-xsd рядом с ним. Нет проекта — нет схем.
|
||||
function Resolve-XsdRoot([string]$templateDir) {
|
||||
$pj = Find-V8Project $templateDir
|
||||
if (-not $pj) { $pj = Find-V8Project (Get-Location).Path }
|
||||
if (-not $pj) { return $null }
|
||||
$pjDir = [System.IO.Path]::GetDirectoryName($pj)
|
||||
$rel = ".v8-xsd"
|
||||
try {
|
||||
$cfg = Get-Content -LiteralPath $pj -Raw -Encoding UTF8 | ConvertFrom-Json
|
||||
if ($cfg.xsdPath) { $rel = "$($cfg.xsdPath)" }
|
||||
} catch {}
|
||||
$dir = if ([System.IO.Path]::IsPathRooted($rel)) { $rel } else { Join-Path $pjDir $rel }
|
||||
if (Test-Path -LiteralPath $dir -PathType Container) { return $dir }
|
||||
return $null
|
||||
}
|
||||
|
||||
# Места, которые платформа пишет не так, как описывает XSD, — сверено на всех схемах компоновки
|
||||
# выгрузок БП и УНФ. Правило — по месту (элемент, родитель, xsi:type), не по тексту: текст
|
||||
# зависит от движка и языка.
|
||||
function Test-XsdPlatformNoise($info) {
|
||||
$e = $info.elem; $p = $info.parent
|
||||
if (($p -ceq 'groupTemplate' -or $p -ceq 'groupHeaderTemplate') -and ($e -ceq 'templateType' -or $e -ceq 'groupName')) { return $true }
|
||||
if ($p -ceq 'right' -and $e -ceq 'lastId') { return $true }
|
||||
if ($p -ceq 'nestedSchema' -and $e -ceq 'schema') { return $true }
|
||||
if ($info.xsiNs -ceq 'http://v8.1c.ru/8.2/data/chart') { return $true }
|
||||
# Пустое выражение параметра макета платформа не пишет, схема требует
|
||||
if ($e -ceq 'parameter' -and $info.xsiLocal -ceq 'ExpressionAreaTemplateParameter') { return $true }
|
||||
return $false
|
||||
}
|
||||
|
||||
function Invoke-XsdCheck {
|
||||
$xsdRoot = Resolve-XsdRoot ([System.IO.Path]::GetDirectoryName($resolvedPath))
|
||||
if (-not $xsdRoot) { Report-OK "XSD: no schemas in project — not checked"; return }
|
||||
$anchor = Find-DumpAnchor ([System.IO.Path]::GetDirectoryName($resolvedPath))
|
||||
$ver = if ($anchor) { Get-RootVersion $anchor } else { $null }
|
||||
if (-not $ver -or (Get-FormatRank $ver) -eq 0) { Report-OK "XSD: format version unknown (template outside a dump) — not checked"; return }
|
||||
|
||||
# Точная версия — ошибки; ближайшая более новая — предупреждения; только старше — пропуск
|
||||
$cands = @(Get-ChildItem -LiteralPath $xsdRoot -Directory |
|
||||
Where-Object { $_.Name -match '^\d+\.\d+$' -and (Get-FormatRank $_.Name) -ge (Get-FormatRank $ver) } |
|
||||
Sort-Object { Get-FormatRank $_.Name } |
|
||||
Where-Object { Test-XsdVersionDir $_.FullName })
|
||||
if ($cands.Count -eq 0) { Report-Warn "XSD: no schemas for format $ver in '$xsdRoot' — not checked"; return }
|
||||
$useDir = $cands[0].FullName
|
||||
$useVer = $cands[0].Name
|
||||
$exact = ($useVer -eq $ver)
|
||||
|
||||
# Набор схем. У import нет schemaLocation — связь по namespace, поэтому в набор кладём все.
|
||||
# Корень DataCompositionSchema в схеме объявлен как dataCompositionSchema (строчная) —
|
||||
# дописываем элемент в саму схему СКД: вторую схему того же namespace без SourceUri
|
||||
# XmlSchemaSet молча отбрасывает.
|
||||
$schemas = @()
|
||||
foreach ($f in Get-ChildItem -LiteralPath $useDir -Filter *.xsd -File) {
|
||||
$fs = [System.IO.File]::OpenRead($f.FullName)
|
||||
try { $schemas += [System.Xml.Schema.XmlSchema]::Read($fs, $null) } finally { $fs.Dispose() }
|
||||
}
|
||||
$dcs = $schemas | Where-Object { $_.TargetNamespace -ceq $xsdDcsNs } | Select-Object -First 1
|
||||
$hasRoot = $false
|
||||
foreach ($it in $dcs.Items) {
|
||||
if ($it -is [System.Xml.Schema.XmlSchemaElement] -and $it.Name -ceq 'DataCompositionSchema') { $hasRoot = $true }
|
||||
}
|
||||
if (-not $hasRoot) {
|
||||
$el = New-Object System.Xml.Schema.XmlSchemaElement
|
||||
$el.Name = 'DataCompositionSchema'
|
||||
$el.SchemaTypeName = New-Object System.Xml.XmlQualifiedName('DataCompositionSchema', $xsdDcsNs)
|
||||
[void]$dcs.Items.Add($el)
|
||||
}
|
||||
$set = New-Object System.Xml.Schema.XmlSchemaSet
|
||||
$set.XmlResolver = $null
|
||||
foreach ($sc in $schemas) { [void]$set.Add($sc) }
|
||||
try { $set.Compile() } catch { Report-Warn "XSD: schemas in '$useDir' do not compile — not checked: $($_.Exception.Message)"; return }
|
||||
|
||||
# Своя цепочка открытых элементов: в обработчике нужен родитель нарушителя
|
||||
$script:xsdStack = New-Object System.Collections.ArrayList
|
||||
$script:xsdFound = 0
|
||||
$script:xsdTag = if ($exact) { "XSD $useVer" } else { "XSD $useVer (no schemas for $ver)" }
|
||||
$script:xsdExact = $exact
|
||||
$handler = {
|
||||
param($sender, $e)
|
||||
if ($script:stopped) { return }
|
||||
$st = $script:xsdStack
|
||||
if ($sender.NodeType -eq 'Element') {
|
||||
$xt = $sender.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance")
|
||||
$info = @{ elem = $sender.LocalName; parent = $(if ($st.Count -gt 0) { $st[$st.Count - 1].name } else { '' }); xsiNs = ''; xsiLocal = '' }
|
||||
if ($xt) {
|
||||
$pp = $xt.Split(':')
|
||||
$info.xsiLocal = $pp[-1]
|
||||
if ($pp.Count -gt 1) { $info.xsiNs = "$($sender.LookupNamespace($pp[0]))" }
|
||||
}
|
||||
} else {
|
||||
$top = if ($st.Count -gt 0) { $st[$st.Count - 1] } else { @{ name = ''; xsiNs = ''; xsiLocal = '' } }
|
||||
$info = @{ elem = $top.name; parent = $(if ($st.Count -gt 1) { $st[$st.Count - 2].name } else { '' }); xsiNs = $top.xsiNs; xsiLocal = $top.xsiLocal }
|
||||
}
|
||||
if (Test-XsdPlatformNoise $info) { return }
|
||||
$script:xsdFound++
|
||||
$msg = "$($script:xsdTag), line $($e.Exception.LineNumber): $($info.parent)/$($info.elem): $($e.Message -replace '[\r\n]+', ' ')"
|
||||
if ($script:xsdExact) { Report-Error $msg } else { Report-Warn $msg }
|
||||
}
|
||||
$rs = New-Object System.Xml.XmlReaderSettings
|
||||
$rs.ValidationType = 'Schema'
|
||||
$rs.Schemas = $set
|
||||
$rs.DtdProcessing = 'Prohibit'
|
||||
$rs.add_ValidationEventHandler($handler)
|
||||
$r = [System.Xml.XmlReader]::Create($resolvedPath, $rs)
|
||||
try {
|
||||
while ($r.Read()) {
|
||||
if ($r.NodeType -eq 'Element' -and -not $r.IsEmptyElement) {
|
||||
$xt = $r.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance")
|
||||
$entry = @{ name = $r.LocalName; xsiNs = ''; xsiLocal = '' }
|
||||
if ($xt) {
|
||||
$pp = $xt.Split(':')
|
||||
$entry.xsiLocal = $pp[-1]
|
||||
if ($pp.Count -gt 1) { $entry.xsiNs = "$($r.LookupNamespace($pp[0]))" }
|
||||
}
|
||||
[void]$script:xsdStack.Add($entry)
|
||||
} elseif ($r.NodeType -eq 'EndElement' -and $script:xsdStack.Count -gt 0) {
|
||||
$script:xsdStack.RemoveAt($script:xsdStack.Count - 1)
|
||||
}
|
||||
if ($script:stopped) { break }
|
||||
}
|
||||
} finally { $r.Dispose() }
|
||||
if ($script:xsdFound -eq 0) { Report-OK "$($script:xsdTag): order, types and values OK" }
|
||||
}
|
||||
|
||||
Invoke-XsdCheck
|
||||
|
||||
if ($script:stopped) { & $finalize; exit 1 }
|
||||
|
||||
# --- Final output ---
|
||||
|
||||
& $finalize
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# skd-validate v1.4 — Validate 1C DCS structure (Python port)
|
||||
# skd-validate v1.5 — Validate 1C DCS structure (Python port)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import os
|
||||
@@ -881,6 +881,290 @@ for vn in value_nodes:
|
||||
if v_checked > 0 and v_ok:
|
||||
report_ok(f"{v_checked} <value> element(s) with xsi:type: content OK")
|
||||
|
||||
if stopped:
|
||||
finalize()
|
||||
sys.exit(1)
|
||||
|
||||
# ── 18. XSD (schemas of the platform, /v8-xsd-fetch) ──────────
|
||||
# Порядок элементов, типы и значения — по XSD платформы, если они есть в проекте. Нет схем —
|
||||
# нет проверки. Схемы XDTO совпадают с выгрузкой конфигуратора только в СКД, и то кроме
|
||||
# нескольких мест, которые платформа пишет иначе, — они отсекаются ниже (xsd_platform_noise).
|
||||
import json
|
||||
import re
|
||||
import shutil
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _sg_find_v8project(start_dir):
|
||||
d = start_dir
|
||||
for _ in range(20):
|
||||
if not d:
|
||||
break
|
||||
pj = os.path.join(d, ".v8-project.json")
|
||||
if os.path.isfile(pj):
|
||||
return pj
|
||||
parent = os.path.dirname(d)
|
||||
if parent == d:
|
||||
break
|
||||
d = parent
|
||||
return None
|
||||
|
||||
|
||||
# Штамп версии формата — атрибут version КОРНЕВОГО элемента файла. Именно корневого: в Form.xml
|
||||
# расширения ниже стоит <BaseForm version=…>. Читается только заголовок, без разбора файла.
|
||||
def root_version(xml_path):
|
||||
if not os.path.isfile(xml_path):
|
||||
return None
|
||||
with open(xml_path, "rb") as f:
|
||||
head = f.read(4096).decode("utf-8", errors="ignore")
|
||||
m = re.search(r'<[A-Za-z_][\w.:-]*(\s[^>]*)?/?>', head)
|
||||
if not m:
|
||||
return None
|
||||
v = re.search(r'(?:^|\s)version="([^"]*)"', m.group(1) or "")
|
||||
if v:
|
||||
return v.group(1)
|
||||
return None
|
||||
|
||||
|
||||
# Корень автономной внешней обработки/отчёта. Копия общего эталона (семья is_external_root,
|
||||
# авторитет — cf-edit).
|
||||
def _sg_is_external_root(xml_path):
|
||||
if not os.path.isfile(xml_path):
|
||||
return False
|
||||
try:
|
||||
mx = etree.parse(xml_path).getroot()
|
||||
for child in mx:
|
||||
if isinstance(child.tag, str):
|
||||
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
|
||||
except Exception:
|
||||
return False
|
||||
return False
|
||||
|
||||
|
||||
# Якорь выгрузки, в чьём дереве лежит файл: корень автономной EPF/ERF либо Configuration.xml,
|
||||
# ближайший вверх. Корень обработки проверяется первым — иначе обработка, лежащая в дереве
|
||||
# конфигурации, сверялась бы с конфигурацией. Нет якоря — сверять не с чем.
|
||||
def find_dump_anchor(start_dir):
|
||||
d = start_dir
|
||||
for _ in range(15):
|
||||
if not d:
|
||||
break
|
||||
if _sg_is_external_root(d + ".xml"):
|
||||
return d + ".xml"
|
||||
cfg = os.path.join(d, "Configuration.xml")
|
||||
if os.path.exists(cfg):
|
||||
return cfg
|
||||
parent = os.path.dirname(d)
|
||||
if not parent or parent == d:
|
||||
break
|
||||
d = parent
|
||||
return None
|
||||
|
||||
|
||||
def format_rank(ver):
|
||||
""""2.20" → 220, "2.9" → 209. Строковое сравнение неверно ("2.9" > "2.17")."""
|
||||
m = re.match(r'^(\d+)\.(\d+)$', ver or '')
|
||||
return int(m.group(1)) * 100 + int(m.group(2)) if m else 0
|
||||
|
||||
|
||||
XSD_DCS_NS = "http://v8.1c.ru/8.1/data-composition-system/schema"
|
||||
XS_NS = "http://www.w3.org/2001/XMLSchema"
|
||||
|
||||
|
||||
def xsd_target_ns(path):
|
||||
"""targetNamespace схемы — из заголовка файла, без разбора."""
|
||||
with open(path, "rb") as f:
|
||||
head = f.read(4096).decode("utf-8", errors="ignore")
|
||||
m = re.search(r'targetNamespace="([^"]*)"', head)
|
||||
return m.group(1) if m else None
|
||||
|
||||
|
||||
def xsd_index(vdir):
|
||||
"""namespace → файл схемы в каталоге версии."""
|
||||
idx = {}
|
||||
for name in sorted(os.listdir(vdir)):
|
||||
fp = os.path.join(vdir, name)
|
||||
if name.lower().endswith(".xsd") and os.path.isfile(fp):
|
||||
ns = xsd_target_ns(fp)
|
||||
if ns and ns not in idx:
|
||||
idx[ns] = fp
|
||||
return idx
|
||||
|
||||
|
||||
def resolve_xsd_root(template_dir):
|
||||
"""Каталог схем: .v8-project.json — сначала от шаблона (проект, которому он принадлежит),
|
||||
потом от текущего каталога; xsdPath из него, иначе .v8-xsd рядом с ним. Нет проекта — нет схем."""
|
||||
pj = _sg_find_v8project(template_dir) or _sg_find_v8project(os.getcwd())
|
||||
if not pj:
|
||||
return None
|
||||
pj_dir = os.path.dirname(pj)
|
||||
rel = ".v8-xsd"
|
||||
try:
|
||||
with open(pj, encoding="utf-8-sig") as f:
|
||||
cfg = json.load(f)
|
||||
if isinstance(cfg, dict) and cfg.get("xsdPath"):
|
||||
rel = str(cfg["xsdPath"])
|
||||
except Exception:
|
||||
pass
|
||||
d = rel if os.path.isabs(rel) else os.path.join(pj_dir, rel)
|
||||
return d if os.path.isdir(d) else None
|
||||
|
||||
|
||||
def xsd_platform_noise(info):
|
||||
"""Места, которые платформа пишет не так, как описывает XSD, — сверено на всех схемах
|
||||
компоновки выгрузок БП и УНФ. Правило — по месту (элемент, родитель, xsi:type), не по тексту:
|
||||
текст зависит от движка и языка."""
|
||||
e, p = info["elem"], info["parent"]
|
||||
if p in ("groupTemplate", "groupHeaderTemplate") and e in ("templateType", "groupName"):
|
||||
return True
|
||||
if p == "right" and e == "lastId":
|
||||
return True
|
||||
if p == "nestedSchema" and e == "schema":
|
||||
return True
|
||||
if info["xsiNs"] == "http://v8.1c.ru/8.2/data/chart":
|
||||
return True
|
||||
# Пустое выражение параметра макета платформа не пишет, схема требует
|
||||
if e == "parameter" and info["xsiLocal"] == "ExpressionAreaTemplateParameter":
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _xsd_build_schema(vdir, tmp):
|
||||
"""Схема для lxml. У import в схемах платформы нет schemaLocation, а libxml2 сам по namespace
|
||||
не ищет, — корневая схема импортирует замыкание зависимостей СКД с путями, листья первыми.
|
||||
Корень DataCompositionSchema в схеме объявлен как dataCompositionSchema (строчная) — схему
|
||||
СКД подключаем через обёртку: xs:include настоящего файла плюс элемент с нужным именем."""
|
||||
idx = xsd_index(vdir)
|
||||
order, seen = [], set()
|
||||
|
||||
def visit(ns):
|
||||
if ns in seen or ns not in idx:
|
||||
return
|
||||
seen.add(ns)
|
||||
doc = etree.parse(idx[ns])
|
||||
for imp in doc.getroot().iter("{%s}import" % XS_NS):
|
||||
visit(imp.get("namespace"))
|
||||
order.append(ns)
|
||||
|
||||
# Сначала замыкание СКД, затем остальные схемы каталога: значения в выгрузке ссылаются через
|
||||
# xsi:type на типы, которые схема СКД не импортирует (data/enterprise: LinkedValueChangeMode,
|
||||
# FoldersAndItemsUse …) — как и в PS-мастере, где в набор кладутся все схемы.
|
||||
visit(XSD_DCS_NS)
|
||||
for ns in idx:
|
||||
visit(ns)
|
||||
dcs_doc = etree.parse(idx[XSD_DCS_NS])
|
||||
has_root = any(el.get("name") == "DataCompositionSchema"
|
||||
for el in dcs_doc.getroot().findall("{%s}element" % XS_NS))
|
||||
locations = {ns: Path(idx[ns]).as_uri() for ns in order}
|
||||
if not has_root:
|
||||
wrapper = os.path.join(tmp, "dcs-root.xsd")
|
||||
with open(wrapper, "w", encoding="utf-8") as f:
|
||||
f.write('<?xml version="1.0" encoding="UTF-8"?>\n'
|
||||
'<xs:schema xmlns:xs="%s" xmlns:tns="%s" targetNamespace="%s" elementFormDefault="qualified">\n'
|
||||
' <xs:include schemaLocation="%s"/>\n'
|
||||
' <xs:element name="DataCompositionSchema" type="tns:DataCompositionSchema"/>\n'
|
||||
'</xs:schema>\n' % (XS_NS, XSD_DCS_NS, XSD_DCS_NS, locations[XSD_DCS_NS]))
|
||||
locations[XSD_DCS_NS] = Path(wrapper).as_uri()
|
||||
root = os.path.join(tmp, "root.xsd")
|
||||
with open(root, "w", encoding="utf-8") as f:
|
||||
f.write('<?xml version="1.0" encoding="UTF-8"?>\n<xs:schema xmlns:xs="%s" targetNamespace="urn:v8-xsd-root">\n' % XS_NS)
|
||||
for ns in order:
|
||||
f.write(' <xs:import namespace="%s" schemaLocation="%s"/>\n' % (ns, locations[ns]))
|
||||
f.write('</xs:schema>\n')
|
||||
return etree.XMLSchema(etree.parse(root))
|
||||
|
||||
|
||||
def _xsd_elem_info(el):
|
||||
if el is None or not isinstance(el.tag, str):
|
||||
return {"elem": "", "parent": "", "xsiNs": "", "xsiLocal": ""}
|
||||
par = el.getparent()
|
||||
info = {"elem": etree.QName(el).localname,
|
||||
"parent": etree.QName(par).localname if par is not None and isinstance(par.tag, str) else "",
|
||||
"xsiNs": "", "xsiLocal": ""}
|
||||
xt = el.get(XSI_TYPE)
|
||||
if xt:
|
||||
pp = xt.split(":")
|
||||
info["xsiLocal"] = pp[-1]
|
||||
if len(pp) > 1:
|
||||
info["xsiNs"] = el.nsmap.get(pp[0]) or ""
|
||||
return info
|
||||
|
||||
|
||||
def _xsd_error_element(err):
|
||||
"""Элемент нарушения по error.path. Путь несёт префиксы документа (dcsset:settings) — xpath
|
||||
получает их из корня; префикс, объявленный глубже, не разрешится — тогда ищем по строке и
|
||||
имени последнего шага."""
|
||||
if not err.path:
|
||||
return None
|
||||
ns = {k: v for k, v in tree.getroot().nsmap.items() if k}
|
||||
try:
|
||||
hits = tree.xpath(err.path, namespaces=ns)
|
||||
if hits and isinstance(hits[0], etree._Element):
|
||||
return hits[0]
|
||||
except Exception:
|
||||
pass
|
||||
last = re.sub(r'\[\d+\]$', '', err.path.rsplit('/', 1)[-1]).split(':')[-1]
|
||||
for el in tree.iter():
|
||||
if isinstance(el.tag, str) and el.sourceline == err.line and etree.QName(el).localname == last:
|
||||
return el
|
||||
return None
|
||||
|
||||
|
||||
def xsd_check():
|
||||
xsd_root = resolve_xsd_root(os.path.dirname(resolved_path))
|
||||
if not xsd_root:
|
||||
report_ok("XSD: no schemas in project — not checked")
|
||||
return
|
||||
anchor = find_dump_anchor(os.path.dirname(resolved_path))
|
||||
ver = root_version(anchor) if anchor else None
|
||||
if not ver or format_rank(ver) == 0:
|
||||
report_ok("XSD: format version unknown (template outside a dump) — not checked")
|
||||
return
|
||||
|
||||
# Точная версия — ошибки; ближайшая более новая — предупреждения; только старше — пропуск
|
||||
cands = sorted((d for d in os.listdir(xsd_root)
|
||||
if re.match(r'^\d+\.\d+$', d) and os.path.isdir(os.path.join(xsd_root, d))
|
||||
and format_rank(d) >= format_rank(ver)), key=format_rank)
|
||||
cands = [d for d in cands if XSD_DCS_NS in xsd_index(os.path.join(xsd_root, d))]
|
||||
if not cands:
|
||||
report_warn(f"XSD: no schemas for format {ver} in '{xsd_root}' — not checked")
|
||||
return
|
||||
use_ver = cands[0]
|
||||
exact = use_ver == ver
|
||||
|
||||
tmp = tempfile.mkdtemp(prefix="skd-xsd-")
|
||||
try:
|
||||
try:
|
||||
schema = _xsd_build_schema(os.path.join(xsd_root, use_ver), tmp)
|
||||
except Exception as ex:
|
||||
report_warn(f"XSD: schemas in '{os.path.join(xsd_root, use_ver)}' do not compile — not checked: {ex}")
|
||||
return
|
||||
finally:
|
||||
shutil.rmtree(tmp, ignore_errors=True)
|
||||
|
||||
tag = f"XSD {use_ver}" if exact else f"XSD {use_ver} (no schemas for {ver})"
|
||||
schema.validate(tree)
|
||||
found = 0
|
||||
for err in schema.error_log:
|
||||
if stopped:
|
||||
break
|
||||
el = _xsd_error_element(err)
|
||||
info = _xsd_elem_info(el)
|
||||
if xsd_platform_noise(info):
|
||||
continue
|
||||
found += 1
|
||||
msg = f"{tag}, line {err.line}: {info['parent']}/{info['elem']}: {' '.join(err.message.split())}"
|
||||
if exact:
|
||||
report_error(msg)
|
||||
else:
|
||||
report_warn(msg)
|
||||
if found == 0:
|
||||
report_ok(f"{tag}: order, types and values OK")
|
||||
|
||||
|
||||
xsd_check()
|
||||
|
||||
if stopped:
|
||||
finalize()
|
||||
sys.exit(1)
|
||||
|
||||
@@ -268,6 +268,10 @@
|
||||
[yellow-hammer/namespace-forest](https://github.com/yellow-hammer/namespace-forest). Схемы —
|
||||
собственность ООО «1С-Софт», в Git их не добавляют. Нет схем — нет проверки.
|
||||
|
||||
Схемы читает `/skd-validate`: порядок элементов, типы и значения схемы компоновки — по схемам
|
||||
версии формата выгрузки (атрибут `version` в `Configuration.xml`). Для объектов метаданных и форм
|
||||
схемы XDTO не совпадают с форматом выгрузки конфигуратора, поэтому другие валидаторы их не используют.
|
||||
|
||||
### `webUrl` — URL веб-клиента (per-database)
|
||||
|
||||
URL для открытия базы в браузере через `/web-test`. Задаётся в записи конкретной базы.
|
||||
|
||||
@@ -24,7 +24,8 @@ Exit code: 0 = все прошли, 1 = есть падения.
|
||||
### Сколько кейсов должно быть пропущено
|
||||
|
||||
`○ skipped` — норма, а не падение: кейс может гейтиться по ОС (`osOnly`), по порту
|
||||
(`runtimeOnly`) или требовать внешней выгрузки (`setup: external:`), которой на машине нет.
|
||||
(`runtimeOnly`), требовать внешней выгрузки (`setup: external:`), которой на машине нет, или
|
||||
локальных данных вне репозитория (`requires`, например XSD-схемы 1С в `.v8-xsd`).
|
||||
Но само число ни о чём не говорит, пока не с чем сверить, а запоминать его нельзя — оно растёт
|
||||
с набором кейсов.
|
||||
|
||||
@@ -402,6 +403,7 @@ ibcmd-проход автоматически `○ skipped`, если рядом
|
||||
| `noSnapshot` | нет | Непустая строка с причиной — кейс объявляет, что эталон не нужен (см. «Эталоны») |
|
||||
| `idempotent` | нет | `true` — повторный прогон с теми же аргументами должен дать байт-в-байт тот же `workDir` |
|
||||
| `runtimeOnly` | нет | `"powershell"` / `"python"` — кейс имеет смысл только на одном порте, на другом `○ skipped` |
|
||||
| `requires` | нет | Путь или массив путей от корня репозитория, без которых кейс не имеет смысла (например `".v8-xsd/2.20"` — схемы 1С не входят в репозиторий). Нет пути — `○ skipped`. В `writeFile` путь к корню — плейсхолдер `{repoRoot}` |
|
||||
| `osOnly` | нет | `"win32"` / `"darwin"` / `"linux"` — кейс работает только на этой ОС, на других `○ skipped`. Принимает и массив: `["darwin","linux"]`. Для фейка платформы **не нужен**: см. `fakePlatform` |
|
||||
| `fakePlatform` | нет | `{ "log": "…", "exit": 0 }` — кейсу нужна фейковая платформа (см. ниже) |
|
||||
| `cwd` | нет | `"workDir"` — запустить навык из рабочего каталога (нужно, если кейс кладёт туда `.v8-project.json`) |
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" version="2.11">
|
||||
<Configuration uuid="00000000-0000-0000-0000-000000000001"/>
|
||||
</MetaDataObject>
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<dataSource>
|
||||
<name>ИсточникДанных1</name>
|
||||
<dataSourceType>Local</dataSourceType>
|
||||
</dataSource>
|
||||
<dataSet xsi:type="DataSetQuery">
|
||||
<name>НаборДанных1</name>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Число</dataPath>
|
||||
<field>Число</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<presentationExpression>Формат(Число, "ЧГ=")</presentationExpression>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Флаг</dataPath>
|
||||
<field>Флаг</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ 1 КАК Число, ИСТИНА КАК Флаг</query>
|
||||
</dataSet>
|
||||
<calculatedField>
|
||||
<dataPath>Удвоенное</dataPath>
|
||||
<expression>Число * 2</expression>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<useRestriction>
|
||||
<group>true</group>
|
||||
</useRestriction>
|
||||
</calculatedField>
|
||||
<parameter>
|
||||
<name>П</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="xs:boolean">False</value>
|
||||
<useRestriction>false</useRestriction>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Основной</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:presentation>
|
||||
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Число</dcsset:field>
|
||||
</dcsset:item>
|
||||
</dcsset:selection>
|
||||
<dcsset:filter>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemComparison">
|
||||
<dcsset:left xsi:type="dcscor:Field">Флаг</dcsset:left>
|
||||
<dcsset:comparisonType>Equal</dcsset:comparisonType>
|
||||
<dcsset:right xsi:type="xs:boolean">true</dcsset:right>
|
||||
</dcsset:item>
|
||||
</dcsset:filter>
|
||||
<dcsset:outputParameters>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Заголовок</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Пример</v8:content>
|
||||
</v8:item>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
</dcsset:outputParameters>
|
||||
<dcsset:dataParameters>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>П</dcscor:parameter>
|
||||
<dcscor:value xsi:type="xs:boolean">false</dcscor:value>
|
||||
<dcsset:userSettingID>0930043f-cf2a-42c1-ae8c-4accf2fd2604</dcsset:userSettingID>
|
||||
</dcscor:item>
|
||||
</dcsset:dataParameters>
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
<dcsset:order>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemAuto"/>
|
||||
</dcsset:order>
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||
</dcsset:selection>
|
||||
</dcsset:item>
|
||||
</dcsset:settings>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" version="2.20">
|
||||
<Configuration uuid="00000000-0000-0000-0000-000000000001"/>
|
||||
</MetaDataObject>
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<dataSource>
|
||||
<name>ИсточникДанных1</name>
|
||||
<dataSourceType>Local</dataSourceType>
|
||||
</dataSource>
|
||||
<dataSet xsi:type="DataSetQuery">
|
||||
<name>НаборДанных1</name>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Число</dataPath>
|
||||
<field>Число</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<presentationExpression>Формат(Число, "ЧГ=")</presentationExpression>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Флаг</dataPath>
|
||||
<field>Флаг</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ 1 КАК Число, ИСТИНА КАК Флаг</query>
|
||||
</dataSet>
|
||||
<calculatedField>
|
||||
<dataPath>Удвоенное</dataPath>
|
||||
<expression>Число * 2</expression>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<useRestriction>
|
||||
<group>true</group>
|
||||
</useRestriction>
|
||||
</calculatedField>
|
||||
<parameter>
|
||||
<name>П</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="xs:boolean">False</value>
|
||||
<useRestriction>false</useRestriction>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Основной</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:presentation>
|
||||
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Число</dcsset:field>
|
||||
</dcsset:item>
|
||||
</dcsset:selection>
|
||||
<dcsset:filter>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemComparison">
|
||||
<dcsset:left xsi:type="dcscor:Field">Флаг</dcsset:left>
|
||||
<dcsset:comparisonType>Equal</dcsset:comparisonType>
|
||||
<dcsset:right xsi:type="xs:boolean">true</dcsset:right>
|
||||
</dcsset:item>
|
||||
</dcsset:filter>
|
||||
<dcsset:outputParameters>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Заголовок</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Пример</v8:content>
|
||||
</v8:item>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
</dcsset:outputParameters>
|
||||
<dcsset:dataParameters>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>П</dcscor:parameter>
|
||||
<dcscor:value xsi:type="xs:boolean">false</dcscor:value>
|
||||
<dcsset:userSettingID>0930043f-cf2a-42c1-ae8c-4accf2fd2604</dcsset:userSettingID>
|
||||
</dcscor:item>
|
||||
</dcsset:dataParameters>
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
<dcsset:order>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemAuto"/>
|
||||
</dcsset:order>
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||
</dcsset:selection>
|
||||
</dcsset:item>
|
||||
</dcsset:settings>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" version="2.20">
|
||||
<Configuration uuid="00000000-0000-0000-0000-000000000001"/>
|
||||
</MetaDataObject>
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<dataSource>
|
||||
<name>ИсточникДанных1</name>
|
||||
<dataSourceType>Local</dataSourceType>
|
||||
</dataSource>
|
||||
<dataSet xsi:type="DataSetQuery">
|
||||
<name>НаборДанных1</name>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Число</dataPath>
|
||||
<field>Число</field>
|
||||
<presentationExpression>Формат(Число, "ЧГ=")</presentationExpression>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Флаг</dataPath>
|
||||
<field>Флаг</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ 1 КАК Число, ИСТИНА КАК Флаг</query>
|
||||
</dataSet>
|
||||
<calculatedField>
|
||||
<dataPath>Удвоенное</dataPath>
|
||||
<expression>Число * 2</expression>
|
||||
<useRestriction>
|
||||
<group>true</group>
|
||||
</useRestriction>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</calculatedField>
|
||||
<parameter>
|
||||
<name>П</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="xs:boolean">false</value>
|
||||
<useRestriction>false</useRestriction>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Основной</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:presentation>
|
||||
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Число</dcsset:field>
|
||||
</dcsset:item>
|
||||
</dcsset:selection>
|
||||
<dcsset:filter>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemComparison">
|
||||
<dcsset:left xsi:type="dcscor:Field">Флаг</dcsset:left>
|
||||
<dcsset:comparisonType>Equal</dcsset:comparisonType>
|
||||
<dcsset:right xsi:type="xs:boolean">true</dcsset:right>
|
||||
</dcsset:item>
|
||||
</dcsset:filter>
|
||||
<dcsset:dataParameters>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>П</dcscor:parameter>
|
||||
<dcscor:value xsi:type="xs:boolean">false</dcscor:value>
|
||||
<dcsset:userSettingID>0eb70b37-3a01-40a0-81c1-98028ef06a05</dcsset:userSettingID>
|
||||
</dcscor:item>
|
||||
</dcsset:dataParameters>
|
||||
<dcsset:outputParameters>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Заголовок</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Пример</v8:content>
|
||||
</v8:item>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
</dcsset:outputParameters>
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
<dcsset:order>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemAuto"/>
|
||||
</dcsset:order>
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||
</dcsset:selection>
|
||||
</dcsset:item>
|
||||
</dcsset:settings>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<dataSource>
|
||||
<name>ИсточникДанных1</name>
|
||||
<dataSourceType>Local</dataSourceType>
|
||||
</dataSource>
|
||||
<dataSet xsi:type="DataSetQuery">
|
||||
<name>НаборДанных1</name>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Число</dataPath>
|
||||
<field>Число</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<presentationExpression>Формат(Число, "ЧГ=")</presentationExpression>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Флаг</dataPath>
|
||||
<field>Флаг</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ 1 КАК Число, ИСТИНА КАК Флаг</query>
|
||||
</dataSet>
|
||||
<calculatedField>
|
||||
<dataPath>Удвоенное</dataPath>
|
||||
<expression>Число * 2</expression>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<useRestriction>
|
||||
<group>true</group>
|
||||
</useRestriction>
|
||||
</calculatedField>
|
||||
<parameter>
|
||||
<name>П</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="xs:boolean">False</value>
|
||||
<useRestriction>false</useRestriction>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Основной</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:presentation>
|
||||
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Число</dcsset:field>
|
||||
</dcsset:item>
|
||||
</dcsset:selection>
|
||||
<dcsset:filter>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemComparison">
|
||||
<dcsset:left xsi:type="dcscor:Field">Флаг</dcsset:left>
|
||||
<dcsset:comparisonType>Equal</dcsset:comparisonType>
|
||||
<dcsset:right xsi:type="xs:boolean">true</dcsset:right>
|
||||
</dcsset:item>
|
||||
</dcsset:filter>
|
||||
<dcsset:outputParameters>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Заголовок</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Пример</v8:content>
|
||||
</v8:item>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
</dcsset:outputParameters>
|
||||
<dcsset:dataParameters>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>П</dcscor:parameter>
|
||||
<dcscor:value xsi:type="xs:boolean">false</dcscor:value>
|
||||
<dcsset:userSettingID>0930043f-cf2a-42c1-ae8c-4accf2fd2604</dcsset:userSettingID>
|
||||
</dcscor:item>
|
||||
</dcsset:dataParameters>
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
<dcsset:order>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemAuto"/>
|
||||
</dcsset:order>
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||
</dcsset:selection>
|
||||
</dcsset:item>
|
||||
</dcsset:settings>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" version="2.20">
|
||||
<Configuration uuid="00000000-0000-0000-0000-000000000001"/>
|
||||
</MetaDataObject>
|
||||
+407
@@ -0,0 +1,407 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<dataSource>
|
||||
<name>ИсточникДанных1</name>
|
||||
<dataSourceType>Local</dataSourceType>
|
||||
</dataSource>
|
||||
<dataSet xsi:type="DataSetQuery">
|
||||
<name>Тест</name>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Организация</dataPath>
|
||||
<field>Организация</field>
|
||||
<role>
|
||||
<dcscom:dimension>true</dcscom:dimension>
|
||||
</role>
|
||||
<valueType>
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:CatalogRef.Организации</v8:Type>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Номенклатура</dataPath>
|
||||
<field>Номенклатура</field>
|
||||
<role>
|
||||
<dcscom:dimension>true</dcscom:dimension>
|
||||
</role>
|
||||
<valueType>
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:CatalogRef.Номенклатура</v8:Type>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Сумма</dataPath>
|
||||
<field>Сумма</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Количество</dataPath>
|
||||
<field>Количество</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>3</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<field xsi:type="DataSetFieldField">
|
||||
<dataPath>Статус</dataPath>
|
||||
<field>Статус</field>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>0</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
</field>
|
||||
<dataSource>ИсточникДанных1</dataSource>
|
||||
<query>ВЫБРАТЬ * ИЗ Справочник.Номенклатура</query>
|
||||
</dataSet>
|
||||
<parameter>
|
||||
<name>Период</name>
|
||||
<valueType>
|
||||
<v8:Type>v8:StandardPeriod</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="v8:StandardPeriod">
|
||||
<v8:variant xsi:type="v8:StandardPeriodVariant">LastMonth</v8:variant>
|
||||
</value>
|
||||
<useRestriction>false</useRestriction>
|
||||
<denyIncompleteValues>true</denyIncompleteValues>
|
||||
<use>Always</use>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>НачалоПериода</name>
|
||||
<title xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Начало периода</v8:content>
|
||||
</v8:item>
|
||||
</title>
|
||||
<valueType>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>DateTime</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:dateTime">0001-01-01T00:00:00</value>
|
||||
<useRestriction>true</useRestriction>
|
||||
<expression>&Период.ДатаНачала</expression>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>КонецПериода</name>
|
||||
<title xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Конец периода</v8:content>
|
||||
</v8:item>
|
||||
</title>
|
||||
<valueType>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>DateTime</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:dateTime">0001-01-01T00:00:00</value>
|
||||
<useRestriction>true</useRestriction>
|
||||
<expression>&Период.ДатаОкончания</expression>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>Активные</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="xs:boolean">true</value>
|
||||
<useRestriction>false</useRestriction>
|
||||
</parameter>
|
||||
<template>
|
||||
<name>Шапка</name>
|
||||
<template xmlns:dcsat="http://v8.1c.ru/8.1/data-composition-system/area-template" xsi:type="dcsat:AreaTemplate">
|
||||
<dcsat:item xsi:type="dcsat:TableRow">
|
||||
<dcsat:tableCell>
|
||||
<dcsat:item xsi:type="dcsat:Field">
|
||||
<dcsat:value xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Орг</v8:content>
|
||||
</v8:item>
|
||||
</dcsat:value>
|
||||
</dcsat:item>
|
||||
<dcsat:appearance>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>ЦветФона</dcscor:parameter>
|
||||
<dcscor:value xmlns:d8p1="http://v8.1c.ru/8.1/data/ui/style" xsi:type="v8ui:Color">d8p1:ReportHeaderBackColor</dcscor:value>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>ЦветГраницы</dcscor:parameter>
|
||||
<dcscor:value xmlns:d8p1="http://v8.1c.ru/8.1/data/ui/style" xsi:type="v8ui:Color">d8p1:ReportLineColor</dcscor:value>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>СтильГраницы</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:Line" width="0" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">None</v8ui:style>
|
||||
</dcscor:value>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>СтильГраницы.Слева</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:Line" width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">Solid</v8ui:style>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>СтильГраницы.Сверху</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:Line" width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">Solid</v8ui:style>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>СтильГраницы.Справа</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:Line" width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">Solid</v8ui:style>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>СтильГраницы.Снизу</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:Line" width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">Solid</v8ui:style>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>Шрифт</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:Font" faceName="Arial" height="10" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>ГоризонтальноеПоложение</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:HorizontalAlign">Center</dcscor:value>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>Размещение</dcscor:parameter>
|
||||
<dcscor:value xsi:type="dcscor:DataCompositionTextPlacementType">Wrap</dcscor:value>
|
||||
</dcscor:item>
|
||||
</dcsat:appearance>
|
||||
</dcsat:tableCell>
|
||||
<dcsat:tableCell>
|
||||
<dcsat:item xsi:type="dcsat:Field">
|
||||
<dcsat:value xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Сум</v8:content>
|
||||
</v8:item>
|
||||
</dcsat:value>
|
||||
</dcsat:item>
|
||||
<dcsat:appearance>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>ЦветФона</dcscor:parameter>
|
||||
<dcscor:value xmlns:d8p1="http://v8.1c.ru/8.1/data/ui/style" xsi:type="v8ui:Color">d8p1:ReportHeaderBackColor</dcscor:value>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>ЦветГраницы</dcscor:parameter>
|
||||
<dcscor:value xmlns:d8p1="http://v8.1c.ru/8.1/data/ui/style" xsi:type="v8ui:Color">d8p1:ReportLineColor</dcscor:value>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>СтильГраницы</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:Line" width="0" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">None</v8ui:style>
|
||||
</dcscor:value>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>СтильГраницы.Слева</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:Line" width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">Solid</v8ui:style>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>СтильГраницы.Сверху</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:Line" width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">Solid</v8ui:style>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>СтильГраницы.Справа</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:Line" width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">Solid</v8ui:style>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>СтильГраницы.Снизу</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:Line" width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">Solid</v8ui:style>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>Шрифт</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:Font" faceName="Arial" height="10" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>ГоризонтальноеПоложение</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:HorizontalAlign">Center</dcscor:value>
|
||||
</dcscor:item>
|
||||
<dcscor:item>
|
||||
<dcscor:parameter>Размещение</dcscor:parameter>
|
||||
<dcscor:value xsi:type="dcscor:DataCompositionTextPlacementType">Wrap</dcscor:value>
|
||||
</dcscor:item>
|
||||
</dcsat:appearance>
|
||||
</dcsat:tableCell>
|
||||
</dcsat:item>
|
||||
</template>
|
||||
</template>
|
||||
<groupHeaderTemplate>
|
||||
<groupName>ДанныеОтчета</groupName>
|
||||
<templateType>Header</templateType>
|
||||
<template>Шапка</template>
|
||||
</groupHeaderTemplate>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Основной вариант</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:presentation>
|
||||
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Организация</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemFolder">
|
||||
<dcsset:lwsTitle>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Объёмы</v8:content>
|
||||
</v8:item>
|
||||
</dcsset:lwsTitle>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Сумма</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemField">
|
||||
<dcsset:field>Количество</dcsset:field>
|
||||
</dcsset:item>
|
||||
<dcsset:placement>Auto</dcsset:placement>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||
</dcsset:selection>
|
||||
<dcsset:filter>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemComparison">
|
||||
<dcsset:use>false</dcsset:use>
|
||||
<dcsset:left xsi:type="dcscor:Field">Организация</dcsset:left>
|
||||
<dcsset:comparisonType>Equal</dcsset:comparisonType>
|
||||
<dcsset:userSettingID>UUID-001</dcsset:userSettingID>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemGroup">
|
||||
<dcsset:groupType>OrGroup</dcsset:groupType>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemComparison">
|
||||
<dcsset:left xsi:type="dcscor:Field">Статус</dcsset:left>
|
||||
<dcsset:comparisonType>Equal</dcsset:comparisonType>
|
||||
<dcsset:right xsi:type="xs:string">Активен</dcsset:right>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemComparison">
|
||||
<dcsset:left xsi:type="dcscor:Field">Сумма</dcsset:left>
|
||||
<dcsset:comparisonType>Greater</dcsset:comparisonType>
|
||||
<dcsset:right xsi:type="xs:decimal">1000</dcsset:right>
|
||||
</dcsset:item>
|
||||
</dcsset:item>
|
||||
</dcsset:filter>
|
||||
<dcsset:dataParameters>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Период</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8:StandardPeriod">
|
||||
<v8:variant xsi:type="v8:StandardPeriodVariant">LastMonth</v8:variant>
|
||||
</dcscor:value>
|
||||
<dcsset:userSettingID>UUID-002</dcsset:userSettingID>
|
||||
</dcscor:item>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Активные</dcscor:parameter>
|
||||
<dcscor:value xsi:type="xs:boolean">true</dcscor:value>
|
||||
<dcsset:userSettingID>UUID-003</dcsset:userSettingID>
|
||||
</dcscor:item>
|
||||
</dcsset:dataParameters>
|
||||
<dcsset:order>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemField">
|
||||
<dcsset:field>Сумма</dcsset:field>
|
||||
<dcsset:orderType>Desc</dcsset:orderType>
|
||||
</dcsset:item>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemAuto"/>
|
||||
</dcsset:order>
|
||||
<dcsset:conditionalAppearance>
|
||||
<dcsset:item>
|
||||
<dcsset:selection/>
|
||||
<dcsset:filter>
|
||||
<dcsset:item xsi:type="dcsset:FilterItemComparison">
|
||||
<dcsset:left xsi:type="dcscor:Field">Сумма</dcsset:left>
|
||||
<dcsset:comparisonType>Greater</dcsset:comparisonType>
|
||||
<dcsset:right xsi:type="xs:decimal">10000</dcsset:right>
|
||||
</dcsset:item>
|
||||
</dcsset:filter>
|
||||
<dcsset:appearance>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>ЦветТекста</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8ui:Color">style:НегативныйТекстЦвет</dcscor:value>
|
||||
</dcscor:item>
|
||||
</dcsset:appearance>
|
||||
<dcsset:presentation xsi:type="xs:string">Большие суммы</dcsset:presentation>
|
||||
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||
<dcsset:userSettingID>UUID-004</dcsset:userSettingID>
|
||||
</dcsset:item>
|
||||
</dcsset:conditionalAppearance>
|
||||
<dcsset:outputParameters>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Заголовок</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8:LocalStringType">
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Сводка по организациям</v8:content>
|
||||
</v8:item>
|
||||
</dcscor:value>
|
||||
</dcscor:item>
|
||||
</dcsset:outputParameters>
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
<dcsset:groupItems>
|
||||
<dcsset:item xsi:type="dcsset:GroupItemField">
|
||||
<dcsset:field>Организация</dcsset:field>
|
||||
<dcsset:groupType>Items</dcsset:groupType>
|
||||
<dcsset:periodAdditionType>None</dcsset:periodAdditionType>
|
||||
<dcsset:periodAdditionBegin xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionBegin>
|
||||
<dcsset:periodAdditionEnd xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionEnd>
|
||||
</dcsset:item>
|
||||
</dcsset:groupItems>
|
||||
<dcsset:order>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemAuto"/>
|
||||
</dcsset:order>
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||
</dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
<dcsset:groupItems>
|
||||
<dcsset:item xsi:type="dcsset:GroupItemField">
|
||||
<dcsset:field>Номенклатура</dcsset:field>
|
||||
<dcsset:groupType>Items</dcsset:groupType>
|
||||
<dcsset:periodAdditionType>None</dcsset:periodAdditionType>
|
||||
<dcsset:periodAdditionBegin xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionBegin>
|
||||
<dcsset:periodAdditionEnd xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionEnd>
|
||||
</dcsset:item>
|
||||
</dcsset:groupItems>
|
||||
<dcsset:order>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemAuto"/>
|
||||
</dcsset:order>
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||
</dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
<dcsset:order>
|
||||
<dcsset:item xsi:type="dcsset:OrderItemAuto"/>
|
||||
</dcsset:order>
|
||||
<dcsset:selection>
|
||||
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||
</dcsset:selection>
|
||||
</dcsset:item>
|
||||
</dcsset:item>
|
||||
</dcsset:item>
|
||||
</dcsset:settings>
|
||||
</settingsVariant>
|
||||
</DataCompositionSchema>
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "XSD точной версии: нарушенный порядок и False — ошибки с местом нарушения",
|
||||
"setup": "fixture:xsd-bad-220",
|
||||
"requires": ".v8-xsd/2.20",
|
||||
"preRun": [
|
||||
{
|
||||
"writeFile": {
|
||||
"path": ".v8-project.json",
|
||||
"content": {
|
||||
"xsdPath": "{repoRoot}/.v8-xsd"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Reports/Отчет/Templates/Схема/Ext/Template.xml"
|
||||
},
|
||||
"expectError": true,
|
||||
"expect": {
|
||||
"stdoutContains": [
|
||||
"[ERROR] XSD 2.20, line 20: field/presentationExpression",
|
||||
"[ERROR] XSD 2.20, line 43: calculatedField/useRestriction",
|
||||
"[ERROR] XSD 2.20, line 52: parameter/value",
|
||||
"[ERROR] XSD 2.20, line 87: settings/dataParameters"
|
||||
]
|
||||
},
|
||||
"noSnapshot": "результат — только вывод; схемы 1С не должны попасть в эталон"
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "XSD точной версии: правильная схема проходит без строк XSD",
|
||||
"setup": "fixture:xsd-good-220",
|
||||
"requires": ".v8-xsd/2.20",
|
||||
"preRun": [
|
||||
{
|
||||
"writeFile": {
|
||||
"path": ".v8-project.json",
|
||||
"content": {
|
||||
"xsdPath": "{repoRoot}/.v8-xsd"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Reports/Отчет/Templates/Схема/Ext/Template.xml"
|
||||
},
|
||||
"args_extra": [
|
||||
"-Detailed"
|
||||
],
|
||||
"expect": {
|
||||
"stdoutContains": "[OK] XSD 2.20: order, types and values OK",
|
||||
"stdoutNotContains": [
|
||||
"[ERROR]",
|
||||
"[WARN]"
|
||||
]
|
||||
},
|
||||
"noSnapshot": "результат — только вывод"
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "Схем точной версии нет (2.11 без схемы СКД) — по ближайшей новой, нарушения предупреждениями",
|
||||
"setup": "fixture:xsd-bad-211",
|
||||
"requires": [
|
||||
".v8-xsd/2.11",
|
||||
".v8-xsd/2.12"
|
||||
],
|
||||
"preRun": [
|
||||
{
|
||||
"writeFile": {
|
||||
"path": ".v8-project.json",
|
||||
"content": {
|
||||
"xsdPath": "{repoRoot}/.v8-xsd"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Reports/Отчет/Templates/Схема/Ext/Template.xml"
|
||||
},
|
||||
"expect": {
|
||||
"stdoutContains": [
|
||||
"[WARN] XSD 2.12 (no schemas for 2.11), line 20: field/presentationExpression"
|
||||
],
|
||||
"stdoutNotContains": "[ERROR]"
|
||||
},
|
||||
"noSnapshot": "результат — только вывод"
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "Шаблон вне выгрузки — версия формата неизвестна, проверка не выполняется",
|
||||
"setup": "fixture:xsd-no-anchor",
|
||||
"preRun": [
|
||||
{
|
||||
"writeFile": {
|
||||
"path": ".v8-project.json",
|
||||
"content": {
|
||||
"xsdPath": "xsd"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"writeFile": {
|
||||
"path": "xsd/2.20/README.txt",
|
||||
"content": "каталог версии"
|
||||
}
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Template.xml"
|
||||
},
|
||||
"args_extra": [
|
||||
"-Detailed"
|
||||
],
|
||||
"expect": {
|
||||
"stdoutContains": "[OK] XSD: format version unknown (template outside a dump) — not checked",
|
||||
"stdoutNotContains": [
|
||||
"[ERROR]",
|
||||
"[WARN]"
|
||||
]
|
||||
},
|
||||
"noSnapshot": "результат — только вывод"
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "Каталога схем нет, -Detailed — строка о пропуске",
|
||||
"setup": "fixture:xsd-bad-220",
|
||||
"preRun": [
|
||||
{
|
||||
"writeFile": {
|
||||
"path": ".v8-project.json",
|
||||
"content": {
|
||||
"xsdPath": "нет-такого-каталога"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Reports/Отчет/Templates/Схема/Ext/Template.xml"
|
||||
},
|
||||
"args_extra": [
|
||||
"-Detailed"
|
||||
],
|
||||
"expect": {
|
||||
"stdoutContains": "[OK] XSD: no schemas in project — not checked",
|
||||
"stdoutNotContains": [
|
||||
"[ERROR]",
|
||||
"[WARN]"
|
||||
]
|
||||
},
|
||||
"noSnapshot": "результат — только вывод"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "Каталога схем нет — проверки нет, строк XSD в выводе нет",
|
||||
"setup": "fixture:xsd-bad-220",
|
||||
"preRun": [
|
||||
{
|
||||
"writeFile": {
|
||||
"path": ".v8-project.json",
|
||||
"content": {
|
||||
"xsdPath": "нет-такого-каталога"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Reports/Отчет/Templates/Схема/Ext/Template.xml"
|
||||
},
|
||||
"expect": {
|
||||
"stdoutContains": "=== Validation OK",
|
||||
"stdoutNotContains": "XSD"
|
||||
},
|
||||
"noSnapshot": "результат — только вывод"
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "В каталоге схем только старшие версии — предупреждение, проверка не выполняется",
|
||||
"setup": "fixture:xsd-bad-220",
|
||||
"preRun": [
|
||||
{
|
||||
"writeFile": {
|
||||
"path": ".v8-project.json",
|
||||
"content": {
|
||||
"xsdPath": "xsd"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"writeFile": {
|
||||
"path": "xsd/2.10/README.txt",
|
||||
"content": "нет схемы СКД"
|
||||
}
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Reports/Отчет/Templates/Схема/Ext/Template.xml"
|
||||
},
|
||||
"expect": {
|
||||
"stdoutContains": "[WARN] XSD: no schemas for format 2.20 in",
|
||||
"stdoutNotContains": "[ERROR]"
|
||||
},
|
||||
"noSnapshot": "результат — только вывод"
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "Места, которые платформа пишет иначе, чем XSD (templateType в groupHeaderTemplate), — не ошибка",
|
||||
"setup": "fixture:xsd-noise-220",
|
||||
"requires": ".v8-xsd/2.20",
|
||||
"preRun": [
|
||||
{
|
||||
"writeFile": {
|
||||
"path": ".v8-project.json",
|
||||
"content": {
|
||||
"xsdPath": "{repoRoot}/.v8-xsd"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"templatePath": "Reports/Отчет/Templates/Схема/Ext/Template.xml"
|
||||
},
|
||||
"args_extra": [
|
||||
"-Detailed"
|
||||
],
|
||||
"expect": {
|
||||
"stdoutContains": "[OK] XSD 2.20: order, types and values OK",
|
||||
"stdoutNotContains": [
|
||||
"[ERROR]",
|
||||
"[WARN]"
|
||||
]
|
||||
},
|
||||
"noSnapshot": "результат — только вывод"
|
||||
}
|
||||
@@ -81,7 +81,7 @@ const FAMILIES = [
|
||||
'form-info', 'meta-info', 'mxl-info', 'role-info', 'skd-info', 'subsystem-info',
|
||||
// Валидаторы отличают автономную обработку от конфигурации: тот же корень — якорь выгрузки
|
||||
// для сверки штампа версии (find_dump_anchor)
|
||||
'form-validate', 'interface-validate', 'meta-validate', 'role-validate', 'subsystem-validate'] },
|
||||
'form-validate', 'interface-validate', 'meta-validate', 'role-validate', 'skd-validate', 'subsystem-validate'] },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -93,7 +93,7 @@ const FAMILIES = [
|
||||
{ id: 'full', authority: 'cf-edit',
|
||||
consumers: ['cfe-borrow', 'db-cfe-admin', 'db-create', 'db-dump-cf', 'db-dump-dt', 'db-dump-xml',
|
||||
'db-load-cf', 'db-load-dt', 'db-load-git', 'db-load-xml', 'db-repo', 'db-run', 'db-update',
|
||||
'epf-build', 'epf-dump', 'web-publish', 'v8-xsd-fetch',
|
||||
'epf-build', 'epf-dump', 'web-publish', 'v8-xsd-fetch', 'skd-validate',
|
||||
'form-add', 'form-compile', 'form-edit', 'help-add', 'interface-edit', 'meta-compile',
|
||||
'meta-edit', 'meta-remove', 'mxl-compile', 'role-compile', 'role-edit', 'skd-compile', 'skd-edit',
|
||||
'subsystem-compile', 'subsystem-edit', 'template-add', 'xdto-compile', 'xdto-edit'] },
|
||||
@@ -130,13 +130,13 @@ const FAMILIES = [
|
||||
{
|
||||
name: 'root_version', py: 'root_version', ps1: 'Get-RootVersion',
|
||||
variants: [
|
||||
{ id: 'base', authority: 'meta-validate', consumers: ['cf-validate', 'cfe-validate', 'epf-validate', 'form-validate', 'interface-validate', 'role-validate', 'subsystem-validate'] },
|
||||
{ id: 'base', authority: 'meta-validate', consumers: ['cf-validate', 'cfe-validate', 'epf-validate', 'form-validate', 'interface-validate', 'role-validate', 'skd-validate', 'subsystem-validate'] },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'find_dump_anchor', py: 'find_dump_anchor', ps1: 'Find-DumpAnchor',
|
||||
variants: [
|
||||
{ id: 'base', authority: 'meta-validate', consumers: ['form-validate', 'interface-validate', 'role-validate', 'subsystem-validate'] },
|
||||
{ id: 'base', authority: 'meta-validate', consumers: ['form-validate', 'interface-validate', 'role-validate', 'skd-validate', 'subsystem-validate'] },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -151,7 +151,7 @@ const FAMILIES = [
|
||||
{ id: 'base', authority: 'meta-compile',
|
||||
consumers: ['cf-init', 'cf-validate', 'cfe-borrow', 'cfe-init', 'cfe-patch-method', 'cfe-validate', 'epf-build',
|
||||
'epf-init', 'epf-validate', 'erf-init', 'form-add', 'form-compile', 'form-validate',
|
||||
'meta-validate', 'mxl-compile', 'role-compile', 'role-edit', 'subsystem-compile', 'subsystem-edit',
|
||||
'meta-validate', 'mxl-compile', 'role-compile', 'role-edit', 'skd-validate', 'subsystem-compile', 'subsystem-edit',
|
||||
'template-add', 'xdto-compile'] },
|
||||
],
|
||||
},
|
||||
|
||||
@@ -22,7 +22,7 @@ const runtime = argv.includes('--runtime') ? argv[argv.indexOf('--runtime') + 1]
|
||||
const listMode = argv.includes('--list');
|
||||
const os = process.platform;
|
||||
|
||||
const reasons = { external: [], runtimeOnly: [], osOnly: [] };
|
||||
const reasons = { external: [], runtimeOnly: [], osOnly: [], requires: [] };
|
||||
|
||||
for (const skill of readdirSync(CASES)) {
|
||||
const dir = join(CASES, skill);
|
||||
@@ -38,6 +38,7 @@ for (const skill of readdirSync(CASES)) {
|
||||
// Порядок совпадает с раннером: сначала ОС, потом порт, потом фикстура.
|
||||
if (c.osOnly && ![].concat(c.osOnly).includes(os)) { reasons.osOnly.push(id); continue; }
|
||||
if (c.runtimeOnly && c.runtimeOnly !== runtime) { reasons.runtimeOnly.push(id); continue; }
|
||||
if (c.requires && ![].concat(c.requires).every(p => existsSync(join(HERE, '..', '..', p)))) { reasons.requires.push(id); continue; }
|
||||
const setup = String(c.setup || skillCfg.setup || '');
|
||||
if (setup.startsWith('external:') && !existsSync(setup.slice('external:'.length))) {
|
||||
reasons.external.push(id);
|
||||
@@ -45,7 +46,7 @@ for (const skill of readdirSync(CASES)) {
|
||||
}
|
||||
}
|
||||
|
||||
const total = reasons.external.length + reasons.runtimeOnly.length + reasons.osOnly.length;
|
||||
const total = reasons.external.length + reasons.runtimeOnly.length + reasons.osOnly.length + reasons.requires.length;
|
||||
|
||||
if (listMode) {
|
||||
for (const [key, ids] of Object.entries(reasons)) {
|
||||
@@ -58,6 +59,7 @@ if (listMode) {
|
||||
|
||||
console.log(
|
||||
`Ожидается пропущенных: ${total} [${os}, runtime: ${runtime}] ` +
|
||||
`= external ${reasons.external.length} + runtimeOnly ${reasons.runtimeOnly.length} + osOnly ${reasons.osOnly.length}`,
|
||||
`= external ${reasons.external.length} + runtimeOnly ${reasons.runtimeOnly.length} + osOnly ${reasons.osOnly.length}` +
|
||||
` + requires ${reasons.requires.length}`,
|
||||
);
|
||||
console.log('Сверить с "Skipped: N" из прогона runner.mjs с теми же --runtime.');
|
||||
|
||||
@@ -282,7 +282,7 @@ function cleanupWorkspace(ws) {
|
||||
// выбор платформы пришлось бы писать двумя копиями под osOnly.
|
||||
function substPlaceholders(s, workDir) {
|
||||
const fakePath = join(workDir, process.platform === 'win32' ? 'fake.cmd' : 'fake.sh');
|
||||
return s.replaceAll('{workDir}', workDir).replaceAll('{fakePlatform}', fakePath);
|
||||
return s.replaceAll('{workDir}', workDir).replaceAll('{fakePlatform}', fakePath).replaceAll('{repoRoot}', REPO_ROOT);
|
||||
}
|
||||
|
||||
function substDeep(value, workDir) {
|
||||
@@ -835,6 +835,13 @@ async function runCaseAsync(testCase, opts) {
|
||||
return { id: testCase.id, skill: testCase.skillDir, name: testCase.name, passed: true, skipped: true, errors: [], elapsed: '0.0s' };
|
||||
}
|
||||
|
||||
// requires: кейс опирается на локальные данные, которые в репозиторий не входят (XSD-схемы 1С
|
||||
// в .v8-xsd — их правообладатель 1С). Пути от корня репозитория; нет хотя бы одного — skipped.
|
||||
// Не external: тот отдаёт каталог на месте только для чтения, а кейсу нужно разложить свои файлы.
|
||||
if (caseData.requires && ![].concat(caseData.requires).every(p => existsSync(resolve(REPO_ROOT, p)))) {
|
||||
return { id: testCase.id, skill: testCase.skillDir, name: testCase.name, passed: true, skipped: true, errors: [], elapsed: '0.0s' };
|
||||
}
|
||||
|
||||
try {
|
||||
const skillCasesDir = join(CASES, testCase.skillDir);
|
||||
const fixturePath = ensureSetup(setupName, opts.runtime, skillCasesDir);
|
||||
|
||||
Reference in New Issue
Block a user