From db2bed896a064d4d78383a7f7635896ca58b0a4b Mon Sep 17 00:00:00 2001 From: Benedict Aas Date: Thu, 1 Feb 2018 12:28:56 +0000 Subject: [PATCH 1/5] feat: replace template paths with contents We replace the `templateUrl` fields with `template` fields and thus switch from template paths to template contents in preparation for the Webpack PR. Changelog-Entry: Replace template paths with template contents. Change-Type: patch --- lib/gui/app/app.js | 8 ++++++ .../drive-selector/services/drive-selector.js | 2 +- .../app/components/modal/services/modal.js | 6 ++--- .../directives/progress-button.js | 2 +- .../tooltip-modal/services/tooltip-modal.js | 2 +- .../warning-modal/services/warning-modal.js | 2 +- lib/gui/app/pages/finish/finish.js | 2 +- lib/gui/app/pages/main/main.js | 2 +- lib/gui/app/pages/settings/settings.js | 2 +- tests/gui/pages/main.spec.js | 27 +++++++++++++++++++ 10 files changed, 45 insertions(+), 10 deletions(-) diff --git a/lib/gui/app/app.js b/lib/gui/app/app.js index 41b73921..69dc49ac 100644 --- a/lib/gui/app/app.js +++ b/lib/gui/app/app.js @@ -26,6 +26,14 @@ var angular = require('angular') /* eslint-enable no-var */ +// Temporary: will be taken care of Webpack automatically soon +// eslint-disable-next-line node/no-deprecated-api +require.extensions['.html'] = (module, filename) => { + module.exports = require('fs').readFileSync(filename, { + encoding: 'utf8' + }) +} + const electron = require('electron') const Bluebird = require('bluebird') const semver = require('semver') diff --git a/lib/gui/app/components/drive-selector/services/drive-selector.js b/lib/gui/app/components/drive-selector/services/drive-selector.js index 5b7376f0..dcb7c9c7 100644 --- a/lib/gui/app/components/drive-selector/services/drive-selector.js +++ b/lib/gui/app/components/drive-selector/services/drive-selector.js @@ -35,7 +35,7 @@ module.exports = function (ModalService, $q) { this.open = () => { modal = ModalService.open({ name: 'drive-selector', - template: './components/drive-selector/templates/drive-selector-modal.tpl.html', + template: require('../templates/drive-selector-modal.tpl.html'), controller: 'DriveSelectorController as modal', size: 'drive-selector-modal' }) diff --git a/lib/gui/app/components/modal/services/modal.js b/lib/gui/app/components/modal/services/modal.js index da6efb6a..e84dc2ee 100644 --- a/lib/gui/app/components/modal/services/modal.js +++ b/lib/gui/app/components/modal/services/modal.js @@ -26,7 +26,7 @@ module.exports = function ($uibModal, $q) { * @public * * @param {Object} options - options - * @param {String} options.template - template path + * @param {String} options.template - template contents * @param {String} options.controller - controller * @param {String} [options.size='sm'] - modal size * @param {Object} options.resolve - modal resolves @@ -35,7 +35,7 @@ module.exports = function ($uibModal, $q) { * @example * ModalService.open({ * name: 'my modal', - * template: './path/to/modal.tpl.html', + * template: require('./path/to/modal.tpl.html'), * controller: 'DriveSelectorController as modal', * }); */ @@ -50,7 +50,7 @@ module.exports = function ($uibModal, $q) { const modal = $uibModal.open({ animation: true, - templateUrl: options.template, + template: options.template, controller: options.controller, size: options.size, resolve: options.resolve diff --git a/lib/gui/app/components/progress-button/directives/progress-button.js b/lib/gui/app/components/progress-button/directives/progress-button.js index 06ccdbf7..7f11983c 100644 --- a/lib/gui/app/components/progress-button/directives/progress-button.js +++ b/lib/gui/app/components/progress-button/directives/progress-button.js @@ -32,7 +32,7 @@ */ module.exports = () => { return { - templateUrl: './components/progress-button/templates/progress-button.tpl.html', + template: require('../templates/progress-button.tpl.html'), restrict: 'E', replace: true, transclude: true, diff --git a/lib/gui/app/components/tooltip-modal/services/tooltip-modal.js b/lib/gui/app/components/tooltip-modal/services/tooltip-modal.js index 11aaefc8..dcc32b27 100644 --- a/lib/gui/app/components/tooltip-modal/services/tooltip-modal.js +++ b/lib/gui/app/components/tooltip-modal/services/tooltip-modal.js @@ -38,7 +38,7 @@ module.exports = function (ModalService) { this.show = (options) => { return ModalService.open({ name: 'tooltip', - template: './components/tooltip-modal/templates/tooltip-modal.tpl.html', + template: require('../templates/tooltip-modal.tpl.html'), controller: 'TooltipModalController as modal', size: 'tooltip-modal', resolve: { diff --git a/lib/gui/app/components/warning-modal/services/warning-modal.js b/lib/gui/app/components/warning-modal/services/warning-modal.js index 90cf29b8..dac49af9 100644 --- a/lib/gui/app/components/warning-modal/services/warning-modal.js +++ b/lib/gui/app/components/warning-modal/services/warning-modal.js @@ -41,7 +41,7 @@ module.exports = function ($sce, ModalService) { options.description = $sce.trustAsHtml(options.description) return ModalService.open({ name: 'warning', - template: './components/warning-modal/templates/warning-modal.tpl.html', + template: require('../templates/warning-modal.tpl.html'), controller: 'WarningModalController as modal', size: 'warning-modal', resolve: { diff --git a/lib/gui/app/pages/finish/finish.js b/lib/gui/app/pages/finish/finish.js index a9ddff73..abb160af 100644 --- a/lib/gui/app/pages/finish/finish.js +++ b/lib/gui/app/pages/finish/finish.js @@ -39,7 +39,7 @@ FinishPage.config(($stateProvider) => { .state('success', { url: '/success', controller: 'FinishController as finish', - templateUrl: './pages/finish/templates/success.tpl.html' + template: require('./templates/success.tpl.html') }) }) diff --git a/lib/gui/app/pages/main/main.js b/lib/gui/app/pages/main/main.js index de88e749..9aeba0f8 100644 --- a/lib/gui/app/pages/main/main.js +++ b/lib/gui/app/pages/main/main.js @@ -55,7 +55,7 @@ MainPage.config(($stateProvider) => { .state('main', { url: '/main', controller: 'MainController as main', - templateUrl: './pages/main/templates/main.tpl.html' + template: require('./templates/main.tpl.html') }) }) diff --git a/lib/gui/app/pages/settings/settings.js b/lib/gui/app/pages/settings/settings.js index 32eb907b..872f0e46 100644 --- a/lib/gui/app/pages/settings/settings.js +++ b/lib/gui/app/pages/settings/settings.js @@ -34,7 +34,7 @@ SettingsPage.config(($stateProvider) => { .state('settings', { url: '/settings', controller: 'SettingsController as settings', - templateUrl: './pages/settings/templates/settings.tpl.html' + template: require('./templates/settings.tpl.html') }) }) diff --git a/tests/gui/pages/main.spec.js b/tests/gui/pages/main.spec.js index b9676292..6b00e9f5 100644 --- a/tests/gui/pages/main.spec.js +++ b/tests/gui/pages/main.spec.js @@ -18,6 +18,7 @@ const m = require('mochainon') const _ = require('lodash') +const fs = require('fs') const path = require('path') const supportedFormats = require('../../../lib/shared/supported-formats') const angular = require('angular') @@ -26,6 +27,14 @@ const availableDrives = require('../../../lib/shared/models/available-drives') const selectionState = require('../../../lib/shared/models/selection-state') require('angular-mocks') +// Mock HTML requires by reading from the file-system +// eslint-disable-next-line node/no-deprecated-api +require.extensions['.html'] = (module, filename) => { + module.exports = fs.readFileSync(filename, { + encoding: 'utf8' + }) +} + describe('Browser: MainPage', function () { beforeEach(angular.mock.module( require('../../../lib/gui/app/pages/main/main') @@ -241,4 +250,22 @@ describe('Browser: MainPage', function () { }) }) }) + + describe('page template', function () { + let $state + + beforeEach(angular.mock.inject(function (_$state_) { + $state = _$state_ + })) + + it('should match the file contents', function () { + const { + template + } = $state.get('main') + const contents = fs.readFileSync('lib/gui/app/pages/main/templates/main.tpl.html', { + encoding: 'utf-8' + }) + m.chai.expect(template).to.equal(contents) + }) + }) }) From f2424095e034e0bfef1bed04d8ee03a4e41adc1b Mon Sep 17 00:00:00 2001 From: Benedict Aas Date: Thu, 1 Feb 2018 23:53:11 +0000 Subject: [PATCH 2/5] test other pages --- tests/gui/pages/finish.spec.js | 46 ++++++++++++++++++++++++++++ tests/gui/pages/settings.spec.js | 52 ++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 tests/gui/pages/finish.spec.js create mode 100644 tests/gui/pages/settings.spec.js diff --git a/tests/gui/pages/finish.spec.js b/tests/gui/pages/finish.spec.js new file mode 100644 index 00000000..42ec78e9 --- /dev/null +++ b/tests/gui/pages/finish.spec.js @@ -0,0 +1,46 @@ +/* + * Copyright 2018 resin.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict' + +const m = require('mochainon') +const fs = require('fs') +const angular = require('angular') +require('angular-mocks') + +describe('Browser: FinishPage', function () { + beforeEach(angular.mock.module( + require('../../../lib/gui/app/pages/finish/finish') + )) + + describe('page template', function () { + let $state + + beforeEach(angular.mock.inject(function (_$state_) { + $state = _$state_ + })) + + it('should match the file contents', function () { + const { + template + } = $state.get('success') + const contents = fs.readFileSync('lib/gui/app/pages/finish/templates/success.tpl.html', { + encoding: 'utf-8' + }) + m.chai.expect(template).to.equal(contents) + }) + }) +}) diff --git a/tests/gui/pages/settings.spec.js b/tests/gui/pages/settings.spec.js new file mode 100644 index 00000000..d986db06 --- /dev/null +++ b/tests/gui/pages/settings.spec.js @@ -0,0 +1,52 @@ +/* + * Copyright 2018 resin.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict' + +const m = require('mochainon') +const _ = require('lodash') +const fs = require('fs') +const path = require('path') +const supportedFormats = require('../../../lib/shared/supported-formats') +const angular = require('angular') +const flashState = require('../../../lib/shared/models/flash-state') +const availableDrives = require('../../../lib/shared/models/available-drives') +const selectionState = require('../../../lib/shared/models/selection-state') +require('angular-mocks') + +describe('Browser: SettingsPage', function () { + beforeEach(angular.mock.module( + require('../../../lib/gui/app/pages/settings/settings') + )) + + describe('page template', function () { + let $state + + beforeEach(angular.mock.inject(function (_$state_) { + $state = _$state_ + })) + + it('should match the file contents', function () { + const { + template + } = $state.get('settings') + const contents = fs.readFileSync('lib/gui/app/pages/settings/templates/settings.tpl.html', { + encoding: 'utf-8' + }) + m.chai.expect(template).to.equal(contents) + }) + }) +}) From ad0b5e758311de5938375b390f9ba4f7584b6d8b Mon Sep 17 00:00:00 2001 From: Benedict Aas Date: Wed, 7 Feb 2018 11:47:16 +0000 Subject: [PATCH 3/5] test modal --- tests/gui/components/modal.spec.js | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 tests/gui/components/modal.spec.js diff --git a/tests/gui/components/modal.spec.js b/tests/gui/components/modal.spec.js new file mode 100644 index 00000000..7880e15b --- /dev/null +++ b/tests/gui/components/modal.spec.js @@ -0,0 +1,40 @@ + +const m = require('mochainon') + +describe('Browser: Modal', function () { + beforeEach(angular.mock.module( + require('../../../lib/gui/app/components/modal/modal') + )) + + describe('ModalService', function () { + let ModalService + + beforeEach(angular.mock.inject(function (_ModalService_) { + ModalService = _ModalService_ + })) + + describe('.open()', function () { + it('should not emit any errors when the template is a non-empty string', function () { + m.chai.expect(function () { + ModalService.open({ + template: '
{{ \'Hello\' }}, World!
' + }) + }).to.not.throw() + }) + + it('should emit error on no template field', function () { + m.chai.expect(function () { + ModalService.open({}) + }).to.throw('One of component or template or templateUrl options is required.') + }) + + it('should emit error on empty string template', function () { + m.chai.expect(function () { + ModalService.open({ + template: '' + }) + }).to.throw('One of component or template or templateUrl options is required.') + }) + }) + }) +}) From d5a14031c63e6c7d4c5eba793b2e53c4e21596cf Mon Sep 17 00:00:00 2001 From: Benedict Aas Date: Thu, 8 Feb 2018 12:27:25 +0000 Subject: [PATCH 4/5] pass linter --- tests/gui/components/modal.spec.js | 19 +++++++++++++++++++ tests/gui/pages/settings.spec.js | 6 ------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/tests/gui/components/modal.spec.js b/tests/gui/components/modal.spec.js index 7880e15b..f385b8cb 100644 --- a/tests/gui/components/modal.spec.js +++ b/tests/gui/components/modal.spec.js @@ -1,5 +1,24 @@ +/* + * Copyright 2017 resin.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict' const m = require('mochainon') +const angular = require('angular') +require('angular-mocks') describe('Browser: Modal', function () { beforeEach(angular.mock.module( diff --git a/tests/gui/pages/settings.spec.js b/tests/gui/pages/settings.spec.js index d986db06..4f6d4690 100644 --- a/tests/gui/pages/settings.spec.js +++ b/tests/gui/pages/settings.spec.js @@ -17,14 +17,8 @@ 'use strict' const m = require('mochainon') -const _ = require('lodash') const fs = require('fs') -const path = require('path') -const supportedFormats = require('../../../lib/shared/supported-formats') const angular = require('angular') -const flashState = require('../../../lib/shared/models/flash-state') -const availableDrives = require('../../../lib/shared/models/available-drives') -const selectionState = require('../../../lib/shared/models/selection-state') require('angular-mocks') describe('Browser: SettingsPage', function () { From 96c76177af6f37f088708722799042d961c34180 Mon Sep 17 00:00:00 2001 From: Benedict Aas Date: Mon, 12 Feb 2018 14:02:42 +0000 Subject: [PATCH 5/5] fix sanity-checks --- scripts/ci/ensure-all-node-requirements-available.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/ci/ensure-all-node-requirements-available.sh b/scripts/ci/ensure-all-node-requirements-available.sh index 0c3efeb7..73ab49c4 100755 --- a/scripts/ci/ensure-all-node-requirements-available.sh +++ b/scripts/ci/ensure-all-node-requirements-available.sh @@ -38,6 +38,7 @@ DEV_FILES_REGEX=^\(tests\|scripts\)/ # need to do a non-greedy match, which is why we're not using (.*) REQUIRE_REGEX=require\\\(\'\([-_/\.a-z0-9]+\)\'\\\) JS_OR_JSON_REGEX=\.js\(on\)?$ +HTML_REGEX=\.html$ # Check all js files stored in the repo can require() the packages they need git ls-tree -r HEAD | while IFS='' read line; do @@ -48,7 +49,7 @@ git ls-tree -r HEAD | while IFS='' read line; do extension=${filename##*.} if [[ "$extension" == "js" ]]; then # 'grep -v' to filter out any comment-blocks - grep 'require(' "$fullpath" | grep -v "^ \* " | while IFS='' read line; do + grep 'require(' "$fullpath" | grep -v -E "^ +\* " | while IFS='' read line; do if [[ "$line" =~ $REQUIRE_REGEX ]]; then required=${BASH_REMATCH[1]} fi @@ -62,6 +63,9 @@ git ls-tree -r HEAD | while IFS='' read line; do requirement_found=1 elif [[ -f "$localpath.js" ]] || [[ -f "$localpath/index.js" ]]; then requirement_found=1 + # Webpack HTML loader + elif [[ "$localpath" =~ $HTML_REGEX ]] && [[ -f "$localpath" ]]; then + requirement_found=1 fi else required=${required%%/*}