0

I have written a small page to learn BDD/TDD. It is at http://duolingo.howyousay.it/link.html

My tests (only one file at the moment) are at http://duolingo.howyousay.it/tests/test.html?coverage&hidepassed&noglobals

I've managed to get 100% code coverage except for 5 lines in http://duolingo.howyousay.it/duolingo_link_fixer.js

   1  var DuolingoLinkFixer = function() {
   2    this.data = {};
   3    var self = this;
   4
   5    document.onreadystatechange = function () {
*  6      self.init();
   7    }
   8  };
   9
  10  DuolingoLinkFixer.prototype.init = function() {
* 11    if (document.readyState == "complete") {
* 12      this.setOriginalUrl();
* 13      this.setAlternateText();
* 14      this.setFixedUrl();
  15    }
  16  }

Lines 6 and 11-14 don't get tested, but if I remove them, the code doesn't work. I'm using QUnit, QUnit-BDD and Blanket.js. How can I test the part of code that runs before onready as it seems that the tests only start running after onready?

My test code currently starts like this:

describe("DuolingoLinkFixer", function() {
  describe("new", function() {
    it("should create a new instance of DuolingoLinkFixer", function() {
      expect(new DuolingoLinkFixer instanceof DuolingoLinkFixer).to.be.true();
    });
  });

});

This is the source for my test HTML page:

<!DOCTYPE html>
<html>
  <head>
    <title>Duolingo JavaScript tests</title>

    <script type="text/javascript" src="/lib/jquery/jquery-3.0.0.js"></script>
    <script type="text/javascript">
      $.holdReady(true);
    </script>

    <link type="text/css" rel="stylesheet" href="/lib/qunit/qunit-1.23.1.css">
    <script type="text/javascript" src="/lib/qunit/qunit-1.23.1.js"></script>
    <script type="text/javascript" src="/lib/qunit-bdd/qunit-bdd.js"></script>

    <script type="text/javascript" src="/lib/blanket.js/blanket.min.js"></script>

    <script type="text/javascript" data-cover src="../url_helper.js"></script>
    <script type="text/javascript" data-cover src="../duolingo_link_fixer.js"></script>

    <script type="text/javascript" src="test_url_helper.js"></script>
    <script type="text/javascript" src="test_duolingo_link_fixer.js"></script>
  </head>
  <body>
    <div id="qunit"></div>
  </body>
</html>

I tried adding jQuery's $.holdReady(true); as suggested in another post but it didn't help. I don't need to use jQuery so I'm trying to avoid it for this project.

CJ Dennis
  • 4,226
  • 2
  • 40
  • 69
  • First thing I would do is to add some printouts using `console.log("here I am");`.Then, you will be able to better focus. – FDavidov Jun 19 '16 at 06:45
  • This might be aweful to do...but... You might be able to creat an on ready event and emit the event at the top top of the page... idk the syntax. maybe something like, var e = document.createEvent('ready'); e.emitChange(); again not sure about the exact syntax – Coty Embry Jun 19 '16 at 07:31
  • @FDavidov I've found this in the docs: https://api.qunitjs.com/QUnit.config/ It says that you can turn `autostart` off, and start it manually _after_ `onready`, instead of as soon as `onready` fires. I haven't worked out if it's possible to manually start it _before_ `onready` fires. – CJ Dennis Jun 19 '16 at 07:45
  • OK, I think now I understand what you are looking for. You want to test if all the lines in your code get executed under the applicable conditions, right? If this is just an ACADEMIC exercise, then I don't know if I can help you. If not, there is a simple way to check it using Google's compressor. It generates warnings if it finds unreachable statements. – FDavidov Jun 19 '16 at 16:19
  • @FDavidov It's only sort of academic. I'm learning BDD/TDD so I can introduce it at work. If it can't be tested, it's hard to automatically be alerted if someone has broken it. – CJ Dennis Jun 19 '16 at 21:12

1 Answers1

0

It turned out that I only needed to add a single line to my test code to test the previously untestable code:

describe("DuolingoLinkFixer", function() {
  describe("new", function() {
    it("should create a new instance of DuolingoLinkFixer", function() {
      expect(new DuolingoLinkFixer instanceof DuolingoLinkFixer).to.be.true();
      document.onreadystatechange();
    });
  });

});

Adding document.onreadystatechange(); runs the code exactly the same as if it had been triggered by the readyStateChange event.

CJ Dennis
  • 4,226
  • 2
  • 40
  • 69