Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ScalarObservable): fix issue where scalar map fired twice #1171

Merged
merged 1 commit into from
Jan 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
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
179 changes: 2 additions & 177 deletions spec/observables/ScalarObservable-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe('ScalarObservable', function () {
expect(s.value).toBe(1);
});

it('should create ScalarObservable via staic create function', function () {
it('should create ScalarObservable via static create function', function () {
var s = new ScalarObservable(1);
var r = ScalarObservable.create(1);

Expand All @@ -25,179 +25,4 @@ describe('ScalarObservable', function () {
subscriber.isUnsubscribed = true;
rxTestScheduler.flush();
});

describe('prototype.map()', function () {
it('should map to a new ScalarObservable', function () {
var s = new ScalarObservable(1);
var r = s.map(function (x) { return x + '!!!'; });
expect(r instanceof ScalarObservable).toBe(true);
expect(r.value).toBe('1!!!');
});

it('should map using a custom thisArg', function () {
var s = new ScalarObservable(1);
var foo = 42;
var selector = function (x) {
expect(this).toEqual(foo);
return x + '!!!';
};
var r = s.map(selector, 42);

expect(r instanceof ScalarObservable).toBe(true);
expect(r.value).toBe('1!!!');
});

it('should return an ErrorObservable if map errors', function () {
var s = new ScalarObservable(1);
var r = s.map(function (x) { throw 'bad!'; });
expect(r instanceof ErrorObservable).toBe(true);
expect(r.error).toBe('bad!');
});
});

describe('prototype.count()', function () {
it('should map to a new ScalarObservable of 1', function () {
var s = new ScalarObservable(1);
var r = s.count();
expect(r instanceof ScalarObservable).toBe(true);
expect(r.value).toBe(1);
});

it('should map to a new ScalarObservable of 1 if predicate matches', function () {
var s = new ScalarObservable(1);
var r = s.count(function (x) { return x === 1; });
expect(r instanceof ScalarObservable).toBe(true);
expect(r.value).toBe(1);
});

it('should map to a new ScalarObservable of 0 if predicate does not match', function () {
var s = new ScalarObservable(1);
var r = s.count(function (x) { return x === 0; });
expect(r instanceof ScalarObservable).toBe(true);
expect(r.value).toBe(0);
});

it('should map to a new ErrorObservable if predicate errors', function () {
var s = new ScalarObservable(1);
var r = s.count(function () { throw 'bad!'; });
expect(r instanceof ErrorObservable).toBe(true);
expect(r.error).toBe('bad!');
});
});

describe('prototype.filter()', function () {
it('should return itself if the filter matches its value', function () {
var s = new ScalarObservable(1);
var r = s.filter(function (x) { return x === 1; });
expect(s).toBe(r);
});

it('should filter using a custom thisArg', function () {
var s = new ScalarObservable(1);
var filterer = {
filter1: function (x) { return x > 0; },
filter2: function (x) { return x === 1; }
};

var r = s
.filter(function (x) { return this.filter1(x); }, filterer)
.filter(function (x) { return this.filter2(x); }, filterer);

expect(s).toBe(r);
});

it('should return EmptyObservable if filter does not match', function () {
var s = new ScalarObservable(1);
var r = s.filter(function (x) { return x === 0; });
expect(r instanceof EmptyObservable).toBe(true);
});

it('should map to a new ErrorObservable if predicate errors', function () {
var s = new ScalarObservable(1);
var r = s.filter(function () { throw 'bad!'; });
expect(r instanceof ErrorObservable).toBe(true);
expect(r.error).toBe('bad!');
});
});

describe('prototype.take()', function () {
it('should return itself if count > 0', function () {
var s = new ScalarObservable(1);
var r = s.take(1);
expect(s).toBe(r);
});

it('should return EmptyObservable if count === 0', function () {
var s = new ScalarObservable(1);
var r = s.take(0);
expect(r instanceof EmptyObservable).toBe(true);
});
});

describe('prototype.skip()', function () {
it('should return itself if count === 0', function () {
var s = new ScalarObservable(1);
var r = s.skip(0);
expect(s).toBe(r);
});

it('should return EmptyObservable if count > 0', function () {
var s = new ScalarObservable(1);
var r = s.skip(1);
expect(r instanceof EmptyObservable).toBe(true);
});
});

describe('prototype.reduce()', function () {
it('should return a ScalarObservable of the result if there is a seed', function () {
var s = new ScalarObservable(1);
var r = s.reduce(function (a, x) { return a + x; }, 1);
expect(r instanceof ScalarObservable).toBe(true);
expect(r.value).toBe(2);
});

it('should return itself if there is no seed', function () {
var s = new ScalarObservable(1);
var r = s.reduce(function (a, x) { return a + x; });
expect(r).toBe(s);
});

it('should return ErrorObservable if projection throws', function () {
var s = new ScalarObservable(1);
var r = s.reduce(function (a, x) { throw 'error'; }, 1);
var expected = new ErrorObservable('error');

expect(r).toEqual(expected);
});
});

describe('prototype.scan()', function () {
it('should return a ScalarObservable of the result if there is a seed', function () {
var s = new ScalarObservable(1);
var r = s.scan(function (a, x) { return a + x; }, 1);
expect(r instanceof ScalarObservable).toBe(true);
expect(r.value).toBe(2);
});

it('should return itself if there is no seed', function () {
var s = new ScalarObservable(1);
var r = s.scan(function (a, x) { return a + x; });
expect(r).toBe(s);
});

it('should return ErrorObservable if projection throws', function () {
var s = new ScalarObservable(1);
var r = s.scan(function (a, x) { throw 'error'; }, 1);
var expected = new ErrorObservable('error');

expect(r).toEqual(expected);
});
});
});

// If you uncomment this, jasmine breaks? WEIRD
// describe('reality', function () {
// it('should exist in this universe', function () {
// expect(true).toBe(true);
// });
// });
});
71 changes: 0 additions & 71 deletions src/observable/ScalarObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ import {Observable} from '../Observable';
import {Subscriber} from '../Subscriber';
import {Subscription} from '../Subscription';

