Sinon: рдирдХрд▓реА рдЯрд╛рдЗрдорд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдореВрд▓ ES6 рд╡рд╛рджреЛрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рд╕реЗ рдХреЙрд▓рдмреИрдХ рдЯреНрд░рд┐рдЧрд░ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 23 рдЕрдкреНрд░реИрд▓ 2015  ┬╖  30рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: sinonjs/sinon

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░реАрдХреНрд╖рдг рдореЗрдВ, рдореБрдЭреЗ рдЙрдореНрдореАрдж рдереА рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдЕрдВрджрд░ рд╣рд▓ рдХрд┐рдП рдЧрдП рд╡рд╛рджреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд▓рдмреИрдХ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЬрд╛рд╣рд┐рд░рд╛ рддреМрд░ рдкрд░, рдореВрд▓ рд╡рд╛рджреЗ рдХреЙрд▓рдмреИрдХ рдХреЛ рд╕рдордХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ setTimeout(callback, 0) рдХреЗ рд╕рдорд╛рди рддрд░реАрдХреЗ рд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реЗрдбреНрдпреВрд▓ рдХрд░рддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реЗрдЯрдЯрд╛рдЗрдордЖрдЙрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП tick() рдкрд░ рдХреЙрд▓ рдХрд░рддреЗ рд╕рдордп рд╕рд┐рдиреЙрди рдХрд╛ рдирдХрд▓реА рдЯрд╛рдЗрдорд░ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЙрд▓рдмреИрдХ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

describe 'Promise', ->
  beforeEach ->
    <strong i="8">@clock</strong> = sinon.useFakeTimers()
  afterEach ->
    @clock.restore()
    console.log 'teardown'

  it "should invoke callback", ->
    p = new Promise (resolve, reject) ->
      console.log 'resolving'
      resolve(42)
      console.log 'resolved'
    p.then ->
      console.log 'callback'
    @clock.tick()
    console.log "test finished"

рдореБрдЭреЗ рдЗрд╕ рдЖрдЙрдЯрдкреБрдЯ рдХреА рдЙрдореНрдореАрдж рд╣реИ:

resolved
callback
test finished
teardown

рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдореБрдЭреЗ рдпрд╣ рдорд┐рд▓рддрд╛ рд╣реИ:

resolved
test finished
teardown
callback

рдкрд░реАрдХреНрд╖рдг рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдХреЙрд▓рдмреИрдХ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдХреЙрд▓рдмреИрдХ рдХреЗ рдЕрдВрджрд░ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рджрд╛рд╡рд╛ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рдХрд┐ then() рдкрд░ рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдпрд╛ рдмрд╛рдж рдореЗрдВ рд╡рд╛рджрд╛ рд╣рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬреЛ рдЖрдкрдХреЛ рдЪрд╛рд╣рд┐рдП рд╡рд╣ рд╣реИ рд╡рд╛рджрд╛ рдорд╛рдЗрдХреНрд░реЛрдЯрд╛рд╕реНрдХ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдирд╛ред
рддреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рд╣реА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:

const tick = async (ms) => {
  clock.tick(ms);
};

it("imitates promise fulfill when called once", async () => {
    new Promise(resolve => setTimeout(resolve, 400)).then(callback);
    expect(callback.callCount).to.eql(0);

    await tick(200);
    expect(callback.callCount).to.eql(0);

    await tick(200);
    expect(callback.callCount).to.eql(1);
  });

рд╕рднреА 30 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореИрдВрдиреЗ рдЗрд╕ рдореБрджреНрджреЗ рдореЗрдВ рднреА рднрд╛рдЧ рд▓рд┐рдпрд╛ рд╣реИ

рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЗрд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░реЙрдорд┐рд╕ рд╕реНрдкреЗрдХ setTimeout рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд░реНрддрдорд╛рди рдХреЗ рдареАрдХ рдмрд╛рдж рдПрдХ рдирдпрд╛ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реЗрдбреНрдпреВрд▓ рдХрд░рддрд╛ рд╣реИред

рдХреНрдпрд╛ рдЖрдкрдиреЗ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рд╡рд╛рджрд╛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ? рдЕрдзрд┐рдХрд╛рдВрд╢ рдкрд░реАрдХреНрд╖рдг рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЕрдм рд╡рд╛рджреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдпрджрд┐ it() рдлрд╝рдВрдХреНрд╢рди рдПрдХ рд╡рд╛рджрд╛ рджреЗрддрд╛ рд╣реИ рддреЛ рдкрд░реАрдХреНрд╖рдг рдзрд╛рд╡рдХ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдиреЛрдЯ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣рд▓ рдХрд░рдиреЗ рдпрд╛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд╡рд╛рджреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдЧрд╛ред

рд╣рд╛рдВ, рдПрдХ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рд╡рд╛рджрд╛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╢рд╛рдпрдж рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдирдХрд▓реА рдЯрд╛рдЗрдорд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдореИрдВ рдкрд░реАрдХреНрд╖рдг рд╕рдорд╛рд░реЛрд╣ рд╕реЗ рд▓реМрдЯрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдореБрдХрд╛рдмрд▓рд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреА рдЙрдореНрдореАрдж рдХрд░реВрдВрдЧрд╛ред рдпрд╣ рдПрдХ рддрд░рд╣ рд╕реЗ рдкреВрд░реА рдмрд╛рдд рд╣реИред

