| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /**
- * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
- * SPDX-License-Identifier: MIT
- */
- import { beforeEach, describe, expect, it } from 'vitest';
- import { toFieldArray } from '@/core/to-field-array';
- import { FormModel } from '@/core/form-model';
- import { FieldArrayModel } from '@/core/field-array-model';
- describe('toFieldArray', () => {
- let formModel: FormModel;
- let fieldArrayModel: FieldArrayModel;
- beforeEach(() => {
- formModel = new FormModel();
- formModel.init({});
- formModel.createFieldArray('users');
- fieldArrayModel = formModel.getField<FieldArrayModel>('users')!;
- });
- it('should convert FieldArrayModel to FieldArray', () => {
- const fieldArray = toFieldArray(fieldArrayModel);
- expect(fieldArray).toBeDefined();
- expect(fieldArray.name).toBe('users');
- expect(fieldArray.value === undefined || Array.isArray(fieldArray.value)).toBe(true);
- });
- it('should expose key property from model id', () => {
- const fieldArray = toFieldArray(fieldArrayModel);
- expect(fieldArray.key).toBe(fieldArrayModel.id);
- });
- it('should expose name property from model path', () => {
- const fieldArray = toFieldArray(fieldArrayModel);
- expect(fieldArray.name).toBe('users');
- expect(fieldArray.name).toBe(fieldArrayModel.path.toString());
- });
- it('should expose value property from model value', () => {
- fieldArrayModel.value = [{ name: 'Alice' }, { name: 'Bob' }];
- const fieldArray = toFieldArray(fieldArrayModel);
- expect(fieldArray.value).toEqual([{ name: 'Alice' }, { name: 'Bob' }]);
- expect(fieldArray.value).toBe(fieldArrayModel.value);
- });
- it('should update model value via onChange', () => {
- const fieldArray = toFieldArray(fieldArrayModel);
- const newValue = [{ name: 'Charlie' }];
- fieldArray.onChange(newValue);
- expect(fieldArrayModel.value).toEqual(newValue);
- expect(fieldArray.value).toEqual(newValue);
- });
- it('should map over array elements correctly', () => {
- fieldArrayModel.value = [{ name: 'Alice' }, { name: 'Bob' }];
- const fieldArray = toFieldArray(fieldArrayModel);
- const mapped = fieldArray.map((field, index) => {
- expect(field).toBeDefined();
- expect(field.name).toBe(`users.${index}`);
- return field.value;
- });
- expect(mapped).toHaveLength(2);
- expect(mapped).toEqual([{ name: 'Alice' }, { name: 'Bob' }]);
- });
- it('should append new item and return Field', () => {
- const fieldArray = toFieldArray(fieldArrayModel);
- const newItem = { name: 'Charlie' };
- const newField = fieldArray.append(newItem);
- expect(newField).toBeDefined();
- expect(newField.name).toBe('users.0');
- expect(newField.value).toEqual(newItem);
- expect(fieldArrayModel.value).toEqual([newItem]);
- });
- it('should delete item by index', () => {
- fieldArrayModel.value = [{ name: 'Alice' }, { name: 'Bob' }, { name: 'Charlie' }];
- const fieldArray = toFieldArray(fieldArrayModel);
- fieldArray.delete(1);
- expect(fieldArrayModel.value).toEqual([{ name: 'Alice' }, { name: 'Charlie' }]);
- expect(fieldArray.value).toEqual([{ name: 'Alice' }, { name: 'Charlie' }]);
- });
- it('should remove item by index (same as delete)', () => {
- fieldArrayModel.value = [{ name: 'Alice' }, { name: 'Bob' }, { name: 'Charlie' }];
- const fieldArray = toFieldArray(fieldArrayModel);
- fieldArray.remove(1);
- expect(fieldArrayModel.value).toEqual([{ name: 'Alice' }, { name: 'Charlie' }]);
- expect(fieldArray.value).toEqual([{ name: 'Alice' }, { name: 'Charlie' }]);
- });
- it('should swap items at two indices', () => {
- fieldArrayModel.value = [{ name: 'Alice' }, { name: 'Bob' }, { name: 'Charlie' }];
- const fieldArray = toFieldArray(fieldArrayModel);
- fieldArray.swap(0, 2);
- expect(fieldArrayModel.value).toEqual([
- { name: 'Charlie' },
- { name: 'Bob' },
- { name: 'Alice' },
- ]);
- expect(fieldArray.value).toEqual([{ name: 'Charlie' }, { name: 'Bob' }, { name: 'Alice' }]);
- });
- it('should move item from one index to another', () => {
- fieldArrayModel.value = [{ name: 'Alice' }, { name: 'Bob' }, { name: 'Charlie' }];
- const fieldArray = toFieldArray(fieldArrayModel);
- fieldArray.move(0, 2);
- expect(fieldArrayModel.value).toEqual([
- { name: 'Bob' },
- { name: 'Charlie' },
- { name: 'Alice' },
- ]);
- expect(fieldArray.value).toEqual([{ name: 'Bob' }, { name: 'Charlie' }, { name: 'Alice' }]);
- });
- it('should hide _fieldModel property (non-enumerable)', () => {
- const fieldArray = toFieldArray(fieldArrayModel);
- // _fieldModel should exist but not be enumerable
- expect((fieldArray as any)._fieldModel).toBe(fieldArrayModel);
- expect(Object.keys(fieldArray)).not.toContain('_fieldModel');
- });
- it('should support complex nested operations', () => {
- const fieldArray = toFieldArray(fieldArrayModel);
- // Append multiple items
- fieldArray.append({ name: 'Alice', age: 30 });
- fieldArray.append({ name: 'Bob', age: 25 });
- fieldArray.append({ name: 'Charlie', age: 35 });
- expect(fieldArray.value).toHaveLength(3);
- // Map and modify
- const names = fieldArray.map((field) => field.value.name);
- expect(names).toEqual(['Alice', 'Bob', 'Charlie']);
- // Swap
- fieldArray.swap(0, 1);
- expect(fieldArray.value[0].name).toBe('Bob');
- expect(fieldArray.value[1].name).toBe('Alice');
- // Remove
- fieldArray.remove(2);
- expect(fieldArray.value).toHaveLength(2);
- // Move
- fieldArray.move(1, 0);
- expect(fieldArray.value[0].name).toBe('Alice');
- expect(fieldArray.value[1].name).toBe('Bob');
- });
- it('should work with empty array', () => {
- const fieldArray = toFieldArray(fieldArrayModel);
- // Value might be undefined or empty array initially
- expect(fieldArray.value === undefined || Array.isArray(fieldArray.value)).toBe(true);
- const mapped = fieldArray.map((field) => field.value);
- expect(Array.isArray(mapped)).toBe(true);
- expect(mapped.length === 0 || mapped.length > 0).toBe(true);
- });
- it('should preserve reactivity through getters', () => {
- const fieldArray = toFieldArray(fieldArrayModel);
- // Initial value might be undefined or empty array
- expect(fieldArray.value === undefined || Array.isArray(fieldArray.value)).toBe(true);
- // Modify through model
- fieldArrayModel.value = [{ name: 'Alice' }];
- // Should reflect in fieldArray (getter)
- expect(fieldArray.value).toEqual([{ name: 'Alice' }]);
- // Modify through fieldArray
- fieldArray.onChange([{ name: 'Bob' }]);
- // Should reflect in model
- expect(fieldArrayModel.value).toEqual([{ name: 'Bob' }]);
- });
- });
|