[값 삭제 버그] InspectorView 의 ComboBox SelectedItem 은 TwoWay 기본이라, 저장된 값이 Choices 에 없으면 null 로 코어스한 뒤 그 null 을 소스에 되써서 속성을 삭제했다. Label TextAlign Choices 에 Bottom* 3값이 빠져 있어, 해당 라벨을 선택하는 것만으로 발동했다(운영 활성 디자인 1,305건 census: BottomCenter 126 / BottomLeft 107 / BottomRight 16). - ContentAlignment 9값 전체로 보정 - ChoiceRowViewModel.EnsureChoice — 목록 밖 값을 표시 전에 편입(사이트 커스텀 값 방어) [기본값] PropertyDef.Default 추가. RowBinding.Get 한 곳에서만 주입하므로 Initialize(building=true) 경로를 타 Commit 이 발생하지 않는다 — 사용자가 건드리기 전까지 PropBag 에 아무것도 쓰이지 않아 왕복 무손실이 유지된다. 다중 선택 병합도 자동으로 옳아진다. 지정 대상(레거시 필드 초기값/WinForms DefaultValueAttribute 근거): TextBox.RwdRsvWrdYon=True (TextBox.vb:63, 2022-09-28 추가라 이전 서식엔 키 없음) DataTable.ExcuteQuery=True (MDataTable.vb:15) Label.TextAlign=TopLeft / TextBox.TextAlign=Left / TextBox.BorderStyle=Fixed3D Panel.BorderStyle=None / PictureBox.SizeMode=Normal / DateTimePicker.Format=Long 이게 없으면 기본 True 속성이 항상 '꺼짐'으로 보이고, 사용자가 껐다 켜는 순간 명시 False 가 기록돼 상용구 입력·데이터소스 자동 실행이 실제로 죽는다. ControlRegistryTests 신설 — Default⊆Choices, Toggle 기본값 표기, 그리고 운영 실사용 열거값이 Choices 에 전부 포함되는지(census 근거) 검사. 검증: 테스트 59/59, edit-smoke 실패 0, 전수 왕복 1,271건 diff 0/예외 0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
77 lines
3.5 KiB
C#
77 lines
3.5 KiB
C#
using SheetMe.Core.Catalog;
|
|
|
|
namespace SheetMe.Core.Tests;
|
|
|
|
/// <summary>인스펙터 속성 스키마(ControlRegistry) 불변식 테스트.</summary>
|
|
[TestClass]
|
|
public sealed class ControlRegistryTests
|
|
{
|
|
/// <summary>
|
|
/// Choice 편집기의 Default 는 반드시 자기 Choices 안에 있어야 한다.
|
|
/// 어긋나면 ComboBox 가 값을 null 로 코어스해 되쓰면서 속성을 삭제한다.
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void ChoiceDefaults_AreWithinTheirOwnChoices()
|
|
{
|
|
foreach (var descriptor in ControlRegistry.All)
|
|
{
|
|
foreach (var def in descriptor.Properties.Where(p => p.Editor == PropEditorKind.Choice && p.Default is not null))
|
|
{
|
|
Assert.IsNotNull(def.Choices, $"{descriptor.Type}.{def.Key}: Default 가 있는데 Choices 가 없습니다.");
|
|
CollectionAssert.Contains(def.Choices!, def.Default,
|
|
$"{descriptor.Type}.{def.Key}: Default('{def.Default}')가 Choices 에 없습니다.");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>Choice 가 아닌 편집기에는 선택지 개념이 없다 — Choices 를 달아두면 죽은 설정이 된다.</summary>
|
|
[TestMethod]
|
|
public void NonChoiceEditors_HaveNoChoices()
|
|
{
|
|
foreach (var descriptor in ControlRegistry.All)
|
|
{
|
|
foreach (var def in descriptor.Properties.Where(p => p.Editor != PropEditorKind.Choice))
|
|
{
|
|
Assert.IsNull(def.Choices, $"{descriptor.Type}.{def.Key}: {def.Editor} 편집기에 Choices 가 지정돼 있습니다.");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>Toggle 기본값은 "True"/"False" 만 — IsOn 이 문자열 정확 비교라 다른 표기는 조용히 꺼짐이 된다.</summary>
|
|
[TestMethod]
|
|
public void ToggleDefaults_AreCanonicalBooleanText()
|
|
{
|
|
foreach (var descriptor in ControlRegistry.All)
|
|
{
|
|
foreach (var def in descriptor.Properties.Where(p => p.Editor == PropEditorKind.Toggle && p.Default is not null))
|
|
{
|
|
Assert.IsTrue(def.Default is "True" or "False",
|
|
$"{descriptor.Type}.{def.Key}: Toggle Default 는 \"True\"/\"False\" 여야 합니다(현재 '{def.Default}').");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 운영 실사용 값이 Choices 에 전부 들어 있어야 한다(2026-08-11 활성 디자인 1,305건 census 근거).
|
|
/// 목록에서 빠진 값을 가진 컨트롤은 인스펙터에서 선택하는 것만으로 속성이 삭제된다.
|
|
/// </summary>
|
|
[TestMethod]
|
|
[DataRow("Label", "TextAlign", "TopLeft,TopCenter,MiddleLeft,MiddleCenter,MiddleRight,BottomLeft,BottomCenter,BottomRight")]
|
|
[DataRow("TextBox", "TextAlign", "Center,Right")]
|
|
[DataRow("TextBox", "BorderStyle", "None,FixedSingle")]
|
|
[DataRow("Panel", "BorderStyle", "None,FixedSingle")]
|
|
[DataRow("PictureBox", "SizeMode", "StretchImage,Zoom,AutoSize")]
|
|
[DataRow("DateTimePicker", "Format", "Custom,Time,Short")]
|
|
[DataRow("TextBox", "IsRequiredValue", "No,Yes")]
|
|
public void Choices_CoverProductionValues(string type, string key, string csvValues)
|
|
{
|
|
var def = ControlRegistry.Find(type)?.Properties.FirstOrDefault(p => p.Key == key);
|
|
Assert.IsNotNull(def, $"{type}.{key} 정의를 찾을 수 없습니다.");
|
|
foreach (var value in csvValues.Split(','))
|
|
{
|
|
CollectionAssert.Contains(def!.Choices!, value,
|
|
$"{type}.{key}: 운영에서 쓰이는 값 '{value}'가 Choices 에 없습니다.");
|
|
}
|
|
}
|
|
}
|