Visualizing algorithms using Processing.js

As part of one assignment for the BTC640 – Multimedia Presentations class, I have to create a visual representation of some algorithms using Processing.js.

The list of algorithms includes:

  • Stack
  • Queue
  • Cyclic Queue
  • Singly Linked List
  • Bubble Sort
  • Selection Sort
  • Insertion Sort
  • MinHeap

So far I started working on the Stack, Queue and Cyclic Queue algorithms.
You can check the code on github

I’ll keep posting updates with the work in progress.

Stay tuned! 🙂

Next ->

Advertisements

Update, ElementMatch and the $ Positional Operator on MongoDB/Mongoose

One of the biggest advantages of mongodb is the option of defining documents inside documents and by doing so creating powerful and at the same time flexible data structures.
In most cases, the deepest you will go is one level, even though mongo doesn’t set any limit on how many levels you can go inside a document, for example: A BlogPost can have an array of Comments, or an Image can have an array of Tags, and there is plenty of documentation online on how to manipulate single dimension arrays in documents. However, what if you have a multi dimensional array in a document?
Take for example the following model:

/**
* Line Item schema
*/
exports.EstimateLineItem = (function () {
 schemas.lineItem = new Schema({
    'name' : String,
    'description' : String,
    'quantity' : Number,
    'cost' : Number
  });

  return db.model('EstimateLineItem', schemas.lineItem);
})();

/**
* Estimate schema
*/
exports.Estimate = (function () {
 schemas.estimate = new Schema({
    'name' : String,
    'quoteID' : Number,
    'subTotal' : Number,
    'finalTotal' : Number,
    'creationDate' : { type: Date, default: Date.now },
    'status' : { type: String, default: "Active" },
    'lineItemSet' : [schemas.lineItem]
  });

  return db.model('Estimate', schemas.estimate);
})();

/**
* Job schema
*/
exports.Job = (function () {
 schemas.job = new Schema({
    'name' : String,
    'description' : String,
    'creationDate' : { type: Date, default: Date.now },
    'status' : { type: String, default: "Active" },
    'scheduledDates' : [Date],
    'customerID' : ObjectId,
    'estimateSet' : [schemas.estimate]
  });

  return db.model('Job', schemas.job);
})();

So a Job has an array of Estimates and an Estimate has an array of LineItems.
The problem is, how to add a new LineItem to an Estimate?
One option would be to query for a job, then loop through its estimateSet and find the selected estimate, then push a new line item to the lineItemSet and finally save back the job. However, there is a simpler way:

Job.update(
    {estimateSet: {"$elemMatch": {_id: estimateID}}},
    {$push:
      {
        "estimateSet.$.lineItemSet":
        {
          'name' : lineItem.name,
          'description' : lineItem.description,
          'quantity' : parseInt(lineItem.quantity),
          'cost' : parseInt(lineItem.cost),
          '_id': lineItem._id
        }
      }
    },
    {upsert:false,safe:true},
    function (err) {
      console.log("err: ", err);
      if (err) {
        res.send({
          "err": true,
        });
      }
      else {
        res.send({
          "err": false,
        })
      }
    }
  );

Breaking down the query:
It finds a job that has an Estimate with the specified ID:

{estimateSet: {"$elemMatch": {_id: estimateID}}}

Once the job is found, it pushes a new line item to the lineItemSet:

{$push:
      {
        "estimateSet.$.lineItemSet":
        {
          'name' : lineItem.name,
          'description' : lineItem.description,
          'quantity' : parseInt(lineItem.quantity),
          'cost' : parseInt(lineItem.cost),
          '_id': lineItem._id
        }
      }
    },

For more info:


Simple Drawing Application with ProcessingJS, part I

One of the assignments I have this semester is to create a simple drawing application.
The assignment is for the Design Patterns course , and the goal is to utilize the patterns we’ve learned so far into the application.

