mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
extends `applyEach` to work on objects as well, conditionally applying logic to each property of the object.
87 lines
2.9 KiB
TypeScript
87 lines
2.9 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.dev/license
|
|
*/
|
|
|
|
import {Injector, signal} from '@angular/core';
|
|
import {TestBed} from '@angular/core/testing';
|
|
import {apply, applyEach, form, required, schema} from '@angular/forms/signals';
|
|
|
|
describe('structure APIs', () => {
|
|
describe('apply', () => {
|
|
it('should maintain order when applying to child of root path', () => {
|
|
const s = schema<{a: string}>((p) => {
|
|
required(p.a, {message: 'before'});
|
|
apply(p.a, (prop) => {
|
|
required(prop, {message: 'apply'});
|
|
});
|
|
required(p.a, {message: 'after'});
|
|
});
|
|
|
|
const data = signal({a: ''});
|
|
const f = form(data, s, {injector: TestBed.inject(Injector)});
|
|
|
|
expect(f.a().errors()).toEqual([
|
|
jasmine.objectContaining({message: 'before'}),
|
|
jasmine.objectContaining({message: 'apply'}),
|
|
jasmine.objectContaining({message: 'after'}),
|
|
]);
|
|
});
|
|
|
|
it('should maintain order when applying to root path', () => {
|
|
const s = schema<{a: {b: string}}>((p) => {
|
|
required(p.a.b, {message: 'before'});
|
|
apply(p, (prop) => {
|
|
required(prop.a.b, {message: 'apply'});
|
|
});
|
|
required(p.a.b, {message: 'after'});
|
|
});
|
|
|
|
const data = signal({a: {b: ''}});
|
|
const f = form(data, s, {injector: TestBed.inject(Injector)});
|
|
|
|
expect(f.a.b().errors()).toEqual([
|
|
jasmine.objectContaining({message: 'before'}),
|
|
jasmine.objectContaining({message: 'apply'}),
|
|
jasmine.objectContaining({message: 'after'}),
|
|
]);
|
|
});
|
|
|
|
it('should apply logic to each property', () => {
|
|
const s = schema<{a: string; b: string}>((p) => {
|
|
applyEach(p, (prop) => {
|
|
required(prop, {message: 'each'});
|
|
});
|
|
});
|
|
|
|
const data = signal({a: '', b: ''});
|
|
const f = form(data, s, {injector: TestBed.inject(Injector)});
|
|
|
|
expect(f.a().errors()).toEqual([jasmine.objectContaining({message: 'each'})]);
|
|
expect(f.b().errors()).toEqual([jasmine.objectContaining({message: 'each'})]);
|
|
});
|
|
|
|
it('should merge each property logic with specific property logic', () => {
|
|
const s = schema<{a: string; b: string}>((p) => {
|
|
required(p.a, {message: 'before'});
|
|
applyEach(p, (prop) => {
|
|
required(prop, {message: 'each'});
|
|
});
|
|
required(p.a, {message: 'after'});
|
|
});
|
|
|
|
const data = signal({a: '', b: ''});
|
|
const f = form(data, s, {injector: TestBed.inject(Injector)});
|
|
|
|
expect(f.a().errors()).toEqual([
|
|
jasmine.objectContaining({message: 'before'}),
|
|
jasmine.objectContaining({message: 'each'}),
|
|
jasmine.objectContaining({message: 'after'}),
|
|
]);
|
|
expect(f.b().errors()).toEqual([jasmine.objectContaining({message: 'each'})]);
|
|
});
|
|
});
|
|
});
|