рдореБрдЭреЗ рдкреВрд░рд╛ рдпрдХреАрди рд╣реИ рдХрд┐ рдпрд╣ рдкреНрд░реЙрдорд┐рд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдмрджрд▓рдХрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдареАрдХ рдЙрд╕реА рддрд░рд╣ рдЬреИрд╕реЗ рдбреЗрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рд╢рд╛рдпрдж рд╡рд╛рджрд╛ рдпреБрдХреНрддрд┐ рдХреЗ рдПрдХ рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзрд╛рддреНрдордХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдореВрд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рднрд░реЛрд╕рд╛ рдирд╣реАрдВ рдХрд░ рдкрд╛рдПрдВрдЧреЗред

рдореИрдВ рдЙрд╕ рдореБрджреНрджреЗ рдХреЛ рджреЗрдЦрддрд╛ рд╣реВрдВ рдЬреЛ рдЖрдк рд▓реЛрдЧ рдпрд╣рд╛рдВ рдЗрдВрдЧрд┐рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдореИрдВ рдЙрд╕ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реНрдерд┐рддрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдЬрд┐рд╕рдореЗрдВ рдореИрдВ рднрд╛рдЧ рдЧрдпрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рд╡рд╛рджрд╛ рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдФрд░ рд╕рд┐рдиреЙрди рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рджреЛрдиреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдпрд╣ рдореБрдЭреЗ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ рдХрд┐ рдпрд╣ "рдХрд╛рдо" рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдореИрдВ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рд╡рд╛рджрд╛ рд╡рд╛рдкрд╕ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рд▓реЗрдХрд┐рди рдирдХрд▓реА рдЯрд╛рдЗрдорд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рд╡рд╛рджрд╛ рдХрднреА рднреА рд╣рд▓ рд╣реЛрдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИред

рдореБрдЭреЗ рдРрд╕рд╛ рд▓рдЧ рд░рд╣рд╛ рдерд╛ рдХрд┐ рдЗрди рджреЛрдиреЛрдВ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдкрд╣рд▓рд╛ рдкрд╛рд╕ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдмрдХрд┐ рджреВрд╕рд░рд╛ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВ рдореЛрдЪрд╛ рдХреЗ рд╕рд╛рде рдЪрд╛рдИ-рдП-рд╡рд╛рджрд╛ рдкреНрд▓рдЧрдЗрди рдХреЗ рд╕рд╛рде рдЪрд╛рдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдореБрдЭреЗ рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИ "2000ms рдХрд╛ рд╕рдордп рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ рд╣реИред рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЗрд╕ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛() рдХреЙрд▓рдмреИрдХ рдХрд╣рд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред"

describe('chai as promised', function() {

    it('should resolve a promise', function() {
        var promise = new Promise(function( resolve ) {
            setTimeout( resolve, 1000 );
        });
        return expect( promise ).to.have.been.fulfilled;
    });

});

describe('sinon.useFakeTimers()', function() {

    before(function() {
        this.clock = sinon.useFakeTimers();
    });

    after(function() {
        this.clock.restore();
    });

    it('should resolve a promise after ticking', function() {

        var promise = new Promise(function( resolve ) {
            setTimeout( resolve, 1000 );
        });

        this.clock.tick( 1001 );

        return expect( promise ).to.have.been.fulfilled;
    });

});

рдореИрдВрдиреЗ рдПрдХ рддреНрд╡рд░рд┐рдд рдкрд░реАрдХреНрд╖рдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рддреИрдпрд╛рд░ рдХреА: https://github.com/JustinLivi/sinon-promises-test

рдкрд░реАрдХреНрд╖рдг рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдмрд╣рд╛рд▓ рдХрд░рдирд╛ рдПрдХ рд╡реНрдпрд╡рд╣рд╛рд░реНрдп рд╕рдорд╛рдзрд╛рди рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ:

describe('sinon.useFakeTimers()', function() {

    before(function() {
        this.clock = sinon.useFakeTimers();
    });

    it('should resolve a promise after ticking', function() {

        var promise = new Promise(function( resolve ) {
            setTimeout( resolve, 1000 );
        });

        this.clock.tick( 1001 );
        this.clock.restore();

        return expect( promise ).to.have.been.fulfilled;
    });

});

рд╣рдо рдЬрд┐рд╕ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд╡рд╣ рдореВрд▓ рд╡рд╛рджреЗ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдХреБрдЫ рд╕рд░рд▓ рдХреЗ рд╕рд╛рде рдмрджрд▓рдирд╛ рд╣реИ рдЬреЛ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рддреЗ рд╕рдордп рд╕реЗрдЯрдЯрд╛рдЗрдордЖрдЙрдЯ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ:

window.Promise = require('promise-polyfill')

UseFakeTimers рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╕рдордп Sinon.JS рдмрд╕ рд╡рд╣реА рдХрд░ рд╕рдХрддрд╛ рд╣реИред

@JustinLivi рдкреВрд░рд╛ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдмрд╣рд╛рд▓ рдХрд░рдирд╛ рдореЗрд░реЗ рд▓рд┐рдП рдпрд╣ рдерд╛: +1:

рддреЛ, рдХреЛрдИ рд╕рдорд╛рдзрд╛рди рдпрд╛ рдХрд╛рдордХрд╛рдЬ?
рдореИрдВ рдЕрдкрдиреЗ рдРрдк рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рдФрд░ ES6 рд╡рд╛рджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░реЗ рдкрд░реАрдХреНрд╖рдг рдРрд╕рд╛ рдХрд╣рддреЗ рд╣реИрдВ :)

рдореБрдЭреЗ рд╕рдорд╕реНрдпрд╛ рд╣реИ, рджреЗрд╢реА рд╡рд╛рджреЛрдВ рд╕реЗ рдирд╣реАрдВ рдмрд▓реНрдХрд┐ es6-рд╡рд╛рджрд╛ рдкреЙрд▓реАрдлрд╝рд┐рд▓ рдХреЗ рд╕рд╛рдеред
@JustinLivi рдХрд╛ clock.restore() рд╕рдорд╛рдзрд╛рди рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░рддрд╛ рд╣реИред

рдкрддрд╛ рдирд╣реАрдВ рдпрд╣ рдореБрджреНрджрд╛ рдЗрддрдиреЗ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдпрд╣рд╛рдБ рдХреНрдпреЛрдВ рдкрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд┐рдиреЛрди рдХреЗ рд╕рд╛рде рдпрд╣ рдХреЛрдИ рдореБрджреНрджрд╛ рдирд╣реАрдВ рд╣реИред рд╡рд╛рджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ async рддрд░реНрдХ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд░ рд░рд╣рд╛ рд╣реИред рдлрд┐рд░ рднреА, рдпрд╣рд╛рдВ рд╕рднреА рдкрд░реАрдХреНрд╖рдг рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд▓реЙрдЬрд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ (рдЬреИрд╕рд╛ рдХрд┐ рдУрдкреА рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рддрд╛ рд╣реИ)ред рдЗрд╕рд▓рд┐рдП рднрд▓реЗ рд╣реА рдЖрдк рд╕рдордп рдХрд╛ рдвреЛрдВрдЧ рдХрд░ рд░рд╣реЗ рд╣реЛрдВ, рдлрд┐рд░ рднреА рдЖрдк рдЕрдкрдиреЗ рдХрд╛рд░реНрдп рдХреЗ рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рднреА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд╡рд╛рджреЗ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдЕрдкрдирд╛ рдкрд░реАрдХреНрд╖рдг рдереЛрдбрд╝рд╛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рдЖрдорддреМрд░ рдкрд░ рдЕрдзрд┐рдХрд╛рдВрд╢ рдкрд░реАрдХреНрд╖рдг рдврд╛рдВрдЪреЗ рдХреЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрддрд╛ рд╣реИ ( рдпрд╣рд╛рдВ рдореЛрдЪрд╛ рд╕реЗ рдПрдХ рд╣реИ ), рд▓реЗрдХрд┐рди рд╣рдо рдЖрдиреЗ рд╡рд╛рд▓реА рдирдИ рд╕рд╛рдЗрдЯ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рд╡реНрдпрдВрдЬрдиреЛрдВ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛ рд╡рд╛рд▓реЗ рдХреБрдЫ рд▓реЗрдЦреЛрдВ рдХреЗ рд╕рд╛рде рдЗрд╕рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░реЗрдВрдЧреЗред

рдЗрд╕рд▓рд┐рдП @JustinLivi рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдереЛрдбрд╝рд╛ рдмрджрд▓рддреЗ рд╣реБрдП рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддреЗ рд╣реИрдВ:

var sinon = require('sinon');

describe('sinon.useFakeTimers()', function() {

    before(function() {
        this.clock = sinon.useFakeTimers();
    });

    it('should resolve a promise after ticking', function(done) {

        var promise = new Promise(function( resolve ) {
            setTimeout( resolve, 10000 );
        });

        this.clock.tick( 10001 );

        promise
            .then(done) // call done when the promise completes
            .catch(done); // catch any accidental errors
    });

});

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрджрд┐ рдЖрдк рдореЛрдЪрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рд╡рд╛рджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдЗрд╕рдХреЗ рдКрдкрд░ рдЙрд╕реА рдХреЛрдб рдХрд╛ "рд╢реЙрд░реНрдЯрдХрдЯ" рд╕рдВрд╕реНрдХрд░рдг рд╣реИ, рдпрджрд┐ рдЖрдк рд╕реАрдзреЗ рдкрд░реАрдХреНрд╖рдг рдврд╛рдВрдЪреЗ рдореЗрдВ рд╡рд╛рджрд╛ рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВ:

it('should resolve a promise after ticking', function() {
    var promise = new Promise(function( resolve ) {
        setTimeout( resolve, 10000 );
    });

    this.clock.tick( 10001 );

    return promise;
});

рдпрд╣ рдХрд░реЗрдЧрд╛

  1. рдкреНрд░реЙрдорд┐рд╕ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рднреЗрдЬреЗ рдЧрдП executor рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ (ES2015 рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рджреЗрдЦреЗрдВ), рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ рдирдП рдЯрд╛рдЗрдордЖрдЙрдЯ рдХреА рд╕реНрдерд╛рдкрдирд╛ред
  2. рдирд┐рд░реНрдорд┐рдд рд╡рд╛рджрд╛ рд╡рд╛рдкрд╕ рдХрд░реЗрдВред
  3. рд╕рдордп рдкрд░ рдЯрд┐рдХ рдХрд░реЗрдВред
  4. рд╡рд╛рджреЗ рдХреЛ рд╣рд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддреЗ рд╣реБрдП, рдЯрд╛рдЗрдо рдЖрдЙрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░реЗрдВ
  5. process (рдпрд╛ рдмреНрд░рд╛рдЙрдЬрд╝рд░) рдПрдХ рдирдпрд╛ "рдЯрд┐рдХ" рд╕реНрдЯреИрдХ рдХрд░реЗрдЧрд╛, рд╡рд╛рджреЗ рдХреЛ рд╣рд▓ рдХрд░реЗрдЧрд╛ рдФрд░ рдХрд┐рд╕реА рднреА рд╢реЗрд╖ Thenables рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛

рдЗрд╕реЗ рдПрдХ рдЧреИрд░-рдмрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдмрдВрдж рдХрд░рдирд╛ред

@ fatso83 рдореИрдВ рдирд╣реАрдВ рджреЗрдЦрддрд╛ рдХрд┐ рдЖрдкрдиреЗ рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рд╣реИ рдЙрд╕реЗ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдкрд░реАрдХреНрд╖рдг рдХреИрд╕реЗ рдорд┐рд▓ рд░рд╣реЗ рд╣реИрдВред рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдг рднрдВрдбрд╛рд░ рдореЗрдВ рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдкрд░реАрдХреНрд╖рдг рдЬреЛрдбрд╝реЗ рдФрд░ рдореБрдЭреЗ рдЕрднреА рднреА timeout of 2000ms exceeded. Ensure the done() callback is being called in this test. рдорд┐рд▓рддрд╛ рд╣реИ

рдпрд╣рд╛рдВ рджреЗрдЦреЗрдВ: https://github.com/JustinLivi/sinon-promises-test/blob/master/test.js#L60
рд╕рд╛рде рд╣реА, рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛрдореИрдВ рдмрддрд╛ рд╕рдХрддрд╛ рд╣реВрдВ, рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдЕрднреА рднреА рд╡рд┐рдлрд▓ рд╣реИ: https://github.com/JustinLivi/Sinon.JS/commit/de106e6db2f5cc076b7e3a78635bd9ae2b6be1c2

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: @fpirsch рджреНрд╡рд╛рд░рд╛ рдЯрд┐рдкреНрдкрдгреА рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ es6 рд╡рд╛рджрд╛ рдкреЙрд▓реАрдлрд┐рд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рд╣реИ? рдХреНрдпрд╛ рдХрд┐рд╕реА рдиреЗ рдмреНрд▓реВрдмрд░реНрдб рдЬреИрд╕реЗ рд╡реИрдХрд▓реНрдкрд┐рдХ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рд╕рд╛рде рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рд╣реИ?

@ fatso83 рдпрд╣ рдХреЛрдИ return promise рдореБрджреНрджрд╛ рдирд╣реАрдВ рд╣реИред
рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдПрдХ рдкреНрд░реЗрдд рд╣реИ (рдкреБрд░рд╛рдирд╛, рдмрд┐рдирд╛ рд╡рд╛рджреЛрдВ рдХреЗ) + es6-рд╡рд╛рджреЗ рдкреЙрд▓реАрдлрд┐рд▓ + sinon.js рдореБрджреНрджрд╛ред рдЖрдзреБрдирд┐рдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдореЗрдВ рд╡рд╛рджрд╛ рд╣рд▓ рд╣реЛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдареАрдХ рдЪрд▓рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡рд╛рджрд╛ рдкреЙрд▓реАрдлрд┐рд▓ рдХреЗ рд╕рд╛рде рд╡рд╛рджрд╛ рдХрднреА рднреА рд╣рд▓ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдЯрд╛рдЗрдорд░ рдирдХрд▓реА рд╣реЛрддреЗ рд╣реИрдВред

@JustinLivi рдФрд░ @fpirsch : рдпрд╣ рдмрдЧ рд░рд┐рдкреЛрд░реНрдЯ _native_ рд╡рд╛рджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереАред рдореБрдЭреЗ es6-promise рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП @JustinLivi рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдкреНрд░реЛрдЬреЗрдХреНрдЯ рджрд┐рдЦрд╛рдИ рджреЗ рд░рд╣рд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕рдХреА рдкреБрд╖реНрдЯрд┐ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ред рд╡рд╣реА рдЕрдиреНрдп рдкреЙрд▓реАрдлрд╝рд┐рд▓ рдХреЗ рд▓рд┐рдП рдЬрд╛рддрд╛ рд╣реИ: рдпрд╣ рдПрдХ рдФрд░ рдореБрджреНрджрд╛ рд╣реЛрдЧрд╛ред рдореИрдВрдиреЗ рдЗрд╕реЗ рдиреЛрдб 5 рдФрд░ 6 рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдореВрд▓ рд╡рд╛рджрд╛ рд╕рдорд░реНрдерди рд╣реИред

рдкрд┐рдЫрд▓реА рдкреЛрд╕реНрдЯ рд╕реЗ рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдг рдХреЛрдб рдХреЛ рдХреЙрдкреА-рдкреЗрд╕реНрдЯ рдХрд░рдирд╛ рдФрд░ рдЙрд╕реЗ рдЪрд▓рд╛рдирд╛ (рдореЛрдЪрд╛ рдФрд░ рд╕рд┐рдиреЙрди рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░рдирд╛):

$ pbpaste > test.js

$ mocha test.js

  sinon.useFakeTimers()
    тЬУ should resolve a promise after ticking

  1 passing (12ms)