Here are the requirements for the assignment:

  • A tool palette to draw simple shapes
    • Line
    • Rectangle
    • Circle
    • Triangle
  • A drawing area where the shapes will be rendered
  • A menu with commands on it
    • Exit
    • Load
    • Save
    • Copy
    • Paste
    • Undo
    • Redo
    • Group
    • Ungroup
    • Color(red, green, blue, black)
    • Line Weight(1—10)
    • Style (solid, dashed)

When a tool is selected, the mouse can be used to place an instance of that shape, resize it and position it. One or more items can be selected by dragging a selection rectangle around them so that everything entirely enclosed by the rectangle is selected. When several items have been selected, they can be combined into a group. When an item in a group is moved, all members of the group are moved. The last command can be undone or performed again. The drawing can be saved into a file and loaded from a file. A simple object or group can be copied and pasted.

Your implementation should use the following patterns:

Singleton, factory or abstract factory, command, composite. It might also use mediator, façade, and any others that you deem appropriate.

I’ll try to blog about the whole process of working on this assignment.
I’m very excited about this, since I’ve been hearing and reading about ProcessingJS for a while now.
My first real contact with ProcessingJS was on the 2011 FSOSS in the workshop given by David Humphrey and Jon Buckley.
Since then I’ve been waiting for the opportunity to use ProcessingJS in one of my projects, and now it’s the perfect time!.

So far I was able to get something working.

It’s possible to create some shapes and move them around

TODO:

  • Change the color and style of the shapes
  • Deal with overlapping shapes, create option to send them to the back/front of the canvas or of other shapes.
  • Resize shapes

You can find the work in progress here


Bug 728893 – Allow mochitest iframe to go fullscreen

Bug 728893 was encountered while implementing PointerLock.

A Quick Overview on Mochitests

By default an iframe is not allowed to go fullscreen mode, and since all the mochitests are run inside and iframe, if one of the mochitest needed to go fullscreen it would not work (pointerlock for example)

There are two different ways to run mochitests. With runtests.py or mochitest-plain(ends up running runtests.py)

  1. python ./obj-dir/_tests/testing/mochitest/runtest.py –test-path=dom/tests/mochitest/pointerlock
  2. TEST_PATH=/dom/test/mochitest/pointerlock make -C obj-dir/ mochitest-plain

The first one calls explicit the runtests.py, that is the script that creates the http server
The second one will run mochitest-plain.
Now what is mochitest-plain?
First we need to look at the root’s Makefile
/Makefile.in
Line 129 is including testsuite-targets.mk, that’s where mochitest-plain is defined

127 ifdef ENABLE_TESTS
128 # Additional makefile targets to call automated test suites
129 include $(topsrcdir)/testing/testsuite-targets.mk
130 endif

mochitest-plain
Here is where mochitest-plain is defined, it calls $(RUN_MOCHITEST)

128 mochitest-plain:
129 	$(RUN_MOCHITEST)
130 	$(CHECK_TEST_ERROR)

RUN_MOCHITEST
In the end runtests.py is ran with some default flags

64 RUN_MOCHITEST = \
65 	rm -f ./$@.log && \
66 	$(PYTHON) _tests/testing/mochitest/runtests.py --autorun --close-when-done \
67 	  --console-level=INFO --log-file=./$@.log --file-level=INFO \
68 	  --failure-file=$(call core_abspath,_tests/testing/mochitest/makefailures.json)  \
69 	  $(SYMBOLS_PATH) $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS)

**Running the tests with mochitest-plain will add some flags to the execution of runtest.py

