Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I load a binary file during javascript unit test?

In my application, the user uses HTML5 drag and drop to process a binary file. That part of the code works fine. In chrome, I drag a binary file and use a FileReader to create an arrayBuffer. That all seems to work fine. I am writing tests for this functionality and I am at a loss. How do I load a binary file into my unit test? For the bit of code I am testing, I only need an arrayBuffer. Currently, I am creating the arrayBuffer manually, but that isn't a sustainable solution. In order for my tests to be effective, I need to be able to throw a new binary file in at anytime and make a new test. My testing environment is testacular+jasmine.

( function() {"use strict";
    function loadSimpleDataView() {
      //instead of defining ArrayBuffer, 
      //I want it to be generated based upon an external file
      var buffer = new ArrayBuffer(4), dataView = new DataView(buffer), int8View = new Int8Array(buffer);
      int8View.set([0x00,0x01,0x02,0x03]);

      return dataView;
    }

    describe('mymodule', function() {

      it('mytest', function() {
        var dataView  = loadSimpleDataView();

        expect(dataView).toBeDefined();
        //do rest of tests
      });
    });
  }());
like image 730
pgreen2 Avatar asked Dec 26 '22 11:12

pgreen2


1 Answers

I solved the problem by encoding the binary file as a hex string, stuffing it into a blob, and calling the function that takes the File object. I'm using Jasmine to test a file load function. FileLoader is the class that I wrote that has the function loadFromFile.

  beforeEach(function() {
    return this.fileLoader = new FileLoader()  });

  it("can load this bin file safely", function() {
    var blob, fileContentsEncodedInHex;

    fileContentsEncodedInHex = ["\x45\x6e\x63\x6f\x64\x65\x49\x6e\x48\x65\x78\x42\x65\x63\x61\x75\x73\x65\x42\x69\x6e\x61\x72\x79\x46\x69\x6c\x65\x73\x43\x6f\x6e\x74\x61\x69\x6e\x55\x6e\x70\x72\x69\x6e\x74\x61\x62\x6c\x65\x43\x68\x61\x72\x61\x63\x74\x65\x72\x73"];

    blob = new Blob(fileContentsEncodedInHex);

    this.fileLoader.loadFromFile(blob);
  });

The function in the File loader class looks something like this (in coffeescript). You should definitely add error handling to your commercial code...

  #
  # Load the file
  #
  # @param [File] file
  #   The DOM file object
  #
  loadFromFile: (file) ->
    # create the file reader
    # assign the file load handler
    # read the array as a buffer, which will trigger the handler
    reader = new FileReader()
    reader.onloadend = this._handleOnLoadEnd
    reader.readAsArrayBuffer(file)
    return

I wrote the following small python app to output file contents as a hex encoded string that can be used as the contents of a javascript string. (FYI, this is my first python script in about 12 years, I'm sure it's not efficient, but it was quick) Many thanks to a co-worker for the output string. I'm not sure why the code block is getting butchered in the display. My apologies.

import sys
fulldoc = ""
with open('your file', 'rb') as readFile:  
    while 1:  character = readFile.read(1)
        if not character:
          break
        fulldoc = fulldoc + "\\x" + character.encode("hex")
print fulldoc

Additional tidbits... I don't know your exact situation but I would suggest the following...

If you need to add a new binary at any time and re-run the tests, then you should make a test for each kind of binary file that you are adding at random. Test both positive and negative files (ie, files that should work with your app, files that should not work with your app). That is what the unit test frameworks are there for. In the future, if you find that a file that breaks your app due to a bug in your code, you can fix the bug, add a new unit test to load that binary and the tests should then pass. If you happen to break the file processing code on accident at some point, the unit tests are always there to show you something is wrong.

like image 64
Lars Avatar answered Dec 29 '22 00:12

Lars