describe('Observer', function() describe('create', function() local function expectObserverToBeInCleanStateAndValid(observer) expect(observer).to.be.an(Rx.Observer) expect(observer.stopped).to.equal(false) end it('works when no parameters is passed', function() local observer = Rx.Observer.create() expectObserverToBeInCleanStateAndValid(observer) end) it('works when onNext callback parameter is passed', function() local observer = Rx.Observer.create(function() end) expectObserverToBeInCleanStateAndValid(observer) end) it('works when onError callback parameter is passed', function() local observer = Rx.Observer.create(nil, function() end) expectObserverToBeInCleanStateAndValid(observer) end) it('works when onComplete callback parameter is passed', function() local observer = Rx.Observer.create(nil, nil, function() end) expectObserverToBeInCleanStateAndValid(observer) end) it('works when all callback parameters are passed', function() local observer = Rx.Observer.create(function() end, function() end, function() end) expectObserverToBeInCleanStateAndValid(observer) end) end) describe('onNext', function() it('calls custom onNext callback if it was provided', function() local onNext = spy() local observer = Rx.Observer.create(onNext, nil, nil) observer:onNext() expect(#onNext).to.equal(1) end) it('passes all arguments to custom onNext callback if it was provided', function() local onNext = spy() local observer = Rx.Observer.create(onNext, nil, nil) observer:onNext(1, '2', 3, nil, 5, { key = 6 }) expect(onNext).to.equal({{1, '2', 3, nil, 5, { key = 6 }}}) end) it('works and does not error when custom onNext callback was not provided', function() local observer = Rx.Observer.create() local errors = {} -- would gladly use something like to_not.fail() here but it's -- not quite good with producing useful error messages local success = tryCall(function() observer:onNext() end, errors) tryCall(function() expect(success).to.equal(true) end, errors) throwErrorsIfAny(errors) end) describe('does not call custom onError callback', function() it('if observer already received completion notification', function() local onNext = spy() local observer = Rx.Observer.create(onNext, nil, nil) observer:onCompleted() observer:onNext() expect(#onNext).to.equal(0) end) it('if observer already received error notification', function() local onNext = spy() local observer = Rx.Observer.create(onNext, nil, nil) observer:onCompleted() observer:onNext() expect(#onNext).to.equal(0) end) end) end) describe('onError', function() it('causes an error by default if custom onError callback was not provided', function() local observer = Rx.Observer.create() expect(function() observer:onError() end).to.fail() end) it('calls custom onError callback if it was provided', function() local onError = spy() local observer = Rx.Observer.create(nil, onError, nil) observer:onError() expect(#onError).to.equal(1) end) it('passes first value from error notification to custom onError callback', function() local onError = spy() local observer = Rx.Observer.create(nil, onError, nil) observer:onError("err msg", "excessive arg", 1) expect(onError).to.equal({{"err msg"}}) end) it('marks observer as stopped', function() local observer = Rx.Observer.create(nil, function() end, nil) observer:onError() expect(observer.stopped).to.equal(true) end) describe('does not call custom onError callback', function() it('if observer already received completion notification', function() local onError = spy() local observer = Rx.Observer.create(nil, onError, nil) observer:onCompleted() observer:onError() expect(#onError).to.equal(0) end) it('if observer already received error notification', function() local spyEnabled = false local onError = spy() local observer = Rx.Observer.create(nil, function() if spyEnabled then onError() end end, nil) observer:onError() spyEnabled = true observer:onError() expect(#onError).to.equal(0) end) end) end) describe('onCompleted', function() it('calls custom onCompleted callback if it was provided', function() local onCompleted = spy() local observer = Rx.Observer.create(nil, nil, onCompleted) observer:onCompleted() expect(#onCompleted).to.equal(1) end) it('calls custom onCompleted callback with no parameters', function() local onCompleted = spy() local observer = Rx.Observer.create(nil, nil, onCompleted) observer:onCompleted("excessive arg", 1) expect(onCompleted).to.equal({{}}) end) it('marks observer as stopped', function() local observer = Rx.Observer.create(nil, function() end, nil) observer:onCompleted() expect(observer.stopped).to.equal(true) end) describe('does not call custom onCompleted callback', function() it('if observer already received completion notification', function() local spyEnabled = false local onCompleted = spy() local observer = Rx.Observer.create(nil, function() if spyEnabled then onCompleted() end end, nil) observer:onCompleted() spyEnabled = true observer:onCompleted() expect(#onCompleted).to.equal(0) end) it('if observer already received error notification', function() local onCompleted = spy() local observer = Rx.Observer.create(nil, function() end, onCompleted) observer:onError() observer:onCompleted() expect(#onCompleted).to.equal(0) end) end) end) end)