@fpirsch : рдореИрдВрдиреЗ рдХрднреА рдирд╣реАрдВ рдХрд╣рд╛ рдХрд┐ рдпрд╣ return promise рдореБрджреНрджрд╛ рдерд╛ред рдореИрдВрдиреЗ рдЕрднреА рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ рд╡рд╣ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдЫреЛрдЯреЗ рд░реВрдк рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦ рд╕рдХрддрд╛ рд╣реИред рдПрдХ рдЯрд┐рдк, рдлрд┐рдХреНрд╕ рдирд╣реАрдВред рд▓реЗрдХрд┐рди рдЖрдкрдиреЗ рдХреБрдЫ рдореВрд▓реНрдпрд╡рд╛рди рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд╛рди рдХреА: рдпрд╣ рджреЗрд╢реА рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╛рджрд╛ рдкреЙрд▓реАрдлрд┐рд▓ рдореЗрдВ рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИред рдпрд╣ рдЖрдкрдХреЗ рд╡рд╛рджреЗ рд▓рд┐рдм рдХрд╛ рджреЛрд╖ рд╣реИ, рд╕рд┐рдиреЛрди рдХрд╛ рдирд╣реАрдВред рдЖрдкрдХрд╛ рд╡рд╛рджрд╛ lib рд╢рд╛рдпрдж setTimeout рдФрд░ рджреЛрд╕реНрдд рдХреЛ рдХреИрд╢ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдЗрд╕ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдЯреВрдЯ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВрдиреЗ рдПрдХ рдмрд╛рд░ pinkyswear lib рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд┐рдХреНрд╕ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛, рдЗрд╕рд▓рд┐рдП рдХреЛрдИ рдЖрд╢реНрдЪрд░реНрдп рдирд╣реАрдВред

es6-promise рдХреЗ рд╕реНрд░реЛрдд рдХреА рдЬрд╛рдБрдЪ рдХреА рдФрд░ рдпрд╣ setTimeout рдХреЗ рд╕рдВрджрд░реНрднреЛрдВ рдХреЛ рдХреИрд╢ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ , рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╕рд┐рдиреЙрди рдХреА рдХрд┐рд╕реА рднреА рдЪреАрдЬрд╝ рд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдореИрдВ рдпрд╣ рджреЗрдЦрдиреЗ рдореЗрдВ рдЕрд╕рдлрд▓ рд░рд╣рд╛ рдХрд┐ рд╡рд╣ рд╢реЗрдбреНрдпреВрд▓рд░ рдпрд╣рд╛рдВ рдХреИрд╕реЗ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ ... рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рдПрдХ рдмрдбрд╝реА рд╕реВрдЪреА рднреА рд╣реИ рдЬреЛ рдкреЙрд▓реАрдлрд┐рд▓ рдЯрд╛рдЗрдордЖрдЙрдЯ рд╢реЗрдбреНрдпреВрд▓рд░ рдкрд░ рд╡рд╛рдкрд╕ рдЖрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдЧрд╛ред рдЙрд╕ рдлрд╝реЙрд▓рдмреИрдХ рдкрд░ рдЙрддрд░рдиреЗ рд╡рд╛рд▓рд╛ рдХреЛрдИ рднреА рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдкреНрд░рд╛рдЪреАрди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП :)

рд▓реЗрдХрд┐рди рд╡реИрд╕реЗ рднреА, @fpirsch рдФрд░ @JustinLivi рдиреЗ рдЬреЛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ, рд╡рд╣ рд╕рд┐рдиреЙрди рдФрд░ рдкреЙрд▓реАрдлрд╝рд┐рд▓ рдХреЗ рдмреАрдЪ рдЕрдВрддрдГрдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рдХреЗ рдореБрджреНрджреЗ рд╣реИрдВред рдФрд░ рдпрд╣ рдПрдХ рдФрд░ рдореБрджреНрджрд╛ рд╣реИред рдпрд╣ рдирд╣реАрдВ рджреЗрдЦ рд░рд╣рд╛ рдХрд┐ рд╕рд┐рдиреЙрди рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдЯреАрдПрдо рдХреИрд╕реЗ рдХрд░ рд╕рдХрддрд╛ рд╣реИ (рдХрд┐рд╕реА рднреА рдкреАрдЖрд░ рдХреЗ es6-polyfill рдореЗрдВ рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рдХреА рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ), рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдпрд╣ рдПрдХ рд╕рд┐рдиреЙрди рдореБрджреНрджрд╛ рд╣реИ рддреЛ рдПрдХ рдирдпрд╛ рдореБрджреНрджрд╛ рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВред

рдкреАрдПрд╕ рдореИрдВ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ @ropez рд╕реЗ рдЯрд┐рдк promise-polyfill рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдерд╛, рдФрд░ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдиреНрдпреВрдирддрдо рдкреЙрд▓реАрдлрд┐рд▓ рдХреЗ рд▓рд┐рдП рднреА рд╣рдорд╛рд░реА рд╕рд┐рдлрд╛рд░рд┐рд╢ рд╣реИ, рд▓реЗрдХрд┐рди рджрд┐рдП рдЧрдП рдХреЗ рд╡рд┐рдкрд░реАрдд рдХрд╛рд░рдг рдХреЗ рд▓рд┐рдПред @mrodrick рдиреЗ рдЬрдирд╡рд░реА рдореЗрдВ рдЙрд╕ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ рдкреИрдЪ рдХрд┐рдпрд╛ ( @ropez рдЯрд┐рдкреНрдкрдгреА рдХреЗ рдХреБрдЫ рдорд╣реАрдиреЗ рдмрд╛рдж) setTimeout рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рдХреИрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддрд╛рдХрд┐ рд╡рд╛рджрд╛ _рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рдХрд┐ sinon рдХреНрдпрд╛ рдХрд░ рд░рд╣рд╛ рдерд╛_ рд╡реИрд╢реНрд╡рд┐рдХ setTimeout рд╕рдВрджрд░реНрдн рдореЗрдВ рд╣рд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП taylorhakes/promise-polyfill#15 рджреЗрдЦреЗрдВред

