- Updated `IMediaSourceCatalog` to support user-added media sources, allowing dynamic editing and management of sources. - Removed the `UrlListSource` class as its functionality is now integrated into the new catalog structure. - Enhanced `CollectOptions` to default `RequireProxy` to true, ensuring stricter handling of proxy requirements. - Improved error handling in `ParseError` to include a `Subject` field for better context on failures. - Adjusted dependency injection to reflect changes in media source management, removing old source registrations. - Introduced background proxy checks to ensure a more robust proxy pool management during collection processes. These changes streamline the media collection process and improve the overall user experience by providing clearer error reporting and more flexible source management.
5.6 KiB
5.6 KiB
Avalonia, тесты и сборка: уже оплаченные грабли
Читать перед правкой .axaml, стилей, тестовых проектов и файлов сборки.
XAML и стили
- Селектор типа матчит точный тип.
UserControl.shellне матчитShellView(наследникReactiveUserControl<T>) и молча не делает ничего — нужен:is(UserControl).shell. Голый.shellтоже матчит, но тогда XAML-компилятор не выводит тип дляSetterи падает с AVLN2200. - Style-сеттер навсегда проигрывает локальному значению. Не стилизовать
IsPaneOpenиDisplayMode— они биндятся во ViewModel. IPseudoClasses.Setтребует ведущего:.- Compiled bindings включены по умолчанию (Avalonia 12):
x:DataTypeнужен на каждомUserControlи каждомDataTemplate. {DynamicResource}с несуществующим ключом молча не срабатывает — свойство остаётся со значением по умолчанию, фон не красится, кисть прозрачная. Дважды доезжало до скриншота; ловитResourceKeyTestsв обеих темах.{l:Loc}с ключом, которого нет в обоих resx, тест паритета не поймает — файлы согласованы между собой. ЛовитLocalizationCoverageTests.
Приложение
InvariantGlobalizationобязан бытьfalse: Semi.Avalonia строитCultureInfoв статическом конструкторе и падает целиком.- Превьюер рефлексирует безпараметровый статический
BuildAvaloniaApp(): необязательный параметр ломает его вызов, вторая перегрузка —AmbiguousMatchException. - Инспектора в Avalonia 12 нет из коробки.
Avalonia.Diagnosticsзакончился на 11.3.x; DevTools живут отдельно (AvaloniaUI.DiagnosticsSupport+.WithDeveloperTools()), со своей установкой. Зависимость намеренно не добавлена.
Тесты
Avalonia.Headless.XUnit12.x — это xUnit v3, а не v2. Тестовые проекты —Exe.- Headless: ручной
Measure/Arrangeвнутри окна бесполезен — следующий проход layout окна вернёт свой размер. Задавать ширину самомуWindow. Но и без окна нельзя: у открепленного контрола не строится визуальное дерево. Execute()завершился ≠IsExecutingуже false. Второе публикуется на выходном планировщике. Тест, который сразу послеawaitдёргает команду, закрытую по чужомуIsExecuting, будет мигать под нагрузкой — ждитеCanExecute, а не предполагайте.- Проект VM-тестов не параллелится:
ReactiveUiBootstrapставит глобальные планировщики ReactiveUI, то есть тесты делят изменяемое состояние независимо от их желания.
Композиция
Dispose()страницы обязан переживать второй вызов. Каждая страница зарегистрирована дважды — своим типом и какPageViewModel, — и контейнер учитывает её как disposable по обеим регистрациям, то есть зовётDispose()два раза.GalleryViewModelотменял на втором вызове уже освобождённыйCancellationTokenSource, и приложение падало сObjectDisposedExceptionпри каждом выходе. Ловят тестыDisposing_twice_is_safe.
Сборка
- csharpier — единственный владелец форматирования (включая
.axamlи.csproj).IDE0055понижен до suggestion: два форматтера сTreatWarningsAsErrorsдерутся насмерть. Condition="'$(Configuration)' == 'Debug'"наPackageReference— ловушка.dotnet restoreвычисляется с конфигурацией по умолчанию, поэтому пакет обязан резолвиться, даже если эту конфигурацию никто не собирает. Так тут проехал мёртвыйAvalonia.Diagnostics:dotnet build -c Releaseработал, а голыйdotnet restoreпадал.- Версии пакетов централизованы в
Directory.Packages.props— никакихVersion=в csproj (иначе NU1008 на restore). TreatWarningsAsErrorsвключён; NuGet-advisory (NU19xx) выведены из ошибок, чтобы свежая CVE не роняла сборку кода, который никто не трогал.- Тестовые послабления анализаторов — в
tests/Directory.Build.props, не в самих тестах.