Use Jquery's Qunit tests to create some unit tests for javascript
cover Use Jquery's Qunit tests to create some unit tests for javascript
Use Jquery's Qunit tests to create some unit tests for javascript.
The following changes since commit c348fa50186fb0796bc7b793c4b8d710419f2a0d:
bitbake: toaster: move code from setup_lv_tests to setUp (2015-08-17 14:41:45 +0100)
are available in the git repository at:
git://git.yoctoproject.org/poky-contrib bavery/submit/michaelw/20150817_qunit-tests
http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=bavery/submit/michaelw/20150817_qunit-tests
Michael Wood (1):
toastergui: Add frontend javascript unit tests
lib/toaster/toastergui/static/js/tests/test.js | 175 +++++++++++++++++++++ .../toastergui/templates/js-unit-tests.html | 39 +++++ lib/toaster/toastergui/urls.py | 3 + lib/toaster/toastergui/views.py | 16 ++ 4 files changed, 233 insertions(+) create mode 100644 bitbake/lib/toaster/toastergui/static/js/tests/test.js create mode 100644 bitbake/lib/toaster/toastergui/templates/js-unit-tests.html
Signature · 1 line
1.9.1
PATCH 1/1 toastergui: Add frontend javascript unit tests
From: Michael Wood <[email protected]>
Use Jquery's Qunit tests to create some unit tests for javascript components used in toaster.
--- lib/toaster/toastergui/static/js/tests/test.js | 175 +++++++++++++++++++++ .../toastergui/templates/js-unit-tests.html | 39 +++++ lib/toaster/toastergui/urls.py | 3 + lib/toaster/toastergui/views.py | 16 ++ 4 files changed, 233 insertions(+) create mode 100644 bitbake/lib/toaster/toastergui/static/js/tests/test.js create mode 100644 bitbake/lib/toaster/toastergui/templates/js-unit-tests.html
lib/toaster/toastergui/static/js/tests/test.js new file +175 -0
@@ -0,0 +1,175 @@ +"use strict"; +/* Unit tests for Toaster's JS */ + +/* libtoaster tests */ + +QUnit.test("Layer alert notification", function(assert) { + var layer = { + "layerdetailurl":"/toastergui/project/1/layer/22", + "vcs_url":"git://example.com/example.git", + "detail":"[ git://example.com/example.git | master ]", + "vcs_reference":"master", + "id": 22, + "name":"meta-example" + }; + + var correctResponse = "You have added <strong>3</strong> layers to your project: <a id=\"layer-affected-name\" href=\"/toastergui/project/1/layer/22\">meta-example</a> and its dependencies <a href=\"/toastergui/project/1/layer/9\" data-original-title=\"\" title=\"\">meta-example-two</a>, <a href=\"/toastergui/project/1/layer/9\" data-original-title=\"\" title=\"\">meta-example-three</a>"; + + var layerDepsList = [ + { + "layerdetailurl":"/toastergui/project/1/layer/9", + "vcs_url":"git://example.com/example.git", + "detail":"[ git://example.com/example.git | master ]", + "vcs_reference":"master", + "id": 9, + "name":"meta-example-two" + }, + { + "layerdetailurl":"/toastergui/project/1/layer/9", + "vcs_url":"git://example.com/example.git", + "detail":"[ git://example.com/example.git | master ]", + "vcs_reference":"master", + "id": 10, + "name":"meta-example-three" + }, + ]; + + var msg = libtoaster.makeLayerAddRmAlertMsg(layer, layerDepsList, true); + var test = $("<div></div>"); + + test.html(msg); + + assert.equal(test.children("strong").text(), "3"); + assert.equal(test.children("a").length, 3); +}); + +QUnit.test("Project info", function(assert){ + var done = assert.async(); + libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl, function(prjInfo){ + assert.ok(prjInfo.machine.name); + assert.ok(prjInfo.releases.length > 0); + assert.ok(prjInfo.layers.length > 0); + assert.ok(prjInfo.freqtargets); + assert.ok(prjInfo.release); + done(); + }); +}); + +QUnit.test("Show notification", function(assert){ + var msg = "Testing"; + var element = $("#change-notification-msg"); + + libtoaster.showChangeNotification(msg); + + assert.equal(element.text(), msg); + assert.ok(element.is(":visible")); + + $("#change-notification").hide(); +}); + +var layer = { + "id": 91, + "name": "meta-crystalforest", + "layerdetailurl": "/toastergui/project/4/layer/91" +}; + +QUnit.test("Add layer", function(assert){ + var done = assert.async(); + + /* Wait for the modal to be added to the dom */ + var checkModal = setInterval(function(){ + if ($("#dependencies-modal").length > 0) { + $("#dependencies-modal .btn-primary").click(); + clearInterval(checkModal); + } + }, 200); + + libtoaster.addRmLayer(layer, true, function(deps){ + assert.equal(deps.length, 1); + done(); + }); + +}); + +QUnit.test("Rm layer", function(assert){ + var done = assert.async(); + + libtoaster.addRmLayer(layer, false, function(deps){ + assert.equal(deps.length, 0); + done(); + }); + +}); + +QUnit.test("Parse url params", function(assert){ + var params = libtoaster.parseUrlParams(); + assert.ok(params); +}); + +QUnit.test("Dump url params", function(assert){ + var params = libtoaster.dumpsUrlParams(); + assert.ok(params); +}); + +QUnit.test("Make typeaheads", function(assert){ + var layersT = $("#layers"); + var machinesT = $("#machines"); + var projectsT = $("#projects"); + var recipesT = $("#recipes"); + + libtoaster.makeTypeahead(layersT, + libtoaster.ctx.layersTypeAheadUrl, {}, function(){}); + + libtoaster.makeTypeahead(machinesT, + libtoaster.ctx.machinesTypeAheadUrl, {}, function(){}); + + libtoaster.makeTypeahead(projectsT, + libtoaster.ctx.projectsTypeAheadUrl, {}, function(){}); + + libtoaster.makeTypeahead(recipesT, + libtoaster.ctx.recipesTypeAheadUrl, {}, function(){}); + + assert.ok(recipesT.data('typeahead')); + assert.ok(layersT.data('typeahead')); + assert.ok(projectsT.data('typeahead')); + assert.ok(recipesT.data('typeahead')); +}); + + + +/* Page init functions */ + +QUnit.test("Import layer page init", function(assert){ + assert.throws(importLayerPageInit()); +}); + +QUnit.test("Project page init", function(assert){ + assert.throws(projectPageInit()); +}); + +QUnit.test("Layer details page init", function(assert){ + assert.throws(layerDetailsPageInit()); +}); + +QUnit.test("Layer btns init", function(assert){ + assert.throws(layerBtnsInit({ projectLayers : [] })); +}); + +QUnit.test("Table init", function(assert){ + assert.throws(tableInit({ url : tableUrl })); +}); + +$(document).ajaxError(function(event, jqxhr, settings, errMsg){ + if (errMsg === 'abort') + return; + + QUnit.test("Ajax error", function(assert){ + assert.notOk(jqxhr.responseText); + }); +}); + + + + + +
lib/toaster/toastergui/templates/js-unit-tests.html new file +39 -0
@@ -0,0 +1,39 @@ +{% extends "base.html" %} +{% load projecttags %} +{% load humanize %} +{% load static %} +{% block pagecontent %} + +<link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.18.0.css" /> + +<script src="//code.jquery.com/qunit/qunit-1.18.0.js"></script> + +<script src="{% static 'js/layerDepsModal.js' %}"></script> +<script src="{% static 'js/projectpage.js' %}"></script> + +<script src="{% static 'js/bootstrap.min.js' %}"></script> +<script src="{% static 'js/filtersnippet.js' %}"></script> +<script src="{% static 'js/importlayer.js' %}"></script> +<script src="{% static 'js/prettify.js' %}"></script> +<script src="{% static 'js/layerBtn.js' %}"></script> +<script src="{% static 'js/layerDepsModal.js' %}"></script> +<script src="{% static 'js/projectpage.js' %}"></script> +<script src="{% static 'js/layerdetails.js' %}"></script> +<script src="{% static 'js/table.js' %}"></script> + +<script> + var tableUrl = '{% url 'projectlayers' project.pk %}'; +</script> + +<script src="{% static 'js/tests/test.js' %}"></script> + +<div id="qunit"></div> + +<input type="text" id="layers" placeholder="layers" ></input> +<input type="text" id="recipes" placeholder="recipes"></input> +<input type="text" id="projects" placeholder="projects"></input> +<input type="text" id="machines" placeholder="machines"></input> + +{% endblock %} + +
lib/toaster/toastergui/urls.py +3 -0
@@ -145,6 +145,9 @@ urlpatterns = patterns('toastergui.views', url(r'^xhr_importlayer/$', 'xhr_importlayer', name='xhr_importlayer'), url(r'^xhr_updatelayer/$', 'xhr_updatelayer', name='xhr_updatelayer'), + # JS Unit tests + url(r'^js-unit-tests/$', 'jsunittests', name='js-unit-tests'), + # default redirection url(r'^$', RedirectView.as_view( url= 'landing')), )
lib/toaster/toastergui/views.py +16 -0
@@ -27,6 +27,7 @@ from django.shortcuts import render, redirect from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe, LogMessage, Variable from orm.models import Task_Dependency, Recipe_Dependency, Package, Package_File, Package_Dependency from orm.models import Target_Installed_Package, Target_File, Target_Image_File, BuildArtifact +from orm.models import BitbakeVersion from bldcontrol import bbcontroller from django.views.decorators.cache import cache_control from django.core.urlresolvers import reverse
@@ -2255,6 +2256,21 @@ if True: return context + def jsunittests(request): + """ Provides a page for the js unit tests """ + bbv = BitbakeVersion.objects.filter(branch="master").first() + release = Release.objects.filter(bitbake_version=bbv).first() + + name = "_js_unit_test_prj_" + + # If there is an existing project by this name delete it. We don't want + # Lots of duplicates cluttering up the projects. + Project.objects.filter(name=name).delete() + + new_project = Project.objects.create_project(name=name, release=release) + + context = { 'project' : new_project } + return render(request, "js-unit-tests.html", context) from django.views.decorators.csrf import csrf_exempt @csrf_exempt
Signature · 1 line
1.9.1
Re: [PATCH 1/1] toastergui: Add frontend javascript unit tests
Quoted 280 lines · brian avery
From: Michael Wood <[email protected]>
Use Jquery's Qunit tests to create some unit tests for javascript components used in toaster.
Signed-off-by Michael Wood <[email protected]>Signed-off-by brian avery <[email protected]>--- lib/toaster/toastergui/static/js/tests/test.js | 175 +++++++++++++++++++++ .../toastergui/templates/js-unit-tests.html | 39 +++++ lib/toaster/toastergui/urls.py | 3 + lib/toaster/toastergui/views.py | 16 ++ 4 files changed, 233 insertions(+)create mode 100644 bitbake/lib/toaster/toastergui/static/js/tests/test.js create mode 100644 bitbake/lib/toaster/toastergui/templates/js-unit-tests.html
lib/toaster/toastergui/static/js/tests/test.js new file +175
-0@@ -0,0 +1,175 @@ +"use strict"; +/* Unit tests for Toaster's JS */ + +/* libtoaster tests */ + +QUnit.test("Layer alert notification", function(assert) { + var layer = { + "layerdetailurl":"/toastergui/project/1/layer/22", + "vcs_url":"git://example.com/example.git", + "detail":"[ git://example.com/example.git | master ]", + "vcs_reference":"master", + "id": 22, + "name":"meta-example" + }; + + var correctResponse = "You have added <strong>3</strong> layers to your project: <a id=\"layer-affected-name\" href=\"/toastergui/project/1/layer/22\">meta-example</a> and its dependencies <a href=\"/toastergui/project/1/layer/9\" data-original-title=\"\" title=\"\">meta-example-two</a>, <a href=\"/toastergui/project/1/layer/9\" data-original-title=\"\" title=\"\">meta-example-three</a>"; + + var layerDepsList = [ + { + "layerdetailurl":"/toastergui/project/1/layer/9", + "vcs_url":"git://example.com/example.git", + "detail":"[ git://example.com/example.git | master ]", + "vcs_reference":"master", + "id": 9, + "name":"meta-example-two" + }, + { + "layerdetailurl":"/toastergui/project/1/layer/9", + "vcs_url":"git://example.com/example.git", + "detail":"[ git://example.com/example.git | master ]", + "vcs_reference":"master", + "id": 10, + "name":"meta-example-three" + }, + ]; + + var msg = libtoaster.makeLayerAddRmAlertMsg(layer, layerDepsList, true); + var test = $("<div></div>"); + + test.html(msg); + + assert.equal(test.children("strong").text(), "3"); + assert.equal(test.children("a").length, 3); +}); + +QUnit.test("Project info", function(assert){ + var done = assert.async(); + libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl, function(prjInfo){ + assert.ok(prjInfo.machine.name); + assert.ok(prjInfo.releases.length > 0); + assert.ok(prjInfo.layers.length > 0); + assert.ok(prjInfo.freqtargets); + assert.ok(prjInfo.release); + done(); + }); +}); + +QUnit.test("Show notification", function(assert){ + var msg = "Testing"; + var element = $("#change-notification-msg"); + + libtoaster.showChangeNotification(msg); + + assert.equal(element.text(), msg); + assert.ok(element.is(":visible")); + + $("#change-notification").hide(); +}); + +var layer = { + "id": 91, + "name": "meta-crystalforest", + "layerdetailurl": "/toastergui/project/4/layer/91" +}; + +QUnit.test("Add layer", function(assert){ + var done = assert.async(); + + /* Wait for the modal to be added to the dom */ + var checkModal = setInterval(function(){ + if ($("#dependencies-modal").length > 0) { + $("#dependencies-modal .btn-primary").click(); + clearInterval(checkModal); + } + }, 200); + + libtoaster.addRmLayer(layer, true, function(deps){ + assert.equal(deps.length, 1); + done(); + }); + +}); + +QUnit.test("Rm layer", function(assert){ + var done = assert.async(); + + libtoaster.addRmLayer(layer, false, function(deps){ + assert.equal(deps.length, 0); + done(); + }); + +}); + +QUnit.test("Parse url params", function(assert){ + var params = libtoaster.parseUrlParams(); + assert.ok(params); +}); + +QUnit.test("Dump url params", function(assert){ + var params = libtoaster.dumpsUrlParams(); + assert.ok(params); +}); + +QUnit.test("Make typeaheads", function(assert){ + var layersT = $("#layers"); + var machinesT = $("#machines"); + var projectsT = $("#projects"); + var recipesT = $("#recipes"); + + libtoaster.makeTypeahead(layersT, + libtoaster.ctx.layersTypeAheadUrl, {}, function(){}); + + libtoaster.makeTypeahead(machinesT, + libtoaster.ctx.machinesTypeAheadUrl, {}, function(){}); + + libtoaster.makeTypeahead(projectsT, + libtoaster.ctx.projectsTypeAheadUrl, {}, function(){}); + + libtoaster.makeTypeahead(recipesT, + libtoaster.ctx.recipesTypeAheadUrl, {}, function(){}); + + assert.ok(recipesT.data('typeahead')); + assert.ok(layersT.data('typeahead')); + assert.ok(projectsT.data('typeahead')); + assert.ok(recipesT.data('typeahead')); +}); + + + +/* Page init functions */ + +QUnit.test("Import layer page init", function(assert){ + assert.throws(importLayerPageInit()); +}); + +QUnit.test("Project page init", function(assert){ + assert.throws(projectPageInit()); +}); + +QUnit.test("Layer details page init", function(assert){ + assert.throws(layerDetailsPageInit()); +}); + +QUnit.test("Layer btns init", function(assert){ + assert.throws(layerBtnsInit({ projectLayers : [] })); +}); + +QUnit.test("Table init", function(assert){ + assert.throws(tableInit({ url : tableUrl })); +}); + +$(document).ajaxError(function(event, jqxhr, settings, errMsg){ + if (errMsg === 'abort') + return; + + QUnit.test("Ajax error", function(assert){ + assert.notOk(jqxhr.responseText); + }); +}); + + + + + +lib/toaster/toastergui/templates/js-unit-tests.html new file +39
-0@@ -0,0 +1,39 @@ +{% extends "base.html" %} +{% load projecttags %} +{% load humanize %} +{% load static %} +{% block pagecontent %} + +<link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.18.0.css" /> + +<script src="//code.jquery.com/qunit/qunit-1.18.0.js"></script> + +<script src="{% static 'js/layerDepsModal.js' %}"></script> +<script src="{% static 'js/projectpage.js' %}"></script> + +<script src="{% static 'js/bootstrap.min.js' %}"></script> +<script src="{% static 'js/filtersnippet.js' %}"></script> +<script src="{% static 'js/importlayer.js' %}"></script> +<script src="{% static 'js/prettify.js' %}"></script> +<script src="{% static 'js/layerBtn.js' %}"></script> +<script src="{% static 'js/layerDepsModal.js' %}"></script> +<script src="{% static 'js/projectpage.js' %}"></script> +<script src="{% static 'js/layerdetails.js' %}"></script> +<script src="{% static 'js/table.js' %}"></script> + +<script> + var tableUrl = '{% url 'projectlayers' project.pk %}'; +</script> + +<script src="{% static 'js/tests/test.js' %}"></script> + +<div id="qunit"></div> + +<input type="text" id="layers" placeholder="layers" ></input> +<input type="text" id="recipes" placeholder="recipes"></input> +<input type="text" id="projects" placeholder="projects"></input> +<input type="text" id="machines" placeholder="machines"></input> + +{% endblock %} + +lib/toaster/toastergui/urls.py +3
-0@@ -145,6 +145,9 @@ urlpatterns = patterns('toastergui.views', url(r'^xhr_importlayer/$', 'xhr_importlayer', name='xhr_importlayer'), url(r'^xhr_updatelayer/$', 'xhr_updatelayer', name='xhr_updatelayer'), + # JS Unit tests + url(r'^js-unit-tests/$', 'jsunittests', name='js-unit-tests'), + # default redirection url(r'^$', RedirectView.as_view( url= 'landing')), )lib/toaster/toastergui/views.py +9
-0@@ -27,6 +27,7 @@ from django.shortcuts import render, redirect from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe, LogMessage, Variable from orm.models import Task_Dependency, Recipe_Dependency, Package, Package_File, Package_Dependency from orm.models import Target_Installed_Package, Target_File, Target_Image_File, BuildArtifact +from orm.models import BitbakeVersion from bldcontrol import bbcontroller from django.views.decorators.cache import cache_control from django.core.urlresolvers import reverse@@ -2255,6 +2256,21 @@ if True: return context + def jsunittests(request): + """ Provides a page for the js unit tests """ + bbv = BitbakeVersion.objects.filter(branch="master").first() + release = Release.objects.filter(bitbake_version=bbv).first() + + name = "_js_unit_test_prj_" + + # If there is an existing project by this name delete it. We don't want
lib/toaster/toastergui/views.py if True: · line 2276
Quoted 10 lines
lib/toaster/toastergui/views.py +7
-0+ # Lots of duplicates cluttering up the projects. + Project.objects.filter(name=name).delete() + + new_project = Project.objects.create_project(name=name, release=release) + + context = { 'project' : new_project } + return render(request, "js-unit-tests.html", context) from django.views.decorators.csrf import csrf_exempt @csrf_exempt
This patch seems to have landed without the new files
http://cgit.openembedded.org/bitbake/commit/?id=1c2f6b9b7b9e700146944b9d6d2114e0d014ee81
-rw-r--r-- lib/toaster/toastergui/urls.py 3
-rwxr-xr-x lib/toaster/toastergui/views.py 16
2 files changed, 19 insertions, 0 deletions
Re: [PATCH 1/1] toastergui: Add frontend javascript unit tests
yes, the following files were new in the patch and were not created:lib/toaster/toastergui/static/js/tests/test.js b/lib/toaster/toastergui/static/js/tests/test.js lib/toaster/toastergui/templates/js-unit-tests.html b/lib/toaster/toastergui/templates/js-unit-tests.html
-bavery
Quoted 320 lines · Michael Wood
Quoted 304 lines · brian avery
From: Michael Wood <[email protected]>
Use Jquery's Qunit tests to create some unit tests for javascript components used in toaster.
Signed-off-by Michael Wood <[email protected]>Signed-off-by brian avery <[email protected]>--- lib/toaster/toastergui/static/js/tests/test.js | 175 +++++++++++++++++++++ .../toastergui/templates/js-unit-tests.html | 39 +++++ lib/toaster/toastergui/urls.py | 3 + lib/toaster/toastergui/views.py | 16 ++ 4 files changed, 233 insertions(+)create mode 100644
bitbake/lib/toaster/toastergui/static/js/tests/test.js
create mode 100644
bitbake/lib/toaster/toastergui/templates/js-unit-tests.htmllib/toaster/toastergui/static/js/tests/test.js new file +16
-0@@ -0,0 +1,175 @@ +"use strict"; +/* Unit tests for Toaster's JS */ + +/* libtoaster tests */ + +QUnit.test("Layer alert notification", function(assert) { + var layer = { + "layerdetailurl":"/toastergui/project/1/layer/22", + "vcs_url":"git://example.com/example.git", + "detail":"[ git://example.com/example.git | master ]", + "vcs_reference":"master", + "id": 22, + "name":"meta-example" + }; + + var correctResponse = "You have added <strong>3</strong> layers to yourproject: <a id=\"layer-affected-name\" href=\"/toastergui/project/1/layer/22\">meta-example</a> and its dependencies <a href=\"/toastergui/project/1/layer/9\" data-original-title=\"\" title=\"\">meta-example-two</a>, <a href=\"/toastergui/project/1/layer/9\" data-original-title=\"\" title=\"\">meta-example-three</a>";
lib/toaster/toastergui/static/js/tests/test.js new file +21
-0+ + var layerDepsList = [ + { + "layerdetailurl":"/toastergui/project/1/layer/9", + "vcs_url":"git://example.com/example.git", + "detail":"[ git://example.com/example.git | master ]", + "vcs_reference":"master", + "id": 9, + "name":"meta-example-two" + }, + { + "layerdetailurl":"/toastergui/project/1/layer/9", + "vcs_url":"git://example.com/example.git", + "detail":"[ git://example.com/example.git | master ]", + "vcs_reference":"master", + "id": 10, + "name":"meta-example-three" + }, + ]; + + var msg = libtoaster.makeLayerAddRmAlertMsg(layer, layerDepsList,true);
lib/toaster/toastergui/static/js/tests/test.js new file +11
-0+ var test = $("<div></div>"); + + test.html(msg); + + assert.equal(test.children("strong").text(), "3"); + assert.equal(test.children("a").length, 3); +}); + +QUnit.test("Project info", function(assert){ + var done = assert.async(); + libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl,function(prjInfo){
lib/toaster/toastergui/static/js/tests/test.js new file +127
-0+ assert.ok(prjInfo.machine.name); + assert.ok(prjInfo.releases.length > 0); + assert.ok(prjInfo.layers.length > 0); + assert.ok(prjInfo.freqtargets); + assert.ok(prjInfo.release); + done(); + }); +}); + +QUnit.test("Show notification", function(assert){ + var msg = "Testing"; + var element = $("#change-notification-msg"); + + libtoaster.showChangeNotification(msg); + + assert.equal(element.text(), msg); + assert.ok(element.is(":visible")); + + $("#change-notification").hide(); +}); + +var layer = { + "id": 91, + "name": "meta-crystalforest", + "layerdetailurl": "/toastergui/project/4/layer/91" +}; + +QUnit.test("Add layer", function(assert){ + var done = assert.async(); + + /* Wait for the modal to be added to the dom */ + var checkModal = setInterval(function(){ + if ($("#dependencies-modal").length > 0) { + $("#dependencies-modal .btn-primary").click(); + clearInterval(checkModal); + } + }, 200); + + libtoaster.addRmLayer(layer, true, function(deps){ + assert.equal(deps.length, 1); + done(); + }); + +}); + +QUnit.test("Rm layer", function(assert){ + var done = assert.async(); + + libtoaster.addRmLayer(layer, false, function(deps){ + assert.equal(deps.length, 0); + done(); + }); + +}); + +QUnit.test("Parse url params", function(assert){ + var params = libtoaster.parseUrlParams(); + assert.ok(params); +}); + +QUnit.test("Dump url params", function(assert){ + var params = libtoaster.dumpsUrlParams(); + assert.ok(params); +}); + +QUnit.test("Make typeaheads", function(assert){ + var layersT = $("#layers"); + var machinesT = $("#machines"); + var projectsT = $("#projects"); + var recipesT = $("#recipes"); + + libtoaster.makeTypeahead(layersT, + libtoaster.ctx.layersTypeAheadUrl, {}, function(){}); + + libtoaster.makeTypeahead(machinesT, + libtoaster.ctx.machinesTypeAheadUrl, {}, function(){}); + + libtoaster.makeTypeahead(projectsT, + libtoaster.ctx.projectsTypeAheadUrl, {}, function(){}); + + libtoaster.makeTypeahead(recipesT, + libtoaster.ctx.recipesTypeAheadUrl, {}, function(){}); + + assert.ok(recipesT.data('typeahead')); + assert.ok(layersT.data('typeahead')); + assert.ok(projectsT.data('typeahead')); + assert.ok(recipesT.data('typeahead')); +}); + + + +/* Page init functions */ + +QUnit.test("Import layer page init", function(assert){ + assert.throws(importLayerPageInit()); +}); + +QUnit.test("Project page init", function(assert){ + assert.throws(projectPageInit()); +}); + +QUnit.test("Layer details page init", function(assert){ + assert.throws(layerDetailsPageInit()); +}); + +QUnit.test("Layer btns init", function(assert){ + assert.throws(layerBtnsInit({ projectLayers : [] })); +}); + +QUnit.test("Table init", function(assert){ + assert.throws(tableInit({ url : tableUrl })); +}); + +$(document).ajaxError(function(event, jqxhr, settings, errMsg){ + if (errMsg === 'abort') + return; + + QUnit.test("Ajax error", function(assert){ + assert.notOk(jqxhr.responseText); + }); +}); + + + + + +lib/toaster/toastergui/templates/js-unit-tests.html new file +39
-0@@ -0,0 +1,39 @@ +{% extends "base.html" %} +{% load projecttags %} +{% load humanize %} +{% load static %} +{% block pagecontent %} + +<link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.18.0.css" /> + +<script src="//code.jquery.com/qunit/qunit-1.18.0.js"></script> + +<script src="{% static 'js/layerDepsModal.js' %}"></script> +<script src="{% static 'js/projectpage.js' %}"></script> + +<script src="{% static 'js/bootstrap.min.js' %}"></script> +<script src="{% static 'js/filtersnippet.js' %}"></script> +<script src="{% static 'js/importlayer.js' %}"></script> +<script src="{% static 'js/prettify.js' %}"></script> +<script src="{% static 'js/layerBtn.js' %}"></script> +<script src="{% static 'js/layerDepsModal.js' %}"></script> +<script src="{% static 'js/projectpage.js' %}"></script> +<script src="{% static 'js/layerdetails.js' %}"></script> +<script src="{% static 'js/table.js' %}"></script> + +<script> + var tableUrl = '{% url 'projectlayers' project.pk %}'; +</script> + +<script src="{% static 'js/tests/test.js' %}"></script> + +<div id="qunit"></div> + +<input type="text" id="layers" placeholder="layers" ></input> +<input type="text" id="recipes" placeholder="recipes"></input> +<input type="text" id="projects" placeholder="projects"></input> +<input type="text" id="machines" placeholder="machines"></input> + +{% endblock %} + +lib/toaster/toastergui/urls.py +2
-0@@ -145,6 +145,9 @@ urlpatterns = patterns('toastergui.views', url(r'^xhr_importlayer/$', 'xhr_importlayer', name='xhr_importlayer'), url(r'^xhr_updatelayer/$', 'xhr_updatelayer', name='xhr_updatelayer'), + # JS Unit tests + url(r'^js-unit-tests/$', 'jsunittests', name='js-unit-tests'), + # default redirection url(r'^$', RedirectView.as_view( url= 'landing')), )lib/toaster/toastergui/views.py +0
-0@@ -27,6 +27,7 @@ from django.shortcuts import render, redirect from orm.models import Build, Target, Task, Layer, Layer_Version,Recipe, LogMessage, Variable
from orm.models importTask_Dependency,Recipe_Dependency, Package,Package_File,Package_Dependency
from orm.models importTarget_Installed_Package,Target_File,Target_Image_File, BuildArtifactlib/toaster/toastergui/views.py +8
-0+from orm.models import BitbakeVersion from bldcontrol import bbcontroller from django.views.decorators.cache import cache_control from django.core.urlresolvers import reverse@@ -2255,6 +2256,21 @@ if True: return context + def jsunittests(request): + """ Provides a page for the js unit tests """ + bbv = BitbakeVersion.objects.filter(branch="master").first() + release = Release.objects.filter(bitbake_version=bbv).first() + + name = "_js_unit_test_prj_" + + # If there is an existing project by this name delete it. We don'twant
lib/toaster/toastergui/views.py +4
-0+ # Lots of duplicates cluttering up the projects. + Project.objects.filter(name=name).delete() + + new_project = Project.objects.create_project(name=name,release=release)
lib/toaster/toastergui/views.py if True: · line 2276
Quoted 5 lines
lib/toaster/toastergui/views.py +3
-0+ + context = { 'project' : new_project } + return render(request, "js-unit-tests.html", context) from django.views.decorators.csrf import csrf_exempt @csrf_exemptThis patch seems to have landed without the new files
http://cgit.openembedded.org/bitbake/commit/?id=1c2f6b9b7b9e700146944b9d6d2114e0d014ee81(quoted diff) +0
-2-rw-r--r-- lib/toaster/toastergui/urls.py 3 -rwxr-xr-x lib/toaster/toastergui/views.py 162 files changed, 19 insertions, 0 deletions
Re: [PATCH 1/1] toastergui: Add frontend javascript unit tests
should I resubmit this to get the js and html file merged? -b
Quoted 329 lines · Brian Avery
yes, the following files were new in the patch and were not created:
lib/toaster/toastergui/static/js/tests/test.jsb/lib/toaster/toastergui/static/js/tests/test.jslib/toaster/toastergui/templates/js-unit-tests.htmlb/lib/toaster/toastergui/templates/js-unit-tests.html-bavery
Quoted 320 lines · Michael Wood
Quoted 304 lines · brian avery
From: Michael Wood <[email protected]>
Use Jquery's Qunit tests to create some unit tests for javascript components used in toaster.
Signed-off-by Michael Wood <[email protected]>Signed-off-by brian avery <[email protected]>--- lib/toaster/toastergui/static/js/tests/test.js | 175 +++++++++++++++++++++ .../toastergui/templates/js-unit-tests.html | 39 +++++ lib/toaster/toastergui/urls.py | 3 + lib/toaster/toastergui/views.py | 16 ++ 4 files changed, 233 insertions(+)create mode 100644
bitbake/lib/toaster/toastergui/static/js/tests/test.js
create mode 100644
bitbake/lib/toaster/toastergui/templates/js-unit-tests.htmllib/toaster/toastergui/static/js/tests/test.js new file +16
-0@@ -0,0 +1,175 @@ +"use strict"; +/* Unit tests for Toaster's JS */ + +/* libtoaster tests */ + +QUnit.test("Layer alert notification", function(assert) { + var layer = { + "layerdetailurl":"/toastergui/project/1/layer/22", + "vcs_url":"git://example.com/example.git", + "detail":"[ git://example.com/example.git | master ]", + "vcs_reference":"master", + "id": 22, + "name":"meta-example" + }; + + var correctResponse = "You have added <strong>3</strong> layers to yourproject: <a id=\"layer-affected-name\" href=\"/toastergui/project/1/layer/22\">meta-example</a> and its dependencies <a href=\"/toastergui/project/1/layer/9\" data-original-title=\"\" title=\"\">meta-example-two</a>, <a href=\"/toastergui/project/1/layer/9\" data-original-title=\"\" title=\"\">meta-example-three</a>";
lib/toaster/toastergui/static/js/tests/test.js new file +21
-0+ + var layerDepsList = [ + { + "layerdetailurl":"/toastergui/project/1/layer/9", + "vcs_url":"git://example.com/example.git", + "detail":"[ git://example.com/example.git | master ]", + "vcs_reference":"master", + "id": 9, + "name":"meta-example-two" + }, + { + "layerdetailurl":"/toastergui/project/1/layer/9", + "vcs_url":"git://example.com/example.git", + "detail":"[ git://example.com/example.git | master ]", + "vcs_reference":"master", + "id": 10, + "name":"meta-example-three" + }, + ]; + + var msg = libtoaster.makeLayerAddRmAlertMsg(layer, layerDepsList,true);
lib/toaster/toastergui/static/js/tests/test.js new file +11
-0+ var test = $("<div></div>"); + + test.html(msg); + + assert.equal(test.children("strong").text(), "3"); + assert.equal(test.children("a").length, 3); +}); + +QUnit.test("Project info", function(assert){ + var done = assert.async(); + libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl,function(prjInfo){
lib/toaster/toastergui/static/js/tests/test.js new file +127
-0+ assert.ok(prjInfo.machine.name); + assert.ok(prjInfo.releases.length > 0); + assert.ok(prjInfo.layers.length > 0); + assert.ok(prjInfo.freqtargets); + assert.ok(prjInfo.release); + done(); + }); +}); + +QUnit.test("Show notification", function(assert){ + var msg = "Testing"; + var element = $("#change-notification-msg"); + + libtoaster.showChangeNotification(msg); + + assert.equal(element.text(), msg); + assert.ok(element.is(":visible")); + + $("#change-notification").hide(); +}); + +var layer = { + "id": 91, + "name": "meta-crystalforest", + "layerdetailurl": "/toastergui/project/4/layer/91" +}; + +QUnit.test("Add layer", function(assert){ + var done = assert.async(); + + /* Wait for the modal to be added to the dom */ + var checkModal = setInterval(function(){ + if ($("#dependencies-modal").length > 0) { + $("#dependencies-modal .btn-primary").click(); + clearInterval(checkModal); + } + }, 200); + + libtoaster.addRmLayer(layer, true, function(deps){ + assert.equal(deps.length, 1); + done(); + }); + +}); + +QUnit.test("Rm layer", function(assert){ + var done = assert.async(); + + libtoaster.addRmLayer(layer, false, function(deps){ + assert.equal(deps.length, 0); + done(); + }); + +}); + +QUnit.test("Parse url params", function(assert){ + var params = libtoaster.parseUrlParams(); + assert.ok(params); +}); + +QUnit.test("Dump url params", function(assert){ + var params = libtoaster.dumpsUrlParams(); + assert.ok(params); +}); + +QUnit.test("Make typeaheads", function(assert){ + var layersT = $("#layers"); + var machinesT = $("#machines"); + var projectsT = $("#projects"); + var recipesT = $("#recipes"); + + libtoaster.makeTypeahead(layersT, + libtoaster.ctx.layersTypeAheadUrl, {}, function(){}); + + libtoaster.makeTypeahead(machinesT, + libtoaster.ctx.machinesTypeAheadUrl, {}, function(){}); + + libtoaster.makeTypeahead(projectsT, + libtoaster.ctx.projectsTypeAheadUrl, {}, function(){}); + + libtoaster.makeTypeahead(recipesT, + libtoaster.ctx.recipesTypeAheadUrl, {}, function(){}); + + assert.ok(recipesT.data('typeahead')); + assert.ok(layersT.data('typeahead')); + assert.ok(projectsT.data('typeahead')); + assert.ok(recipesT.data('typeahead')); +}); + + + +/* Page init functions */ + +QUnit.test("Import layer page init", function(assert){ + assert.throws(importLayerPageInit()); +}); + +QUnit.test("Project page init", function(assert){ + assert.throws(projectPageInit()); +}); + +QUnit.test("Layer details page init", function(assert){ + assert.throws(layerDetailsPageInit()); +}); + +QUnit.test("Layer btns init", function(assert){ + assert.throws(layerBtnsInit({ projectLayers : [] })); +}); + +QUnit.test("Table init", function(assert){ + assert.throws(tableInit({ url : tableUrl })); +}); + +$(document).ajaxError(function(event, jqxhr, settings, errMsg){ + if (errMsg === 'abort') + return; + + QUnit.test("Ajax error", function(assert){ + assert.notOk(jqxhr.responseText); + }); +}); + + + + + +lib/toaster/toastergui/templates/js-unit-tests.html new file +39
-0@@ -0,0 +1,39 @@ +{% extends "base.html" %} +{% load projecttags %} +{% load humanize %} +{% load static %} +{% block pagecontent %} + +<link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.18.0.css" /> + +<script src="//code.jquery.com/qunit/qunit-1.18.0.js"></script> + +<script src="{% static 'js/layerDepsModal.js' %}"></script> +<script src="{% static 'js/projectpage.js' %}"></script> + +<script src="{% static 'js/bootstrap.min.js' %}"></script> +<script src="{% static 'js/filtersnippet.js' %}"></script> +<script src="{% static 'js/importlayer.js' %}"></script> +<script src="{% static 'js/prettify.js' %}"></script> +<script src="{% static 'js/layerBtn.js' %}"></script> +<script src="{% static 'js/layerDepsModal.js' %}"></script> +<script src="{% static 'js/projectpage.js' %}"></script> +<script src="{% static 'js/layerdetails.js' %}"></script> +<script src="{% static 'js/table.js' %}"></script> + +<script> + var tableUrl = '{% url 'projectlayers' project.pk %}'; +</script> + +<script src="{% static 'js/tests/test.js' %}"></script> + +<div id="qunit"></div> + +<input type="text" id="layers" placeholder="layers" ></input> +<input type="text" id="recipes" placeholder="recipes"></input> +<input type="text" id="projects" placeholder="projects"></input> +<input type="text" id="machines" placeholder="machines"></input> + +{% endblock %} + +lib/toaster/toastergui/urls.py +2
-0@@ -145,6 +145,9 @@ urlpatterns = patterns('toastergui.views', url(r'^xhr_importlayer/$', 'xhr_importlayer', name='xhr_importlayer'), url(r'^xhr_updatelayer/$', 'xhr_updatelayer', name='xhr_updatelayer'), + # JS Unit tests + url(r'^js-unit-tests/$', 'jsunittests', name='js-unit-tests'), + # default redirection url(r'^$', RedirectView.as_view( url= 'landing')), )lib/toaster/toastergui/views.py +0
-0@@ -27,6 +27,7 @@ from django.shortcuts import render, redirect from orm.models import Build, Target, Task, Layer, Layer_Version,Recipe, LogMessage, Variable
from orm.models importTask_Dependency,Recipe_Dependency, Package,Package_File,Package_Dependency
from orm.models importTarget_Installed_Package,Target_File,Target_Image_File, BuildArtifactlib/toaster/toastergui/views.py +8
-0+from orm.models import BitbakeVersion from bldcontrol import bbcontroller from django.views.decorators.cache import cache_control from django.core.urlresolvers import reverse@@ -2255,6 +2256,21 @@ if True: return context + def jsunittests(request): + """ Provides a page for the js unit tests """ + bbv = BitbakeVersion.objects.filter(branch="master").first() + release = Release.objects.filter(bitbake_version=bbv).first() + + name = "_js_unit_test_prj_" + + # If there is an existing project by this name delete it. We don'twant
lib/toaster/toastergui/views.py +4
-0+ # Lots of duplicates cluttering up the projects. + Project.objects.filter(name=name).delete() + + new_project = Project.objects.create_project(name=name,release=release)
lib/toaster/toastergui/views.py if True: · line 2276
Quoted 5 lines
lib/toaster/toastergui/views.py +3
-0+ + context = { 'project' : new_project } + return render(request, "js-unit-tests.html", context) from django.views.decorators.csrf import csrf_exempt @csrf_exemptThis patch seems to have landed without the new files
http://cgit.openembedded.org/bitbake/commit/?id=1c2f6b9b7b9e700146944b9d6d2114e0d014ee81(quoted diff) +0
-2-rw-r--r-- lib/toaster/toastergui/urls.py 3 -rwxr-xr-x lib/toaster/toastergui/views.py 162 files changed, 19 insertions, 0 deletions
Re: [PATCH 1/1] toastergui: Add frontend javascript unit tests
Quoted 10 lines · Brian Avery
should I resubmit this to get the js and html file merged? -b
Quoted 6 lines · Brian Avery
yes, the following files were new in the patch and were not created:
lib/toaster/toastergui/static/js/tests/test.jsb/lib/toaster/toastergui/static/js/tests/test.jslib/toaster/toastergui/templates/js-unit-tests.htmlb/lib/toaster/toastergui/templates/js-unit-tests.html
I believe this was fixed yesterday. Let me know if not.
Cheers,
Richard