• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

atinc / ngx-tethys / 68ef226c-f83e-44c1-b8ed-e420a83c5d84

28 May 2025 10:31AM UTC coverage: 10.352% (-80.0%) from 90.316%
68ef226c-f83e-44c1-b8ed-e420a83c5d84

Pull #3460

circleci

pubuzhixing8
chore: xxx
Pull Request #3460: refactor(icon): migrate signal input #TINFR-1476

132 of 6823 branches covered (1.93%)

Branch coverage included in aggregate %.

10 of 14 new or added lines in 1 file covered. (71.43%)

11648 existing lines in 344 files now uncovered.

2078 of 14525 relevant lines covered (14.31%)

6.69 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/util/immutable.ts
1
import { Id } from 'ngx-tethys/types';
2
import { coerceArray, isFunction, isUndefinedOrNull } from './helpers';
3

UNCOV
4
export interface EntityAddOptions {
×
UNCOV
5
    prepend?: boolean;
×
UNCOV
6

×
UNCOV
7
    afterId?: Id;
×
8
}
9

10
export interface EntityMoveOptions {
11
    afterId?: Id;
12

13
    toIndex?: number;
14
}
15

16
export interface ProducerOptions {
17
    idKey?: string;
18
}
19

UNCOV
20
export class Producer<TEntity> {
×
UNCOV
21
    private idKey = '_id';
×
UNCOV
22

×
23
    private entities: TEntity[];
UNCOV
24

×
UNCOV
25
    constructor(entities: TEntity[], options?: ProducerOptions) {
×
UNCOV
26
        this.entities = entities || [];
×
UNCOV
27
        if (options && options.idKey) {
×
UNCOV
28
            this.idKey = options.idKey;
×
29
        }
UNCOV
30
    }
×
UNCOV
31

×
32
    /**
UNCOV
33
     * Add an entity or entities.
×
UNCOV
34
     *
×
35
     * @example
36
     * produce([users]).add(Entity);
37
     * produce([users]).add([Entity, Entity]);
UNCOV
38
     * produce([users]).add(Entity, { prepend: true });
×
39
     * produce([users]).add(Entity, { afterId: '' });
UNCOV
40
     */
×
41
    add(entity: TEntity | TEntity[], addOptions?: EntityAddOptions): TEntity[] {
42
        const addEntities = coerceArray(entity);
UNCOV
43
        if (addEntities.length === 0) {
×
UNCOV
44
            return this.entities;
×
UNCOV
45
        }
×
UNCOV
46
        if (addOptions && (addOptions.afterId || addOptions.prepend)) {
×
UNCOV
47
            if (addOptions.afterId) {
×
UNCOV
48
                const entities = [...this.entities];
×
49
                const index =
50
                    this.entities.findIndex(item => {
UNCOV
51
                        return item[this.idKey] === addOptions.afterId;
×
52
                    }) + 1;
53
                entities.splice(index, 0, ...addEntities);
UNCOV
54
                this.entities = [...entities];
×
UNCOV
55
            } else if (addOptions.prepend) {
×
UNCOV
56
                this.entities = [...addEntities, ...this.entities];
×
57
            }
58
        } else {
59
            this.entities = [...this.entities, ...addEntities];
UNCOV
60
        }
×
UNCOV
61
        return this.entities;
×
UNCOV
62
    }
×
63

64
    /**
UNCOV
65
     *
×
66
     * Update an entity or entities.
67
     *
68
     * @example
69
     * produce([users]).update(3, {
70
     *   name: 'New Name'
71
     * });
72
     *
73
     * produce([users]).update(3, entity => {
74
     *    return {
75
     *      ...entity,
UNCOV
76
     *      name: 'New Name'
×
UNCOV
77
     *    }
×
UNCOV
78
     *  });
×
UNCOV
79
     *
×
UNCOV
80
     * produce([users]).update([1,2,3], {
×
81
     *   name: 'New Name'
UNCOV
82
     * });
×
UNCOV
83
     */
×
UNCOV
84
    update(id: Id | Id[] | null, newStateFn: (entity: Readonly<TEntity>) => Partial<TEntity>): TEntity[];
×
85
    update(id: Id | Id[] | null, newState?: Partial<TEntity>): TEntity[];
UNCOV
86
    update(
×
UNCOV
87
        idsOrFn: Id | Id[] | null | Partial<TEntity> | ((entity: Readonly<TEntity>) => boolean),
×
88
        newStateOrFn?: ((entity: Readonly<TEntity>) => Partial<TEntity>) | Partial<TEntity>
89
    ): TEntity[] {
UNCOV
90
        const ids = coerceArray(idsOrFn);
×
UNCOV
91

×
92
        for (let i = 0; i < this.entities.length; i++) {
×
93
            const oldEntity = this.entities[i];
94
            if (ids.indexOf(oldEntity[this.idKey]) >= 0) {
UNCOV
95
                const newState = isFunction(newStateOrFn) ? (newStateOrFn as any)(oldEntity) : newStateOrFn;
×
UNCOV
96
                this.entities[i] = { ...(oldEntity as any), ...newState };
×
UNCOV
97
            }
×
UNCOV
98
        }
×
99
        return [...this.entities];
UNCOV
100
    }
×
UNCOV
101

×
102
    /**
103
     *
104
     * Remove one or more entities:
105
     *
UNCOV
106
     * @example
×
107
     * produce([users]).remove(5);
108
     * produce([users]).remove([1,2,3]);
109
     * produce([users]).remove(entity => entity.id === 1);
110
     */
111
    remove(id: Id | Id[]): TEntity[];
112
    remove(predicate: (entity: Readonly<TEntity>) => boolean): TEntity[];
113
    remove(idsOrFn?: Id | Id[] | ((entity: Readonly<TEntity>) => boolean)): TEntity[] {
114
        if (isFunction(idsOrFn)) {
115
            this.entities = this.entities.filter(entity => {
116
                return !(idsOrFn as any)(entity);
117
            });
118
        } else {
119
            const ids = coerceArray(idsOrFn);
120
            this.entities = this.entities.filter(entity => {
121
                return ids.indexOf(entity[this.idKey]) === -1;
122
            });
123
        }
124
        return this.entities;
125
    }
126

127
    /**
128
     *
129
     * Move one or more entities:
130
     *
131
     * @example
132
     * produce([users]).move(5, {afterId: 2});
133
     * produce([users]).move(5, {toIndex: 0});
134
     */
135
    move(id: Id, moveOptions?: EntityMoveOptions): TEntity[] {
136
        const fromIndex = this.entities.findIndex(item => item[this.idKey] === id);
137
        let toIndex = 0;
138
        const newEntities = [...this.entities];
139

140
        if (!id || fromIndex < 0) {
141
            return [...this.entities];
142
        }
143

144
        if (moveOptions) {
145
            if (!isUndefinedOrNull(moveOptions.afterId)) {
146
                toIndex = this.entities.findIndex(item => item[this.idKey] === moveOptions.afterId);
147
            } else if (moveOptions.toIndex) {
148
                toIndex = moveOptions.toIndex;
149
            }
150
        }
151
        toIndex = Math.max(0, Math.min(this.entities.length - 1, toIndex));
152
        if (toIndex === fromIndex) {
153
            return [...this.entities];
154
        } else {
155
            const target = this.entities[fromIndex];
156
            const delta = toIndex < fromIndex ? -1 : 1;
157

158
            for (let i = fromIndex; i !== toIndex; i += delta) {
159
                newEntities[i] = newEntities[i + delta];
160
            }
161
            newEntities[toIndex] = target;
162
            return [...newEntities];
163
        }
164
    }
165
}
166

167
export function produce<TEntity>(entities: TEntity[], options?: ProducerOptions) {
168
    return new Producer(entities, options);
169
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc