Skip to content

Commit

Permalink
- Support empty string, null and falsy values as key for GroupJoin
Browse files Browse the repository at this point in the history
- Support empty string and falsy values as key for Join
- moved chai typescript definition into package.json "@types/chai"
  and updated to newer version in order to use newer functionality
  • Loading branch information
barakbbn committed Jun 15, 2020
1 parent f4ccd98 commit 60aa364
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 519 deletions.
7 changes: 3 additions & 4 deletions lib/generators.ts
Expand Up @@ -212,7 +212,7 @@ export function* UnionFast<T>(first: Iterable<T>, second: Iterable<T>) {
export function* Join<T, K, R, I>(target: Iterable<T>, oKeySelect: (x: T) => K, transform: (x: T, a: any) => R, map: Map<K, Array<I>>) {
for (let value of target) {
let key = oKeySelect(value);
if (!key) continue;
if (key == null) continue;
let innerSet = map.get(key);
if (!innerSet) continue;
for (let inner of innerSet) {
Expand All @@ -226,9 +226,8 @@ export function* GroupJoin<T, K, R, I>(target: Iterable<T>, oKeySelect: (x: T) =
for (let value of target) {
let innerSet = undefined;
let key = oKeySelect(value);
if (key){
innerSet = map.get(key);
}
innerSet = map.get(key);

yield transform(value, innerSet);
}
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -78,6 +78,7 @@
"url": "https://github.com/ENikS/Linq.git"
},
"devDependencies": {
"@types/chai": "^4.2.11",
"browserify": "^16.5.0",
"chai": "^4.2.0",
"jsmin": "^1.0.1",
Expand Down
7 changes: 4 additions & 3 deletions test/data.ts
Expand Up @@ -16,13 +16,14 @@ export var jsn = [
{ id: 1, "ids": [11, 21, 31], "name": "d" },
{ id: 2, "ids": [12, 22, 32], "name": "c" },
{ id: 3, "ids": [13, 23, 33], "name": "b" },
{ id: 4, "ids": [14, 24, 34], "name": "a" }
{ id: 4, "ids": [14, 24, 34], "name": "a" },
{ id: 0, "ids": [0, 0, 0], "name": "null" }
];

export var un1 = [
{ id: 1, "name": "q" },
{ id: 2, "name": "w" },
{ id: null, "name": "n" },
{ id: null, "name": "null" },
{ id: 3, "name": "e" },
{ id: 3, "name": "e" },
{ id: 4, "name": "r" }
Expand All @@ -31,7 +32,7 @@ export var un1 = [
export var un2 = [
{ id: 3, "name": "a" },
{ id: 4, "name": "s" },
{ id: undefined, "name": "d" },
{ id: undefined, "name": "undefined" },
{ id: 5, "name": "d" },
{ id: 5, "name": "d" },
{ id: 6, "name": "f" }
Expand Down
74 changes: 32 additions & 42 deletions test/deferred.ts
Expand Up @@ -129,21 +129,15 @@ describe('Deferred Execution -', function () {
// Select

it('Select()', function () {
let array = Linq(jsn).Select((a) => a.name).ToArray();
assert.equal(array.length, 4);
assert.equal('d', array[0]);
assert.equal('c', array[1]);
assert.equal('b', array[2]);
assert.equal('a', array[3]);
const actual = Linq(jsn).Select((a) => a.name).ToArray();
const expected = jsn.map(a => a.name);
assert.sameOrderedMembers(actual, expected);
});

it('Select() - With index', function () {
let array = Linq(jsn).Select((a: any, b: any) => b).ToArray();
assert.equal(array.length, 4);
assert.equal(0, array[0]);
assert.equal(1, array[1]);
assert.equal(2, array[2]);
assert.equal(3, array[3]);
const actual = Linq(jsn).Select((a: any, b: any) => b).ToArray();
const expected = jsn.map((a: any, b: any) => b);
assert.sameOrderedMembers(actual, expected);
});


Expand Down Expand Up @@ -484,6 +478,24 @@ describe('Deferred Execution -', function () {

});

it('Join() - null key', function () {
const nullPerson: { Name: string; } = null;
const expectedPeople = people.concat(nullPerson);

const actual = Linq(expectedPeople).Join(
pets,
person => person,
pet => pet.Owner,
(person, pet) => person.Name + " - " + pet.Name).ToArray();

const expected = [].concat(...expectedPeople
.filter(person => person != null)
.map(person => pets.filter(pet => pet.Owner === person).map(pet => person.Name + " - " + pet.Name)));

assert.sameMembers(actual, expected);
});




// GroupJoin
Expand Down Expand Up @@ -637,40 +649,18 @@ describe('Deferred Execution -', function () {

it('SelectMany()', function () {

var iterable = Linq(jsn).SelectMany(a => a.ids);
var iterator = iterable[Symbol.iterator]()
assert.equal(11, iterator.next().value);
assert.equal(21, iterator.next().value);
assert.equal(31, iterator.next().value);
assert.equal(12, iterator.next().value);
assert.equal(22, iterator.next().value);
assert.equal(32, iterator.next().value);
assert.equal(13, iterator.next().value);
assert.equal(23, iterator.next().value);
assert.equal(33, iterator.next().value);
assert.equal(14, iterator.next().value);
assert.equal(24, iterator.next().value);
assert.equal(34, iterator.next().value);
assert.isTrue(iterator.next().done);
const iterable = Linq(jsn).SelectMany(a => a.ids);
const actual = [...iterable];
const expected = [].concat(...jsn.map(a => a.ids));
assert.sameOrderedMembers(actual, expected);
});

it('SelectMany() - Selector', function () {

var iterable = Linq(jsn).SelectMany(a => a.ids, (t, s) => s);
var iterator = iterable[Symbol.iterator]()
assert.equal(11, iterator.next().value);
assert.equal(21, iterator.next().value);
assert.equal(31, iterator.next().value);
assert.equal(12, iterator.next().value);
assert.equal(22, iterator.next().value);
assert.equal(32, iterator.next().value);
assert.equal(13, iterator.next().value);
assert.equal(23, iterator.next().value);
assert.equal(33, iterator.next().value);
assert.equal(14, iterator.next().value);
assert.equal(24, iterator.next().value);
assert.equal(34, iterator.next().value);
assert.isTrue(iterator.next().done);
const iterable = Linq(jsn).SelectMany(a => a.ids, (t, s) => s);
const actual = [...iterable];
const expected = [].concat(...jsn.map(a => a.ids.map(s => s)));
assert.sameOrderedMembers(actual, expected);
});

});
Expand Down
29 changes: 5 additions & 24 deletions test/ienumerable.ts
Expand Up @@ -23,31 +23,12 @@ describe('Enumerable - ', function () {

var enumerable = asEnumerable(jsn).SelectMany(a => a.ids);
var enumerator = enumerable.GetEnumerator();
const expected = [].concat(...jsn.map(a => a.ids));
for(const exp of expected) {
assert.isTrue(enumerator.MoveNext());
assert.equal(exp, enumerator.Current);
}

assert.isTrue(enumerator.MoveNext());
assert.equal(11, enumerator.Current);
assert.isTrue(enumerator.MoveNext());
assert.equal(21, enumerator.Current);
assert.isTrue(enumerator.MoveNext());
assert.equal(31, enumerator.Current);
assert.isTrue(enumerator.MoveNext());
assert.equal(12, enumerator.Current);
assert.isTrue(enumerator.MoveNext());
assert.equal(22, enumerator.Current);
assert.isTrue(enumerator.MoveNext());
assert.equal(32, enumerator.Current);
assert.isTrue(enumerator.MoveNext());
assert.equal(13, enumerator.Current);
assert.isTrue(enumerator.MoveNext());
assert.equal(23, enumerator.Current);
assert.isTrue(enumerator.MoveNext());
assert.equal(33, enumerator.Current);
assert.isTrue(enumerator.MoveNext());
assert.equal(14, enumerator.Current);
assert.isTrue(enumerator.MoveNext());
assert.equal(24, enumerator.Current);
assert.isTrue(enumerator.MoveNext());
assert.equal(34, enumerator.Current);
assert.isFalse(enumerator.MoveNext());
});

Expand Down
5 changes: 3 additions & 2 deletions test/immediate.ts
Expand Up @@ -75,7 +75,8 @@ describe('Immediate Execution -', function () {
});

it('Average()', function () {
assert.equal((1+2+3+4)/4, Linq.From(jsn).Average(o => o.id));
const expectedAvg = jsn.reduce((sum, o)=>sum+o.id, 0) / jsn.length;
assert.equal(Linq.From(jsn).Average(o => o.id), expectedAvg);
});


Expand Down Expand Up @@ -137,7 +138,7 @@ describe('Immediate Execution -', function () {
});

it('Min()', function () {
assert.equal(1, Linq.From(jsn).Min(o => o.id));
assert.equal(Math.min(...jsn.map(o => o.id)), Linq.From(jsn).Min(o => o.id));
});

it('Min() - Empty', function () {
Expand Down
22 changes: 8 additions & 14 deletions test/nogen.ts
Expand Up @@ -107,13 +107,10 @@ describe('Custom Iterator based -', function () {
});

it('OrderBy() - Selector', function () {
var iterable = asEnumerable(jsn).OrderBy(a => a.name);
var iterator = iterable[Symbol.iterator]()
assert.equal("a", iterator.next().value.name);
assert.equal("b", iterator.next().value.name);
assert.equal("c", iterator.next().value.name);
assert.equal("d", iterator.next().value.name);
assert.isTrue(iterator.next().done);
const iterable = asEnumerable(jsn).OrderBy(a => a.name);
const actual = [...iterable];
const expected = jsn.sort((a,b) => a.name.localeCompare(b.name));
assert.sameOrderedMembers(actual, expected);
});

it('OrderBy() - Comparator', function () {
Expand Down Expand Up @@ -152,13 +149,10 @@ describe('Custom Iterator based -', function () {
});

it('OrderByDescending() - Selector', function () {
var citerable = asEnumerable(jsn).OrderByDescending(a => a.name);
var citerator = citerable[Symbol.iterator]()
assert.equal("d", citerator.next().value.name);
assert.equal("c", citerator.next().value.name);
assert.equal("b", citerator.next().value.name);
assert.equal("a", citerator.next().value.name);
assert.isTrue(citerator.next().done);
const iterable = asEnumerable(jsn).OrderByDescending(a => a.name);
const actual = [...iterable];
const expected = jsn.sort((a,b) => a.name.localeCompare(b.name)).reverse();
assert.sameOrderedMembers(actual, expected);
});

it('OrderByDescending() - Key', function () {
Expand Down
55 changes: 13 additions & 42 deletions test/reentrancy.ts
Expand Up @@ -95,19 +95,13 @@ describe('Reentrancy -', function () {

it('Select()', function () {
var iterable = asEnumerable(jsn).Select((a) => a.name);
var iterator = iterable[Symbol.iterator]()
assert.equal(iterator.next().value, 'd');
assert.equal(iterator.next().value, 'c');
assert.equal(iterator.next().value, 'b');
assert.equal(iterator.next().value, 'a');
assert.isTrue(iterator.next().done);

iterator = iterable[Symbol.iterator]()
assert.equal(iterator.next().value, 'd');
assert.equal(iterator.next().value, 'c');
assert.equal(iterator.next().value, 'b');
assert.equal(iterator.next().value, 'a');
assert.isTrue(iterator.next().done);
const actual = [...iterable];
const expected = [].concat(...jsn.map(a => a.name));
assert.sameOrderedMembers(actual, expected);

const actualReentrant = [...iterable];
assert.sameOrderedMembers(actualReentrant, expected);
});


Expand Down Expand Up @@ -409,38 +403,15 @@ describe('Reentrancy -', function () {


it('SelectMany()', function () {

var iterable = asEnumerable(jsn).SelectMany(a => a.ids);
var iterator = iterable[Symbol.iterator]()
assert.equal(11, iterator.next().value);
assert.equal(21, iterator.next().value);
assert.equal(31, iterator.next().value);
assert.equal(12, iterator.next().value);
assert.equal(22, iterator.next().value);
assert.equal(32, iterator.next().value);
assert.equal(13, iterator.next().value);
assert.equal(23, iterator.next().value);
assert.equal(33, iterator.next().value);
assert.equal(14, iterator.next().value);
assert.equal(24, iterator.next().value);
assert.equal(34, iterator.next().value);
assert.isTrue(iterator.next().done);

iterator = iterable[Symbol.iterator]()
assert.equal(11, iterator.next().value);
assert.equal(21, iterator.next().value);
assert.equal(31, iterator.next().value);
assert.equal(12, iterator.next().value);
assert.equal(22, iterator.next().value);
assert.equal(32, iterator.next().value);
assert.equal(13, iterator.next().value);
assert.equal(23, iterator.next().value);
assert.equal(33, iterator.next().value);
assert.equal(14, iterator.next().value);
assert.equal(24, iterator.next().value);
assert.equal(34, iterator.next().value);
assert.isTrue(iterator.next().done);
});
const actual = [...iterable];
const expected = [].concat(...jsn.map(a => a.ids));
assert.sameOrderedMembers(actual, expected);

const actualReentrant = [...iterable];
assert.sameOrderedMembers(actualReentrant, expected);
});


it('Concat()', function () {
Expand Down

0 comments on commit 60aa364

Please sign in to comment.