From d88e6674fd6fcad3bdd841c75c81fec1815615c8 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 5 Sep 2013 17:21:25 -0700 Subject: First attempt at an EOS test runner This adds a script eos-run-test which is adapted from gjs_run_tests, but does not try to discover the tests itself. Instead, in keeping with Automake's test suite facilities, it takes the filename of a test to run. [endlessm/eos-sdk#290] --- test/Makefile.am | 5 +++++ test/tools/eos-run-test/sanitycheck.js | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 test/tools/eos-run-test/sanitycheck.js (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index b4217c1..dcf6ee4 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -24,3 +24,8 @@ test_run_tests_LDADD = $(TEST_LIBS) test_smoke_tests_hello_SOURCES = test/smoke-tests/hello.c test_smoke_tests_hello_CPPFLAGS = $(TEST_FLAGS) test_smoke_tests_hello_LDADD = $(TEST_LIBS) + +javascript_tests = \ + test/tools/eos-run-test/sanitycheck.js \ + $(NULL) +EXTRA_DIST += $(javascript_tests) diff --git a/test/tools/eos-run-test/sanitycheck.js b/test/tools/eos-run-test/sanitycheck.js new file mode 100644 index 0000000..4bb3a80 --- /dev/null +++ b/test/tools/eos-run-test/sanitycheck.js @@ -0,0 +1,3 @@ +function testNothing() { + assertEquals(2, 2); +} \ No newline at end of file -- cgit v1.2.3 From 02f3b14035f0b7f97f24c6bb2f8e81ee1884bc0c Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 5 Sep 2013 17:44:37 -0700 Subject: Move webhelper smoke test into a new subdir The webhelper tests should be in their own directory, mirroring the source directory structure. [endlessm/eos-sdk#290] --- test/smoke-tests/webview.js | 112 ---------------------- test/smoke-tests/webview/first_page.html | 54 ----------- test/webhelper/smoke-tests/webview.js | 155 +++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+), 166 deletions(-) delete mode 100644 test/smoke-tests/webview.js delete mode 100644 test/smoke-tests/webview/first_page.html create mode 100644 test/webhelper/smoke-tests/webview.js (limited to 'test') diff --git a/test/smoke-tests/webview.js b/test/smoke-tests/webview.js deleted file mode 100644 index 98226f3..0000000 --- a/test/smoke-tests/webview.js +++ /dev/null @@ -1,112 +0,0 @@ -//Copyright 2013 Endless Mobile, Inc. - -const Lang = imports.lang; -const Endless = imports.gi.Endless; -const GLib = imports.gi.GLib; -const Gtk = imports.gi.Gtk; -const WebKit = imports.gi.WebKit; - -// WebHelper.js must be copied somewhere in GJS's imports.searchPath -const WebHelper = imports.webhelper; - -const TEST_APPLICATION_ID = 'com.endlessm.example.test-webview'; - -const TestApplication = new Lang.Class({ - Name: 'TestApplication', - Extends: WebHelper.Application, - - /* *** ACTIONS AVAILABLE FROM THE WEB VIEW *** */ - - _webActions: { - /* dict['name'] is the name of the page to move to */ - 'moveToPage': function(dict) { - print('move to page '+dict['name']); - this._pm.visible_page_name = dict['name']; - }, - - /* dict['msg'] is the message to display */ - 'showMessageFromParameter': function(dict) { - let dialog = new Gtk.MessageDialog({ - buttons: Gtk.ButtonsType.CLOSE, - message_type: Gtk.MessageType.INFO, - text: dict['msg'] }); - dialog.set_transient_for(this._window); - dialog.run(); - dialog.destroy(); - }, - - /* dict['id'] is the ID of the input field to use */ - 'showMessageFromInputField': function(dict) { - let input = this._getElementById(this._webview, dict['id']); - - // WebKitDOMHTMLInputElement - let msg = input.get_value(); - - let dialog = new Gtk.MessageDialog({ - buttons: Gtk.ButtonsType.CLOSE, - message_type: Gtk.MessageType.INFO, - text: msg }); - dialog.set_transient_for(this._window); - dialog.run(); - dialog.destroy(); - }, - - /* dict['id'] is the ID of the element to use */ - 'addStars': function(dict) { - let e = this._getElementById(this._webview, dict['id']); - e.inner_text += '★ '; - } - }, - - /* *************************** */ - - vfunc_startup: function() { - this.parent(); - - this._webview = new WebKit.WebView(); - - let cwd = GLib.get_current_dir(); - let target = cwd + '/test/smoke-tests/webview/first_page.html'; - this._webview.load_uri(GLib.filename_to_uri(target, null)); - - this._webview.connect('notify::load-status', - Lang.bind(this, function (web_view, status) { - if (web_view.load_status == WebKit.LoadStatus.FINISHED) { - // now we translate to Brazilian Portuguese - this._translateHTML (web_view, 'pt_BR'); - } - })); - - this._webview.connect('navigation-policy-decision-requested', - Lang.bind(this, this._onNavigationRequested)); - - this._page1 = new Gtk.ScrolledWindow(); - this._page1.add(this._webview); - - this._page2 = new Gtk.Grid(); - let back_button = new Gtk.Button({label:"Go back to page 1"}); - back_button.connect('clicked', Lang.bind(this, function() { - this._pm.visible_page_name = 'page1'; - })) - this._page2.add(back_button); - - this._pm = new Endless.PageManager(); - this._pm.set_transition_type(Endless.PageManagerTransitionType.CROSSFADE) - this._pm.add(this._page1, { name: 'page1' }); - this._pm.add(this._page2, { name: 'page2' }); - - this._pm.visible_page = this._page1; - - this._window = new Endless.Window({ - application: this, - border_width: 16, - page_manager: this._pm - }); - - this._window.show_all(); - } -}); - -let app = new TestApplication({ application_id: TEST_APPLICATION_ID, - flags: 0 }); -app.run(ARGV); diff --git a/test/smoke-tests/webview/first_page.html b/test/smoke-tests/webview/first_page.html deleted file mode 100644 index 33a6a8f..0000000 --- a/test/smoke-tests/webview/first_page.html +++ /dev/null @@ -1,54 +0,0 @@ - - - -First page - - - - - - -

First page

- -

-Move to page 2 -

- -

-Show message from parameter in this URL -

- -
- - -
- -

- -Show message using the <input>'s ID -

- -

-Regular link to a Web site -

- -

-I want stars! -

- -

-This is text that will be translated: Hello, world! -

- - - \ No newline at end of file diff --git a/test/webhelper/smoke-tests/webview.js b/test/webhelper/smoke-tests/webview.js new file mode 100644 index 0000000..681de20 --- /dev/null +++ b/test/webhelper/smoke-tests/webview.js @@ -0,0 +1,155 @@ +//Copyright 2013 Endless Mobile, Inc. + +const Lang = imports.lang; +const Endless = imports.gi.Endless; +const GLib = imports.gi.GLib; +const Gtk = imports.gi.Gtk; +const WebKit = imports.gi.WebKit; + +// WebHelper.js must be copied somewhere in GJS's imports.searchPath +const WebHelper = imports.webhelper; + +const TEST_APPLICATION_ID = 'com.endlessm.example.test-webview'; + +const TEST_HTML = '\ + \ + \ +First page \ + \ + \ +\ + \ +

First page

\ +\ +

Move to page 2

\ +\ +

Show \ +message from parameter in this URL

\ +\ +
\ + \ + \ +
\ +\ +

\ + \ +Show message \ +using the <input>\'s ID \ +

\ +\ +

Regular link to a Web site

\ +\ +

I want \ +stars!

\ +\ +

This is text that will be translated: Hello, \ +world!

\ +\ + \ +'; + +const TestApplication = new Lang.Class({ + Name: 'TestApplication', + Extends: WebHelper.Application, + + /* *** ACTIONS AVAILABLE FROM THE WEB VIEW *** */ + + _webActions: { + /* dict['name'] is the name of the page to move to */ + 'moveToPage': function(dict) { + print('move to page '+dict['name']); + this._pm.visible_page_name = dict['name']; + }, + + /* dict['msg'] is the message to display */ + 'showMessageFromParameter': function(dict) { + let dialog = new Gtk.MessageDialog({ + buttons: Gtk.ButtonsType.CLOSE, + message_type: Gtk.MessageType.INFO, + text: dict['msg'] }); + dialog.set_transient_for(this._window); + dialog.run(); + dialog.destroy(); + }, + + /* dict['id'] is the ID of the input field to use */ + 'showMessageFromInputField': function(dict) { + let input = this._getElementById(this._webview, dict['id']); + + // WebKitDOMHTMLInputElement + let msg = input.get_value(); + + let dialog = new Gtk.MessageDialog({ + buttons: Gtk.ButtonsType.CLOSE, + message_type: Gtk.MessageType.INFO, + text: msg }); + dialog.set_transient_for(this._window); + dialog.run(); + dialog.destroy(); + }, + + /* dict['id'] is the ID of the element to use */ + 'addStars': function(dict) { + let e = this._getElementById(this._webview, dict['id']); + e.inner_text += '★ '; + } + }, + + /* *************************** */ + + vfunc_startup: function() { + this.parent(); + + this._webview = new WebKit.WebView(); + this._webview.load_string(TEST_HTML, 'text/html', 'UTF-8', 'file://'); + this._webview.connect('notify::load-status', + Lang.bind(this, function (web_view, status) { + if (web_view.load_status == WebKit.LoadStatus.FINISHED) { + // now we translate to Brazilian Portuguese + this._translateHTML (web_view, 'pt_BR'); + } + })); + + this._webview.connect('navigation-policy-decision-requested', + Lang.bind(this, this._onNavigationRequested)); + + this._page1 = new Gtk.ScrolledWindow(); + this._page1.add(this._webview); + + this._page2 = new Gtk.Grid(); + let back_button = new Gtk.Button({label:"Go back to page 1"}); + back_button.connect('clicked', Lang.bind(this, function() { + this._pm.visible_page_name = 'page1'; + })) + this._page2.add(back_button); + + this._pm = new Endless.PageManager(); + this._pm.set_transition_type(Endless.PageManagerTransitionType.CROSSFADE) + this._pm.add(this._page1, { name: 'page1' }); + this._pm.add(this._page2, { name: 'page2' }); + + this._pm.visible_page = this._page1; + + this._window = new Endless.Window({ + application: this, + border_width: 16, + page_manager: this._pm + }); + + this._window.show_all(); + } +}); + +let app = new TestApplication({ application_id: TEST_APPLICATION_ID, + flags: 0 }); +app.run(ARGV); -- cgit v1.2.3 From 6d595d347c6d454edc4749333edd413e9640a99d Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Fri, 6 Sep 2013 09:25:05 -0700 Subject: Adjust API so that "public" functions don't start with _ Also, since the functions will likely be translated into C in the future, give_them_underscored_names insteadOfCamelCase, in order to avoid API changes. [endlessm/eos-sdk#290] --- test/webhelper/smoke-tests/webview.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/webhelper/smoke-tests/webview.js b/test/webhelper/smoke-tests/webview.js index 681de20..c3c7dd5 100644 --- a/test/webhelper/smoke-tests/webview.js +++ b/test/webhelper/smoke-tests/webview.js @@ -116,12 +116,12 @@ const TestApplication = new Lang.Class({ Lang.bind(this, function (web_view, status) { if (web_view.load_status == WebKit.LoadStatus.FINISHED) { // now we translate to Brazilian Portuguese - this._translateHTML (web_view, 'pt_BR'); + this.translate_html(web_view); } })); this._webview.connect('navigation-policy-decision-requested', - Lang.bind(this, this._onNavigationRequested)); + Lang.bind(this, this.web_actions_handler)); this._page1 = new Gtk.ScrolledWindow(); this._page1.add(this._webview); -- cgit v1.2.3 From e4048bffd4153f7d7bd978f5779caaec8e76a069 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 10 Sep 2013 17:43:25 -0700 Subject: Do translation with webhelper Previously, the translation was such that it did a dummy translation, italicizing the text to be translated. Now it looks for a translationFunction property on the app object, and calls that on the text. [endlessm/eos-sdk#290] --- test/webhelper/smoke-tests/webview.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/webhelper/smoke-tests/webview.js b/test/webhelper/smoke-tests/webview.js index c3c7dd5..fe2a655 100644 --- a/test/webhelper/smoke-tests/webview.js +++ b/test/webhelper/smoke-tests/webview.js @@ -52,7 +52,7 @@ using the <input>\'s ID \

I want \ stars!

\ \ -

This is text that will be translated: Hello, \ +

This is text that will be italicized: Hello, \ world!

\ \ \ @@ -62,6 +62,10 @@ const TestApplication = new Lang.Class({ Name: 'TestApplication', Extends: WebHelper.Application, + _translationFunction: function(string) { + return string.italics(); + }, + /* *** ACTIONS AVAILABLE FROM THE WEB VIEW *** */ _webActions: { -- cgit v1.2.3 From 658cb6d84afcb01fc121a04df0d82bbea22c2c25 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Fri, 6 Sep 2013 09:26:02 -0700 Subject: Unit tests for webhelper These are tests for the basic functionality and a few fail cases of webhelper, by no means exhaustive. There are a few tests that cannot execute because I do not currently know of any way to catch exceptions that occur inside GObject callbacks. [endlessm/eos-sdk#290] --- test/Makefile.am | 2 + test/webhelper/testTranslate.js | 72 ++++++++++++++++++++ test/webhelper/testWebActions.js | 140 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 214 insertions(+) create mode 100644 test/webhelper/testTranslate.js create mode 100644 test/webhelper/testWebActions.js (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index dcf6ee4..e913d57 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -27,5 +27,7 @@ test_smoke_tests_hello_LDADD = $(TEST_LIBS) javascript_tests = \ test/tools/eos-run-test/sanitycheck.js \ + test/webhelper/testTranslate.js \ + test/webhelper/testWebActions.js \ $(NULL) EXTRA_DIST += $(javascript_tests) diff --git a/test/webhelper/testTranslate.js b/test/webhelper/testTranslate.js new file mode 100644 index 0000000..10e389c --- /dev/null +++ b/test/webhelper/testTranslate.js @@ -0,0 +1,72 @@ +const Endless = imports.gi.Endless; +const GLib = imports.gi.GLib; +const Gtk = imports.gi.Gtk; +const Lang = imports.lang; +const WebHelper = imports.webhelper; +const WebKit = imports.gi.WebKit; + +const TestClass = new Lang.Class({ + Name: 'testclass', + Extends: WebHelper.Application, + + vfunc_startup: function() { + this.parent(); + this.webview = new WebKit.WebView(); + let string = '

Translate Me

'; + this.webview.load_string(string, 'text/html', 'UTF-8', 'file://'); + this.win = new Endless.Window({ + application: this + }); + this.scrolled = new Gtk.ScrolledWindow(); + this.scrolled.add(this.webview); + this.win.page_manager.add(this.scrolled); + + this.webview.connect('notify::load-status', Lang.bind(this, function() { + if(this.webview.load_status === WebKit.LoadStatus.FINISHED) { + this.translate_html(this.webview); + this.quit(); + } + })); + + // Add an upper bound on how long the app runs, in case app.quit() does + // not get called + GLib.timeout_add_seconds(GLib.PRIORITY_HIGH, 5, Lang.bind(this, function() { + this.quit(); + })); + } +}); + +let app; + +function setUp() { + // Generate a unique ID for each app instance that we test + let id_string = 'com.endlessm.webhelper.test' + GLib.get_real_time(); + app = new TestClass({ + application_id: id_string + }); +} + +function testStringIsTranslated() { + let translationFunctionWasCalled = false; + let translationFunctionCalledWithString; + app._translationFunction = function(s) { + translationFunctionWasCalled = true; + translationFunctionCalledWithString = s; + return s; + }; + app.run([]); + assertTrue(translationFunctionWasCalled); + assertEquals('Translate Me', translationFunctionCalledWithString); +} + +// The following two tests are commented out because GJS cannot catch exceptions +// across FFI interfaces (e.g. in GObject callbacks.) + +// function testMissingTranslationFunctionIsHandled() { +// assertRaises(app.run([])); +// } + +// function testBadTranslationFunctionIsHandled() { +// app._translationFunction = "I am not a function"; +// assertRaises(app.run([])); +// } \ No newline at end of file diff --git a/test/webhelper/testWebActions.js b/test/webhelper/testWebActions.js new file mode 100644 index 0000000..585ab00 --- /dev/null +++ b/test/webhelper/testWebActions.js @@ -0,0 +1,140 @@ +const Endless = imports.gi.Endless; +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; +const Gtk = imports.gi.Gtk; +const Lang = imports.lang; +const WebHelper = imports.webhelper; +const WebKit = imports.gi.WebKit; + +const TestClass = new Lang.Class({ + Name: 'testclass', + Extends: WebHelper.Application, + + vfunc_startup: function() { + this.parent(); + this.webview = new WebKit.WebView(); + this.webview.connect('navigation-policy-decision-requested', + Lang.bind(this, this.web_actions_handler)); + let string = (''); + this.webview.load_string(string, 'text/html', 'UTF-8', 'file://'); + this.win = new Endless.Window({ + application: this + }); + this.scrolled = new Gtk.ScrolledWindow(); + this.scrolled.add(this.webview); + this.win.page_manager.add(this.scrolled); + + // Add an upper bound on how long the app runs, in case app.quit() does + // not get called + GLib.timeout_add_seconds(GLib.PRIORITY_HIGH, 5, Lang.bind(this, function() { + this.quit(); + })); + } +}); + +let app; + +function setUp() { + // Generate a unique ID for each app instance that we test + let id_string = 'com.endlessm.webhelper.test' + GLib.get_real_time(); + app = new TestClass({ + application_id: id_string + }); +} + +function testWebActionIsCalled() { + let actionWasCalled = false; + app._webActions = { + quitApplication: function() { + actionWasCalled = true; + app.quit(); + } + }; + app.webActionToTest = 'endless://quitApplication'; + app.run([]); + assertTrue(actionWasCalled); +} + +function testWebActionIsCalledWithParameter() { + let actionParameter; + app._webActions = { + getParameterAndQuit: function(dict) { + actionParameter = dict['param']; + app.quit(); + } + }; + app.webActionToTest = 'endless://getParameterAndQuit?param=value'; + app.run([]); + assertEquals('value', actionParameter); +} + +function testWebActionIsCalledWithManyParameters() { + let firstParameter, secondParameter, thirdParameter; + app._webActions = { + getParametersAndQuit: function(dict) { + firstParameter = dict['first']; + secondParameter = dict['second']; + thirdParameter = dict['third']; + app.quit(); + } + }; + app.webActionToTest = 'endless://getParametersAndQuit?first=thefirst&second=thesecond&third=thethird'; + app.run([]); + assertEquals('thefirst', firstParameter); + assertEquals('thesecond', secondParameter); + assertEquals('thethird', thirdParameter); +} + +function testParameterNameIsUriDecoded() { + let expectedParameter = 'päräm💩'; + let parameterWasFound = false; + app._webActions = { + getUriDecodedParameterAndQuit: function(dict) { + parameterWasFound = (expectedParameter in dict); + app.quit(); + } + }; + app.webActionToTest = 'endless://getUriDecodedParameterAndQuit?p%C3%A4r%C3%A4m%F0%9F%92%A9=value'; + app.run([]); + assertTrue(parameterWasFound); +} + +function testParameterValueIsUriDecoded() { + let expectedValue = 'válué💩'; + let actualValue; + app._webActions = { + getUriDecodedValueAndQuit: function(dict) { + actualValue = dict['param']; + app.quit(); + } + }; + app.webActionToTest = 'endless://getUriDecodedValueAndQuit?param=v%C3%A1lu%C3%A9%F0%9F%92%A9'; + app.run([]); + assertEquals(expectedValue, actualValue); +} + +// This is commented out because GJS cannot catch exceptions across FFI +// interfaces (e.g. in GObject callbacks.) +// function testBadActionIsNotCalled() { +// app.webActionToTest = 'endless://nonexistentAction?param=value'; +// assertRaises(function() { app.run([]); }); +// } + +function testWebActionIsCalledWithBlankParameter() { + let parameterWasFound = false; + let parameterValue; + app._webActions = { + getBlankValueAndQuit: function(dict) { + parameterWasFound = ('param' in dict); + if(parameterWasFound) + parameterValue = dict['param']; + app.quit(); + } + }; + app.webActionToTest = 'endless://getBlankValueAndQuit?param='; + app.run([]); + assertTrue(parameterWasFound); + assertNotUndefined(parameterValue); + assertEquals('', parameterValue); +} -- cgit v1.2.3 From dcab98606ce9aa37d7f980e2365e08af5458a5f3 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Wed, 18 Sep 2013 13:52:09 -0700 Subject: Move test autotooling to test/Makefile.am include file The autotools code for running the tests should go in the included Makefile.am in the test/ subdirectory, so that all those test files are run and distributed in the same place. [endlessm/eos-sdk#290] --- test/Makefile.am | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index e913d57..4124c52 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -31,3 +31,16 @@ javascript_tests = \ test/webhelper/testWebActions.js \ $(NULL) EXTRA_DIST += $(javascript_tests) + +# Run tests when running 'make check' +TESTS = \ + test/run-tests \ + $(javascript_tests) \ + $(NULL) +TEST_EXTENSIONS = .js +JS_LOG_COMPILER = tools/eos-run-test +AM_JS_LOG_FLAGS = \ + --include-path=$(top_srcdir)/webhelper \ + $(NULL) +LOG_COMPILER = gtester +AM_LOG_FLAGS = -k --verbose -- cgit v1.2.3