RequireJS を使用していくつかのサードパーティ フレームワークをロードするJavaEEプロジェクトがあります。それらのフレームワークの 1 つが OpenLayers3 です。Openlayers3 は、グローバルな「ol」変数をネイティブに作成します。ただし、OpenLayers3 は AMD と互換性があるように作成されており、RequireJS を介してモジュールとして機能します。AMD用に最適化されていない「olLayerSwitcher」と呼ばれるOpenLayers3プラグインも使用しています。代わりに、「ol」変数がグローバルであることに依存します。
私の必要な設定は次のようになります:
paths: {
"sinon": ['/webjars/sinonjs/1.7.3/sinon'],
"jquery": ["/webjars/jquery/2.1.4/jquery"],
"backbone": ['/webjars/backbonejs/1.2.1/backbone'],
"underscore": ['/webjars/underscorejs/1.8.3/underscore'],
"text": ['/webjars/requirejs-text/2.0.14/text'],
"log4js": ['/webjars/log4javascript/1.4.13/log4javascript'],
"ol": ['/webjars/openlayers/3.5.0/ol'],
"olLayerSwitcher": ['/js/vendor/ol3-layerswitcher/1.0.1/ol3-layerswitcher']
},
shim: {
"olLayerSwitcher": {
deps: ["ol"],
exports: "olLayerSwitcher"
},
'sinon' : {
'exports' : 'sinon'
}
}
このプロジェクトは Backbone を使用しており、Router モジュール (/src/main/webapp/js/controller/AppRouter.js) が含まれています。
/*jslint browser : true*/
/*global Backbone*/
define([
'backbone',
'utils/logger',
'views/MapView'
], function (Backbone, logger, MapView) {
"use strict";
var applicationRouter = Backbone.Router.extend({
routes: {
'': 'mapView'
},
initialize: function () {
this.LOG = logger.init();
this.on("route:mapView", function () {
this.LOG.trace("Routing to map view");
new MapView({
mapDivId: 'map-container'
});
});
}
});
return applicationRouter;
});
Router モジュールは、View モジュール (/src/main/webapp/js/views/MapView.js) に依存します。
/*jslint browser: true */
define([
'backbone',
'utils/logger',
'ol',
'utils/mapUtils',
'olLayerSwitcher'
], function (Backbone, logger, ol, mapUtils, olLayerSwitcher) {
"use strict";
[...]
initialize: function (options) {
this.LOG = logger.init();
this.mapDivId = options.mapDivId;
this.map = new ol.Map({
[...]
controls: ol.control.defaults().extend([
new ol.control.ScaleLine(),
new ol.control.LayerSwitcher({
tipLabel: 'Switch base layers'
})
])
});
Backbone.View.prototype.initialize.apply(this, arguments);
this.render();
this.LOG.debug("Map View rendered");
}
});
return view;
});
View モジュールは、OpenLayers3 とサードパーティの OpenLayers プラグインの両方を取り込もうとします。
プロジェクトをビルドしてデプロイすると、ブラウザーで正常に動作します。View モジュールが読み込まれると、OpenLayers とサードパーティのプラグインが適切に取り込まれ、すべてが適切にレンダリングされます。
ただし、ジャスミンでこれをテストしようとすると、すべてが崩壊します。
Jasmine の場合、Jasmine-Maven プラグインを使用しています。JasmineJS、PhantomJS、RequireJS をライブラリと共に取り込み、スペックを実行します。問題は、Jasmine 経由で実行すると、MapView モジュールが OpenLayers3 ライブラリとサード パーティのプラグイン (olLayerSwitcher) の両方を読み込もうとするが、サード パーティのプラグインが「ol」を見つけられないために失敗することです。
テスト:
define([
"backbone",
"sinon",
'controller/AppRouter'
], function (Backbone, sinon, Router) {
describe("Router", function () {
beforeEach(function () {
this.router = new Router();
this.routeSpy = sinon.spy();
this.router.bind("route:mapView", this.routeSpy);
try {
Backbone.history.start({silent: true});
} catch (e) {
}
this.router.navigate("elsewhere");
});
it("does not fire for unknown paths", function () {
this.router.navigate("unknown", true);
expect(this.routeSpy.notCalled).toBeTruthy();
});
it("fires the default root with a blank hash", function () {
this.router.navigate("", true);
expect(this.routeSpy.calledOnce).toBeTruthy();
expect(this.routeSpy.calledWith(null)).toBeTruthy();
});
});
});
ジャスミンからのエラー:
[ERROR - 2015-08-08T21:27:30.693Z] Session [4610ead0-3e14-11e5-bb2b-dd2c4b5c2c7b] - page.onError - msg: ReferenceError: Can't find variable: ol
:262 in error
[ERROR - 2015-08-08T21:27:30.694Z] Session [4610ead0-3e14-11e5-bb2b-dd2c4b5c2c7b] - page.onError - stack:
global code (http://localhost:58309/js/vendor/ol3- layerswitcher/1.0.1/ol3-layerswitcher.js:9)
:262 in error
JavaScript Console Errors:
* ReferenceError: Can't find variable: ol
9 行目の ol3-layerswitcher プラグインの関連セクションは次のとおりです。
[...]
ol.control.LayerSwitcher = function(opt_options) {
[...]
したがって、この時点で「ol」が問題であるかどうかに依存します。
Jasmine-Maven プラグインは独自のスペック ランナー HTML を作成し、関連する部分は次のようになります。
<script type="text/javascript">
if(window.location.href.indexOf("ManualSpecRunner.html") !== -1) {
document.body.appendChild(document.createTextNode("Warning: Opening this HTML file directly from the file system is deprecated. You should instead try running `mvn jasmine:bdd` from the command line, and then visit `http://localhost:8234` in your browser. "))
}
var specs = ['spec/controller/AppRouterSpec.js'];
var configuration = {
paths: {
"sinon": ['/webjars/sinonjs/1.7.3/sinon'],
"jquery": ["/webjars/jquery/2.1.4/jquery"],
"backbone": ['/webjars/backbonejs/1.2.1/backbone'],
"underscore": ['/webjars/underscorejs/1.8.3/underscore'],
"text": ['/webjars/requirejs-text/2.0.14/text'],
"log4js": ['/webjars/log4javascript/1.4.13/log4javascript'],
"ol": ['/webjars/openlayers/3.5.0/ol'],
"olLayerSwitcher": ['/js/vendor/ol3-layerswitcher/1.0.1/ol3-layerswitcher']
},
shim: {
"olLayerSwitcher": {
deps: ["ol"],
exports: "olLayerSwitcher"
},
'sinon' : {
'exports' : 'sinon'
}
}
};
if (!configuration.baseUrl) {
configuration.baseUrl = 'js';
}
if (!configuration.paths) {
configuration.paths = {};
}
if (!configuration.paths.specs) {
var specDir = 'spec';
if (!specDir.match(/^file/)) {
specDir = '/'+specDir;
}
configuration.paths.specs = specDir;
}
require.config(configuration);
require(specs, function() {
jasmine.boot();
});
顧客の HTML ランナーを作成することはできますが、何が問題なのかわからないため、何を変更する必要があるのかわかりません。
これは、ブラウザーでテストを読み込むことができ、同じ問題が発生しているため、PhantomJS の問題ではないようです。
ここで何が起こっているのかについて誰かが何か考えを持っていれば幸いです。ジャスミンのテストはこれを完全に実装する最後の行程であり、私はここで完全に立ち往生しているため、サードパーティのモジュールをハックして RequireJS モジュールに変換したくありません。
Jasmine 2.3.0 と RequireJS 2.1.18 を使用しています
これ以上リンクできなくて申し訳ありませんが、これは新しいアカウントであり、十分な担当者がいません。