[diogogmt@rome mozilla-central-diogogmt]$ TEST_PATH=dom/tests/mochitest/pointerlock/ make -C ff-dbg/ mochitest-plain
make: Entering directory `/home/diogogmt/mozilla-central-diogogmt/ff-dbg’
rm -f ./mochitest-plain.log && /usr/bin/python2.7 _tests/testing/mochitest/runtests.py –autorun –close-when-done –console-level=INFO –log-file=./mochitest-plain.log –file-level=INFO –failure-file=/home/diogogmt/mozilla-central-diogogmt/ff-dbg/_tests/testing/mochitest/makefailures.json –symbols-path=./dist/crashreporter-symbols –test-path=dom/tests/mochitest/pointerlock/

The flag –close-when-done is set by default. However sometimes you may want to leave the browser window open for debug purposes. I’m not sure if there is a way to tell mochitest-plain not run the runtests.py with the –close-when-done flag not set. What I usually do is run the tests calling directly runtest.py, since it runs withouth any flags, giving me more flexbility.

When not specifying a file, the mochitest will load all the files of the dir and run them inside the harness

For example:
dom/tests/mochitest/Makefile.in
The mochitest Makefile contains the list of the dirs of some tests

45 DIRS	+= \
46 	dom-level0 \
47 	dom-level1-core \
48 	dom-level2-core \
49 	dom-level2-html \
50 	ajax \
51 	bugs \
52 	chrome \
53 	general \
54 	whatwg \
55 	geolocation \
56 	localstorage \
57 	orientation \
58 	sessionstorage \
59 	storageevent \
60 	$(NULL

dom/test/mochitest/geolocation/Makefile.in
In the geolocation Makefile all the tests for that module are listed

41 relativesrcdir	= dom/tests/mochitest/geolocation
42
43 include $(DEPTH)/config/autoconf.mk
44
45 include $(topsrcdir)/config/rules.mk
46
47 _TEST_FILES	= \
48 		test_allowCurrent.html \
49 		test_allowWatch.html \
50 		test_cancelCurrent.html \
51 		test_cancelWatch.html \
52 		test_clearWatch.html \
53 		test_clearWatch_invalid.html \
54 		test_manyCurrentConcurrent.html \
55 		test_manyCurrentSerial.html \
56 		test_manyWatchConcurrent.html \
57 		test_manyWatchSerial.html \
58 		test_manyWindows.html \
59 		test_optional_api_params.html \
60 		test_shutdown.html \
61 		test_windowClose.html \
62 		test_timerRestartWatch.html \
63 		test_worseAccuracyDoesNotBlockCallback.html \
64 		geolocation.html \
65 		geolocation_common.js  \
66 		network_geolocation.sjs \
67 		windowTest.html \
68 		$(NULL)
69
70 libs:: 	$(_TEST_FILES)
71 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)

From line 48 to 67 are listed all the test files
Line 41 is defined the path where the files are located
Line 71 is the path where the files will be copied after compiling firefox, for example:
/obj-dir/_tests/testing/mochitest/tests/dom/tests/mochitest/geolocation

Running single tests
When running the test as a stand alone, there is no need for an iframe, the test is loaded in the parent window, so the element is allowed to go fullscreen, different from when the tests are run inside the harness.

 

The Problem

When we first started writing mochitests for pointerlock we had to find a way to run the tests inside the harness while setting them to fullscreen.
The solution was to use the same approach as the fullscreen tests. To create a harness inside the harness, for example

Solution

The solution was simple, we just had to add the attribute mozallowfullscreen=true to the mochitest iframe.
However, there are three places where the iframe gets defined:

server.js is used for mochitest-plain
browser_harness.xul is used for mochitest-chrome and mochitest-browser-chrome
plain-loop remains a mystery 😛

For server.js:

IFRAME({scrolling: "no", id: "testframe", width: "500", height: "300", mozallowfullscreen: "true"})

For browser_harness.xul

<iframe id="testframe" scrolling="no" width="550" height="350"></iframe>

You can find the complete patch here

Sanity tests

To make sure the mochitest framework works, before running all the tests a list of sanity tests is executed to test the framework itself.
You can see the list of the tests in the /testing/mochitest/tests/Makefile.in

43 relativesrcdir  = testing/mochitest/tests
44
45 include $(DEPTH)/config/autoconf.mk
46
47 PARALLEL_DIRS = \
48 	MochiKit-1.4.2 \
49 	SimpleTest \
50 	browser \
51 	$(NULL)
52
53 include $(topsrcdir)/config/rules.mk
54
55 _TEST_FILES = \
56   test_sanity.html \
57   test_sanityException.html \
58   test_sanityException2.html \
59   test_sanityWindowSnapshot.html \
60   test_SpecialPowersExtension.html \
61   test_SpecialPowersExtension2.html \
62   file_SpecialPowersFrame1.html \
63   $(NULL)
64
65 ifneq ($(OS_TARGET),Android)
66 # Disabled on Android for permaorange, see bug 688052
67   _TEST_FILES += \
68   test_sanityEventUtils.html \
69   test_sanitySimpletest.html
70 endif
71 # Copy the sanity tests into a subdirectory, so the top level is all dirs
72 # in the test screen.
73 libs:: $(_TEST_FILES)
74 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/$(relativesrcdir)/Harness_sanity

One thing to notice is the folder the sanity tests are copied to: Harness_sanity

After Firefox is compiled, all the tests are copied to /obj-dir/_tests/testing/mochitest/tests
So to run the geolocation tests for example:

  • TEST_PATH=dom/tests/mochitest/geolocation

The Harness_sanity on the other hand:

  • TEST_PATH=Harness_sanity

Since allowing the iframe to go fullscreen mode could break other tests we decided to add a check on SimpleTest.finish() to cancel fullscreen mode if the test forgets to cancel it

+    // Cancel element fullscreen mode due to Bug 728893
+    if (document && document.mozFullScreenElement) {
+        document.mozCancelFullScreen();
+    }

So now we needed a test to make sure SimpleTest.finish was actually cancelling fullscreen.
My first thought was to have two test files, test_fullscreen1.html and test_fullscreen2.html. On test_fullscreen1.html the element would be set to fullscreen mode and without cancelling call SimpleTest.finish(), then on test_fullscreen2.html would check the fullscreen status of the iframe, it should be false since SimpleTest.finish() supposed to cancel it.
However, there was an easier way to write the test, with just one file instead of two.

+
+
+
+  Test for Bug 728893
+<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>+<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+
+
+
+<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=728893" target="_blank">
+ Mozilla Bug
+</a>
+</pre>
<div id="div">+</div>
<pre>
+</pre>
<pre id="test">+<script type="text/javascript">// <![CDATA[
+
+  /** Test for Bug 728893
+      Checks if SimpleTest.finish cancels fullscreen mode
+      The assertion happens after calling SimpleTest.finish
+      Running the test without the harness won't work
+  **/
+
+  SpecialPowers.setBoolPref("full-screen-api.enabled", true);
+  SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only",
+                                 false);
+
+  SimpleTest.waitForExplicitFinish();
+
+  var div = document.getElementById("div");
+
+  document.addEventListener("mozfullscreenchange", function (e) {
+    if (document.mozFullScreenElement === div) {
+      SimpleTest.finish();
+    }
+    else {
+      is(false, document.mozFullScreen,
+        "SimpleTest.finish should cancel fullscreen mode");
+    }
+  }, false);
+
+  function start() {
+    SimpleTest.waitForFocus(function() {
+      div.mozRequestFullScreen();
+    });
+  }
+
+
// ]]></script>
+
+
+

The assertion “is(false, document.mozFullScreen, “SimpleTest.finish should cancel fullscreen mode”);” is happening after SimpleTest.finish is called, the reason that it is possible to still make assertions after calling SimpleTest.finish is because the test itself is being run inside the mochitest harness

SimpleTest.js

678     if (parentRunner) {
679         /* We're running in an iframe, and the parent has a TestRunner */
680         parentRunner.testFinished(SimpleTest._tests);
681     } else {
682         SimpleTest.showReport();
683     }

Line 678 checks if the test is being run inside a harness, if true it goes to the next test, but it doesn’t terminates the current one.
Different from line 682 that call showReport, terminating the current test and displaying the results.

**Big thans to Clint(ctalbert) for all the help with this bug