Setting up single-player tests before adding spinner

What is the fail error supposed to say?

It fails here: https://jsfiddle.net/kq5cerjn/

 it("it triggers afterClickCover when cover is clicked", function() {

    //given
    const afterClickCover = jasmine.createSpy("afterClickCover");
    
    //then
    expect(afterClickCover).toHaveBeenCalled();

  });

It passes here: https://jsfiddle.net/6sbvrfz0/1/

it("it triggers afterClickCover when cover is clicked", function() {

    //given
    const afterClickCover = jasmine.createSpy("afterClickCover");
    afterClickCover();

    //then
    expect(afterClickCover).toHaveBeenCalled();

  });

It looks like you are not understanding what we are supposed to be testing.

What do you think that we are testing here?

The part that we are wanting to test is at the end of the coverClickHandler function, where the dispatch occurs.

  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const curtain = openCurtain(cover);
    showVideo(curtain);
    cover.dispatchEvent(events.afterClickCover);
  }

I donā€™t understand what Iā€™m supposed to be doing then.

I seem to be having a hard time with this.

From here, how many fail tests am I supposed to get before it is a good fail test?

It fails here: https://jsfiddle.net/kq5cerjn/

 it("it triggers afterClickCover when cover is clicked", function() {

    //given
    const afterClickCover = jasmine.createSpy("afterClickCover");
    
    //then
    expect(afterClickCover).toHaveBeenCalled();

  });

Okay then, letā€™s follow this where it leads.

With that line at the end of the coverClickHandler, where does events.afterClickCover come from?

If this is wrong, then I do not understand what you mean.

It goes from here:

   cover.dispatchEvent(events.afterClickCover);
  }

To here:

  function init(callback) {
    const cover = document.querySelector(".play");
    cover.addEventListener("click", coverClickHandler);
    events.afterClickCover = new Event("afterClickCover");
    cover.addEventListener("afterClickCover", callback);
  }

Thatā€™s alright, we can keep slowing things down until we are at a pace that you can understand.

Iā€™m not asking you about where it goes. Iā€™m asking you about where it comes from.

Iā€™m also not asking to have random code thrown at me in the hopes that you might strike it lucky. Iā€™m asking you to demonstrate if you understand a simple and fundamental aspect of programming.

In the coverClickHandler() function, where does the property called events.afterClickCover come from? I am asking you about the origin of that property. How does that property gain its value?

`const events = {};`
`const cover = evt.currentTarget;`

The events and cover are given to:

cover.dispatchEvent(events.afterClickCover);

Sorry no, that is not how events.afterClickCover gains its value.

within init

This line: events.afterClickCover = new Event("afterClickCover");

  function init(callback) {
    const cover = document.querySelector(".play");
    cover.addEventListener("click", coverClickHandler);
    events.afterClickCover = new Event("afterClickCover");
    cover.addEventListener("afterClickCover", callback);
  }

My attempt at figuring this out:

Is this good, can progress be made from here?

The code fails here: https://jsfiddle.net/u6ebvqrm/

Expected spy afterClickCover to have been called.

  it("it triggers afterClickCover when cover is clicked", function() {
    const events = {};
    
    //given
    const afterClickCover = jasmine.createSpy("afterClickCover");
    events.afterClickCover = new Event("afterClickCover");

    manageCover.init(afterClickCover);

    //when
    //simulateClick(cover);
    
    //then
    expect(afterClickCover).toHaveBeenCalled();

  });

The code passes here: https://jsfiddle.net/t3cvwx76/

it("it triggers afterClickCover when cover is clicked", function() {
    const events = {};

    //given
    const afterClickCover = jasmine.createSpy("afterClickCover");
    events.afterClickCover = new Event("afterClickCover");

    manageCover.init(afterClickCover);

    //when
    simulateClick(cover);
    
    //then
    expect(afterClickCover).toHaveBeenCalled();

  });

There was much much more to be explained, but you donā€™t seem interested in knowing. I give up on that line of teaching.

No, that test not suitable. You have much more in that test than needs to be there.

We need a simpler test before doing that one, called ā€œdefines the afterClickCover eventā€ where we check that the afterClickCover is being defined first, before using a different test to check that the click event triggers the afterClickCover event.

Delete the ā€œit triggers afterClickCover when cover is clickedā€ test.

For the ā€œdefines the afterClickCover eventā€ test we will need a different function called simulateAfterClickCover, that is similar to the simulateClick function but is a CustomEvent, and doesnā€™t need the object that was defined with the MouseEvent.

How is the simulateAfterClickCover function being written?

  function simulateAfterClickCover(el) {
    const clickEvent = new MouseEvent('click', {
      currentTarget: 'el'
    });
    el.dispatchEvent(clickEvent);
  }

MouseEvent gets changed to CustomEvent.

Do I do anything else?

  function simulateAfterClickCover(el) {
    const clickEvent = new CustomEvent('click', {
      currentTarget: 'el'
    });
    el.dispatchEvent(clickEvent);
  }

How much of inside here is being removed?

it("defines the afterClickCover event", function() {
    const events = {};
    
    //given
    const afterClickCover = jasmine.createSpy("afterClickCover");
    events.afterClickCover = new Event("afterClickCover");

    manageCover.init(afterClickCover);

    //when
    simulateAfterClickCover();
    
    //then
    expect(afterClickCover).toHaveBeenCalled();

  });