@ fatso83 рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ setTimeout рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рд╕рд╣реЗрдЬрдирд╛ рдЬреИрд╕рд╛ рдХрд┐ @mrodrick рдиреЗ promise-polyfill рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдерд╛, рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рди рддреЛ es6-promise рдХреЛ promise-polyfill рд╕реЗ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддрд╛ рд╣реИ :-(
рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдпрд╣ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдкреНрд░реЗрдд + рдореЛрдЪрд╛ рдвреЗрд░ рдореЗрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХрд░реНрдо рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реЗ рдкреВрд░реНрдг рдвреЗрд░ рдореЗрдВ рдирд╣реАрдВред рдЗрд╕рд╕реЗ рдмрд╣реБрдд рдердХ рдЧрдПред

@ fatso83 рдореИрдВрдиреЗ рдпрд╣рд╛рдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рд╣реИ: рдлреЗрдХрдЯрд╛рдЗрдорд░реНрд╕
рдорд╛рдорд▓рд╛ рдХрд░реНрдо рдХреЗ рд╕рд╛рде рд╣реЛ рд╕рдХрддрд╛ рд╣реИ ... рдореИрдВ рдЗрд╕рдореЗрдВ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдЙрддрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ред

@fpirsch : рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдкрд░ рд╣реИрдВред рдЖрдк рдФрд░ @JustinLivi рджреЛрдиреЛрдВ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдзрд╛рд╡рдХ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд░реНрдо рдкрд░ рдирд┐рд░реНрднрд░ рд╣реИрдВред рд╡реЗ рдмрд╣реБрдд рд╕рдорд╛рди рд▓рдЧрддреЗ рд╣реИрдВред рдкреАрдПрд╕ рдореИрдВрдиреЗ рдЕрдкрдиреА рдЯрд┐рдкреНрдкрдгреА рд╣рдЯрд╛ рджреА рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рд▓рдЧрд╛ рдХрд┐ рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдЬрд╕реНрдЯрд┐рди рдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдЯреЗрд╕реНрдЯ рдХреЗрд╕ рдХреА рдЖрдкреВрд░реНрддрд┐ рдХреА рдереА рдЬрд┐рд╕рдиреЗ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рджрд┐рдЦрд╛рдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЖрдкрдХреА рдЙрджрд╛рд╣рд░рдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рдЗрд╕ рдХрд░реНрдо рдХреА рдЪреАрдЬ рд╣реЛрдиреЗ рдХреА рдкрд░рд┐рдХрд▓реНрдкрдирд╛ рдХреЛ рдордЬрдмреВрдд рдХрд░рддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!

рдпрд╣ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИред рдиреАрдЪреЗ рддреАрд╕рд░рд╛ рдкрд░реАрдХреНрд╖рдг рдХреНрдпреЛрдВ рд╡рд┐рдлрд▓ рд╣реЛрддрд╛ рд╣реИ? рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд┐рдлрд▓рддрд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрд░реАрдХреНрд╖рдг рд╕рдордпрдмрд╛рд╣реНрдп рд╣реИ:

     Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
describe.only('working', () => {
  let clock;
  beforeEach(() => { clock = Sinon.useFakeTimers(); })
  afterEach(() => { clock.restore() })

  const delay = (ms) => (
    new Promise((resolve/* , reject */) => {
      setTimeout(resolve, ms)
    })
  );

  it('1 OK', () => {
    const promise = new Promise((resolve) => {
      setTimeout(resolve, 100)
    })
    clock.tick(200)
    return promise
  })

  it('2 OK', () => {
    const promise = delay(100)
    clock.tick(200)
    return promise
  })

  it('3 FAIL', () => {
    const promise = delay(50).then(() => delay(50))
    clock.tick(200)
    return promise
  })
})

@jasonkuhrt рддреАрд╕рд░рд╛ рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ clock.tick рдирд┐рд╖реНрдкрд╛рджрдХреЛрдВ рдХреЛ рд╕рдордХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ .then(...) рдХреЛ рдЗрд╕рдХреА рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкреНрд░рдХреГрддрд┐ рдХреЗ рдХрд╛рд░рдг рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

рдСрдирдлреБрд▓рдлрд┐рд▓реНрдб рдпрд╛ рдСрди рд░рд┐рдЬреЗрдХреНрдЯреЗрдб рдХреЛ рддрдм рддрдХ рдирд╣реАрдВ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрдм рддрдХ рдХрд┐ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдВрджрд░реНрдн рд╕реНрдЯреИрдХ рдореЗрдВ рдХреЗрд╡рд▓ рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдХреЛрдб рди рд╣реЛред

@ fatso83 рдореИрдВ рдЯрд╛рдЗрдорд░ рдЬреЛрдбрд╝рдиреЗ рд╡рд╛рд▓реЗ рдЬрдВрдЬреАрд░ рд╡рд╛рджреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓реЛрд▓реЗрдХреНрд╕ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреА рд╕реНрдерд┐рддрд┐ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ред рд╡рд░реНрддрдорд╛рди рд╕реАрдорд╛ рдХреЛ рдХрдо рд╕реЗ рдХрдо рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рд╡рд┐рд╕реНрддреГрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЗрд╕ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рд╕рдорд░реНрдерди рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдпрд╛ рдирд╣реАрдВ, рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдпрд╛ рдПрдХ рдирдпрд╛ рдЦреЛрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ) рдФрд░ рд▓реЛрд▓реЗрдХреНрд╕ рдореЗрдВ рдПрдХ рдирдП рдореБрджреНрджреЗ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред
рдореИрдВ рдпрд╣ рднреА рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рддрд╛ рд╣реВрдВ рдХрд┐ рдпрджрд┐ рдЗрд╕ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ (рдЯрд╛рдЗрдорд░ рдЬреЛрдбрд╝рдиреЗ рд╡рд╛рд▓реЗ рд╡рд╛рджреЗ рдХрд╛ рдкреАрдЫрд╛ рдХрд░рдирд╛) рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рд╣реИ, рддреЛ рдЗрд╕рд╕реЗ рдПрдХ рдмрд╛рдзрд┐рдд рд▓реЛрд▓реЗрдХреНрд╕ рдПрдкреАрдЖрдИ рд╕рдВрд╢реЛрдзрди рд╣реЛ рдЬрд╛рдПрдЧрд╛ (AFAIK рдШрдбрд╝реА ред рдЯрд┐рдХ рдХреЛ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╣реЛрдирд╛ рд╣реЛрдЧрд╛)ред