import {tryCatch} from '../util/tryCatch';
import {errorObject} from '../util/errorObject';
import {ErrorObservable} from './throw';
import {EmptyObservable} from './empty';

export class ScalarObservable<T> extends Observable<T> {
static create<T>(value: T, scheduler?: Scheduler): ScalarObservable<T> {
return new ScalarObservable(value, scheduler);
Expand Down Expand Up @@ -52,69 +47,3 @@ export class ScalarObservable<T> extends Observable<T> {
}
}
}

// TypeScript is weird about class prototype member functions and instance properties touching on it's plate.
const proto = ScalarObservable.prototype;

proto.map = function <T, R>(project: (x: T, ix?: number) => R, thisArg?: any): Observable<R> {
let result = tryCatch(project).call(thisArg || this, this.value, 0);
if (result === errorObject) {
return new ErrorObservable(errorObject.e);
} else {
return new ScalarObservable(project.call(thisArg || this, this.value, 0));
}
};

proto.filter = function <T>(select: (x: T, ix?: number) => boolean, thisArg?: any): Observable<T> {
let result = tryCatch(select).call(thisArg || this, this.value, 0);
if (result === errorObject) {
return new ErrorObservable(errorObject.e);
} else if (result) {
return this;
} else {
return new EmptyObservable<T>();
}
};

proto.reduce = function <T, R>(project: (acc: R, x: T) => R, seed?: R): Observable<R> {
if (typeof seed === 'undefined') {
return <any>this;
}
let result = tryCatch(project)(seed, this.value);
if (result === errorObject) {
return new ErrorObservable(errorObject.e);
} else {
return new ScalarObservable(result);
}
};

proto.scan = function <T, R>(project: (acc: R, x: T) => R, acc?: R): Observable<R> {
return this.reduce(project, acc);
};

proto.count = function <T>(predicate?: (value: T, index: number, source: Observable<T>) => boolean): Observable<number> {
if (!predicate) {
return new ScalarObservable(1);
} else {
let result = tryCatch(predicate).call(this, this.value, 0, this);
if (result === errorObject) {
return new ErrorObservable(errorObject.e);
} else {
return new ScalarObservable(result ? 1 : 0);
}
}
};

proto.skip = function <T>(count: number): Observable<T> {
if (count > 0) {
return new EmptyObservable<T>();
}
return this;
};

proto.take = function <T>(count: number): Observable<T> {
if (count > 0) {
return this;
}
return new EmptyObservable<T>();
};