Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/parser/src/models/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ export interface CollectionMetadata<T = any> {
}

export abstract class Collection<T extends BaseModel = BaseModel, M extends Record<string, any> = {}> extends Array<T> {
static get [Symbol.species](): ArrayConstructor {
return Array;
}

constructor(
protected readonly collections: T[],
protected readonly _meta: CollectionMetadata<T> & M = {} as CollectionMetadata<T> & M,
Expand Down
42 changes: 42 additions & 0 deletions packages/parser/test/models/collection.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,46 @@ describe('Collection model', function() {
expect(d.filterBy(filter)).toEqual([]);
});
});

describe('native array methods', function() {
const createCollection = () => {
const item1 = new ItemModel({ name: 'name1' });
const item2 = new ItemModel({ name: 'name2' });
return { collection: new Model([item1, item2]), item1, item2 };
};

it('should map collection items into a plain array', function() {
const { collection } = createCollection();

const names = collection.map(item => item.name());

expect(names).toEqual(['name1', 'name2']);
expect(names).toBeInstanceOf(Array);
expect(names).not.toBeInstanceOf(Model);
});

it('should return plain arrays from filter and slice', function() {
const { collection, item1, item2 } = createCollection();

const filtered = collection.filter(item => item.name() === 'name2');
const sliced = collection.slice(0, 1);

expect(filtered).toEqual([item2]);
expect(sliced).toEqual([item1]);
expect(filtered).not.toBeInstanceOf(Model);
expect(sliced).not.toBeInstanceOf(Model);
});

it('should leave the source collection unchanged', function() {
const { collection, item1, item2 } = createCollection();

collection.map(item => item.name());
collection.filter(item => item.name() === 'name1');
collection.slice(1);

expect(collection).toBeInstanceOf(Model);
expect(collection.all()).toEqual([item1, item2]);
expect(collection.meta()).toEqual({});
});
});
});
Loading