@gautaz рдЖрд╣ рдЕрдм рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред рд╕рдордЭрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!

lolex рдПрдХ рд╕рд┐рдВрдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИ, рдФрд░ рдореБрдЭреЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рднреА рддрд░рд╣ @jasonkuhrt рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рдХреИрд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдкреАрдЖрд░ рдХреА рдЖрдкреВрд░реНрддрд┐ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ, рд▓реЗрдХрд┐рди clock.tick рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрдХрд░реНрд╖рдХ рдирд╣реАрдВ рд╣реИред рдореИрдВ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд async рд╡рд┐рдзрд┐ рджреЗрдЦрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред

рдореБрдЭреЗ рд╡рд╛рджреЛрдВ рдФрд░ рдШрдбрд╝реА рдХреА рдЯрд┐рдХ рдЯрд┐рдХ рдХреЗ рд╕рд╛рде рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рдереА, рд▓реЗрдХрд┐рди рд╢рд╛рдпрдж рдЗрд╕рд▓рд┐рдП рдХрд┐ рдореИрдВрдиреЗ рджреЗрдЦрд╛ рдерд╛ рдХрд┐ рд╡реЗ рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдереЗ, рдФрд░ рдмреАрдЪ рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдШрдбрд╝реА рдХреА рдЯрд┐рдХ рдЬреЛрдбрд╝ рджреА рдереАред

@ fatso83 рдЖрдк рд╕рд╣реА рдХрд╣ рд░рд╣реЗ рд╣реИрдВ, рдПрдХ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ tick рдЬреЛрдбрд╝рдирд╛ рдХрдо рдмрд╛рдзрд┐рдд рд╣реЛрдЧрд╛ (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдмрд╛рдзрд┐рдд рдирд╣реАрдВ)ред
рддреЛ asyncTick рдЬреИрд╕рд╛ рдХреБрдЫ рд╕рд╣реА рдлрд┐рдЯ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЕрдЧрд░ рдореИрдВ рд╕рдордп рдирд┐рдХрд╛рд▓ рд╕рдХрддрд╛ рд╣реВрдВ рддреЛ рдореИрдВ рдЗрд╕реЗ рджреЗрдЦ рд▓реВрдВрдЧрд╛ред

@gautaz рдмрд╕ рдЙрддреНрд╕реБрдХ рд╣реИ рдЕрдЧрд░ рдЖрдк рдХрднреА рднреА рдкреИрдЪ рдХреА рдЖрдкреВрд░реНрддрд┐ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП lolex ?

@ fatso83 рдирдорд╕реНрддреЗ, рдореИрдВрдиреЗ рдкрд┐рдЫрд▓реЗ рд╕рд╛рд▓ рдЕрдкрдиреА рддрд░рдл рд╕реЗ рдПрдХ рд╢рд╛рдЦрд╛ рд╢реБрд░реВ рдХреА рд╣реИ рд▓реЗрдХрд┐рди рдХрд╛рдо рдЦрддреНрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрднреА рд╕рдордп рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИред
рдореЗрд░реЗ рдкрд╛рд╕ рд╕рд╣рдХрд░реНрдореА рд╣реИрдВ рдЬреЛ рднреА рдЗрд╕реА рдореБрджреНрджреЗ рд╕реЗ рдлрдВрд╕ рдЧрдП рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдХреЗрд╡рд▓ рдпрд╣ рдЖрд╢рд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдореБрджреНрджрд╛ рдореБрдЭреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рдордп рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛред

рдХреНрдпрд╛ рдЗрд╕ рдмреАрдЪ рдЗрд╕ рд╡рд┐рд╢реЗрд╖ рдмрд┐рдВрджреБ рдкрд░ рд▓реЛрд▓реЗрдХреНрд╕ рдПрдкреАрдЖрдИ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХреБрдЫ рдмрджрд▓рд╛рд╡ рдЖрдпрд╛?