When you said delete this test, should it be saved to use at a later date?

or should it be forgotten?

    it("it triggers afterClickCover when cover is clicked", function() {
    const events = {};
    
    //given
    const afterClickCover = jasmine.createSpy("afterClickCover");
    events.afterClickCover = new Event("afterClickCover");

    manageCover.init(afterClickCover);

    //when
    simulateClick(cover);
    
    //then
    expect(afterClickCover).toHaveBeenCalled();

  });

I got this error here: https://jsfiddle.net/fn37buo6/1/

ReferenceError: afterClickCover is not defined

it("defines the afterClickCover event", function() {
    const events = {};
    
    //given
    //const afterClickCover = jasmine.createSpy("afterClickCover");
    //events.afterClickCover = new Event("afterClickCover");

    manageCover.init(afterClickCover);

    //when
    simulateAfterClickCover(cover);
    
    //then
    expect(afterClickCover).toHaveBeenCalled();

  });

Yes you do. Itā€™s in the same sentence in which I said that.

and doesnā€™t need the object that was defined with the MouseEvent.

This was the object: currentTarget: 'el'

And you told me to remove that.

This:

  function simulateAfterClickCover(el) {
    const clickEvent = new CustomEvent('click', {
      currentTarget: 'el'
    });
    el.dispatchEvent(clickEvent);
  }

Becomes this?

  function simulateAfterClickCover(el) {
    const clickEvent = new CustomEvent('click', {
    });
    el.dispatchEvent(clickEvent);
  }

Code: https://jsfiddle.net/xns9yqL8/

describe("init manageCover", function() {

  function simulateAfterClickCover(el) {
    const clickEvent = new CustomEvent('click', {
    });
    el.dispatchEvent(clickEvent);
  }

Bottom:

it("defines the afterClickCover event", function() {
    const events = {};
    
    //given
    //const afterClickCover = jasmine.createSpy("afterClickCover");
    //events.afterClickCover = new Event("afterClickCover");

    manageCover.init(afterClickCover);

    //when
    simulateAfterClickCover(cover);
    
    //then
    expect(afterClickCover).toHaveBeenCalled();

  });

No not correct. What you have shown there is a property (consisting of a key/value pair) which is only part of an object.

image

The object is represented by the curly braces, inside of which are properties (which have values) and methods, (which are functions).

Yes, curly braces are overloaded in JavaScript being used for function bodies and blocks of code, and they are used to represent objects too.

This:

  function simulateAfterClickCover(el) {
    const clickEvent = new CustomEvent('click', {
      currentTarget: 'el'
    });
    el.dispatchEvent(clickEvent);
  }

Becomes this:

Is this right?

  function simulateAfterClickCover(el) {
    const clickEvent = new CustomEvent('click');
    el.dispatchEvent(clickEvent);
  }

Then I do this: https://jsfiddle.net/4smogc50/1/

Where I receive this error:

ReferenceError: afterClickCover is not defined

it("defines the afterClickCover event", function() {
    const events = {};
    
    //given
   // const afterClickCover = jasmine.createSpy("afterClickCover");
   // events.afterClickCover = new Event("afterClickCover");

    manageCover.init(afterClickCover);

    //when
    simulateAfterClickCover(cover);
    
    //then
    expect(afterClickCover).toHaveBeenCalled();

  });

Right, so define afterClickCover.

if you donā€™t define it as a spy, youā€™ll even be told that you need to define it as a spy.

I thought we wanted it to fail first, then pass it.

I did that here: https://jsfiddle.net/7oqgmkhd/2/

The code passes, what do I do next?

Was I supposed to add: events.afterClickCover = new Event("afterClickCover");

I can remove it if it is not needed here.

If it is needed, I can continue progress from here.

  it("defines the afterClickCover event", function() {
    const events = {};

    //given
    const afterClickCover = jasmine.createSpy("afterClickCover");
    events.afterClickCover = new Event("afterClickCover");

    manageCover.init(afterClickCover);

    //when
    simulateAfterClickCover(cover);

    //then
    expect(afterClickCover).toHaveBeenCalled();

  });

Yes thatā€™s right, which is why when adding tests after the code has already been written, that the when section is the last part to be added.

If youā€™re ever not sure that a test can appropriately fail, one of the ways of checking it is to remove the when section to gain that confirmation.

There was never any good reason to have that there. That needs to be removed.

Delete that blasted events object too. You have no good reason for that to be there either.

We can check that the test is properly doing its job by commenting out the cover.dispatchEvent line in the manageCover code. If the test is properly doing its job, it will still pass. It should only be when the cover.addEventListener line is commented out that the test should fail.

We can check that the test is properly doing its job by commenting out the cover.dispatchEvent line in the manageCover code. If the test is properly doing its job, it will still pass.

I did that here and it says failed: https://jsfiddle.net/320uperw/1/

Expected spy afterClickCover to have been called.

  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const curtain = openCurtain(cover);
    showVideo(curtain);
  // cover.dispatchEvent(events.afterClickCover);
  }
it("defines the afterClickCover event", function() {

    //given
    const afterClickCover = jasmine.createSpy("afterClickCover");

    manageCover.init(afterClickCover);

    //when
    simulateAfterClickCover(cover);

    //then
    expect(afterClickCover).toHaveBeenCalled();

  });

Well weā€™ve figured out that thereā€™s something not quite right with the way that the afterClickCover event is being tested. What do you think it might be?