рдпрд╣ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдкрд┐рдЫрд▓реЗ рдЖрдзреЗ рд╕рд╛рд▓ рдореЗрдВ рдХреЛрдбрдмреЗрд╕ рдореЗрдВ рдмрд╣реБрдд рдХрдо рдмрджрд▓рд╛рд╡ рд╣реБрдП рд╣реИрдВред рдХрд╛рдлреА рд╕реНрдерд┐рд░ред

рдпрд╣рд╛рдВ рд╕рд░рд▓ рдХрд╛рдордХрд╛рдЬ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдореМрдХрд╛ рд╣реИ? рдПрдХ рд╣реА рд╕рдорд╕реНрдпрд╛ рд╣реИред рдореЗрд░реЗ рдкрд╛рд╕ рджреЛ рд╡рд╛рджреЗ рд╣реИрдВ рдФрд░ рд╡реЗ рд╕реЗрдЯрдЯрд╛рдЗрдордЖрдЙрдЯ рджреНрд╡рд╛рд░рд╛ рд╣рд▓ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдореБрдЭреЗ рдХрд┐рд╕реА рднреА рд╕рдВрдХрд▓реНрдк рд╕реЗ рдкрд╣рд▓реЗ, рджреВрд╕рд░реЗ рд╕реЗ рдкрд╣рд▓реЗ рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ рд╕рдВрдХрд▓реНрдк рдХреЗ рдмрд╛рдж, рдФрд░ рд╕рднреА рд╣рд▓ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рд╕рд╛рдорд╛рди рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬреЛ рдЖрдкрдХреЛ рдЪрд╛рд╣рд┐рдП рд╡рд╣ рд╣реИ рд╡рд╛рджрд╛ рдорд╛рдЗрдХреНрд░реЛрдЯрд╛рд╕реНрдХ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдирд╛ред
рддреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рд╣реА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:

const tick = async (ms) => {
  clock.tick(ms);
};

it("imitates promise fulfill when called once", async () => {
    new Promise(resolve => setTimeout(resolve, 400)).then(callback);
    expect(callback.callCount).to.eql(0);

    await tick(200);
    expect(callback.callCount).to.eql(0);

    await tick(200);
    expect(callback.callCount).to.eql(1);
  });

@jakwuh рдХреА рдЪрд╛рд▓ рдиреЗ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛ (рдиреЛрдб 8, рдХреЛрдИ рдЯреНрд░рд╛рдВрд╕рдкрд┐рд▓реЗрд╢рди рдирд╣реАрдВ, рдореВрд▓ рд╡рд╛рджреЗ), рд╕рд┐рд╡рд╛рдп then рдХреЙрд▓рдмреИрдХ рдХреЛ рдПрдХ рдЯрд┐рдХ рджреНрд╡рд╛рд░рд╛ рд╕реНрдердЧрд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рдЕрджреНрдпрддрди рдЯрд┐рдкреНрдкрдгреА : рдореЗрд░реА рдореВрд▓ рдЯрд┐рдкреНрдкрдгреА (рдиреАрдЪреЗ) рдореЗрдВ рд╕рдорд╛рдзрд╛рди рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВред рдХрднреА-рдХрднреА рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдмрдХреБрдЫ рдлреНрд▓рд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рдЧрд╛рддрд╛рд░ await Promise.resolve() рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрд╣рд╛рдВ рдХреБрдЫ рдРрд╕рд╛ рд╣реИ рдЬреЛ рдереЛрдбрд╝рд╛ рдмреЗрд╣рддрд░ рдХрд╛рдо рдХрд░рддрд╛ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ:

beforeEach(function() {
    const originalSetImmediate = setImmediate;
    this.clock = sinon.useFakeTimers();
    this.tickAsync = async ms => {
        this.clock.tick(ms);
        await new Promise(resolve => originalSetImmediate(resolve));
    }
});

afterEach(function() {
    this.clock.restore();
});

рдореВрд▓ рдЯрд┐рдкреНрдкрдгреА [рдЪреЗрддрд╛рд╡рдиреА: рдКрдкрд░ рджрд┐рдП рдЧрдП рдХреЛрдб рдХреА рддрд░рд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ред]

tick рд╕рд╣рд╛рдпрдХ рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд async рдЧреИрдк рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдореЗрд░реЗ рд▓рд┐рдП рд╕рдорд╕реНрдпрд╛ рдареАрдХ рд╣реЛ рдЧрдИ:

```рдЬреЗрдПрд╕
рдХреЙрдиреНрд╕реНрдЯ рдЯрд┐рдХ = рдПрд╕рд┐рдВрдХреНрд╕ (рдПрдордПрд╕) => {
рдШрдбрд╝реА.рдЯрд┐рдХ (рдПрдордПрд╕);
Promise.resolv() рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░реЗрдВ;
};

рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕рд┐рдиреЙрди рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдХреЗ рдХрд╛рдо рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рд░рдЦрдиреЗ рд╡рд╛рд▓реЗ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрд╕рдХреА рд╕рд╣реЛрджрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛ lolex ), рдпрд╣рд╛рдБ рдЪрд░реНрдЪрд╛рдПрдБ рджреЗрдЦреЗрдВ:

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

brettz9 picture brettz9  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

fearphage picture fearphage  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

ljian3377 picture ljian3377  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

kbirger picture kbirger  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

stevenmusumeche picture stevenmusumeche  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