I have followed the guide from Sitepen to mock AMD modules (LINK), but when I try to mock the same Module twice, the mocking fails, telling me my mock has no constructor. It crashes in the AMD-Mocker here:
try {
originalModule = require(moduleId); [...]
}
Has anybody ever stumbled across this issue and has found a solution for it? It does not help to create two test files, either.
Here is my compressed code:
define(function (require) {
var registerSuite = require('intern!object');
var assert = require('intern/chai!assert');
var amdMocker = require('support/AMDMocker');
registerSuite( function(){
var Hello;
return{
before: function(){
return amdMocker.mock('amd/Hello', {
'amd/Resolver': 'support/ResolverMocked'
}).then(function (mocked) {
Hello = mocked;
});
},
name: 'helloMocked',
'greet': function () {
var hello = new Hello();
}
}
});
registerSuite( function(){
var Hello2;
return{
before: function(){
return amdMocker.mock('amd/Hello', {
'amd/Resolver': 'support/ResolverMocked'
}).then(function (mocked) {
Hello2 = mocked;
});
},
name: 'helloMocked2',
'greet': function () {
var hello = new Hello2(); // here it crashes
}
}
});
});
Related
I'm trying to return some data using nextTick() in vuejs 2 as following
getProperty() {
this.$nextTick(function() {
return 'hello';
});
}
It doesn't work. Any clue?
this.$nextTick this function does not return anything; it just executes your callback after refreshing all new data.
so if you want to set some flag or data you can use modal/variable for that.
new Vue({
data: {
msg: 'hello'
},
methods: {
someTask: function () {
this.msg = 'hello next tick';
this.$nextTick(function() {
this.printVar();
});
},
printVar: function() {
// here this variable will be changed to latest value
// or call another function where this value is used
// this.anotherFunction();
console.log(this.msg);
}
},
ready: function () {
this.someTask();
}
});
or just let us know what you want to do with that so we can provide you better answer.
I am trying to store a resource in a store that can be shared between components according to the following documentation:
https://github.com/vuejs/vue-resource/blob/master/docs/http.md#response
http://vuejs.org/guide/application.html#State_Management
var App = Vue.extend({});
getcolleges = '/wp-json/wp/v2/schools-api?filter[posts_per_page]=9999';
var schoolFilter = Vue.extend({
template: '#school-filter-template',
data: function(){
return {
colleges: ''
}
},
ready: function() {
this.$http.get(getcolleges).then(function(colleges) {
this.$set('colleges', colleges.data);
})
},
});
However, when I try to create a store with the resource to use with other components, I get the following error: "The 'Data' option should be a function that returns a per-instance value in component definitions."
var App = Vue.extend({});
getcolleges = '/wp-json/wp/v2/schools-api?filter[posts_per_page]=9999';
var store = {
data: function(){
return {
colleges: ''
}
},
ready: function() {
vue.$http.get(getcolleges).then(function(colleges) {
vue.$set('colleges', colleges.data);
})
}
}
var schoolFilter = Vue.extend({
template: '#school-filter-template',
data: store
});
I want to create an invisible widget that binds to keypressed anywhere on the webclient after the login.
I have tried to extent Widget
but as i don't need to render anything , i don't know how to put it in the html on screen.
should i try to extent some other class in OpenErp to get this working?
console.log('start') // Custome message to dispaly on console
openerp.web_hello = function(instance) {
console.log('Object',instance);
var invisibleWidget = instance.web.Widget.extend({
template: 'invisibleWidget',
init: function(parent){
this._super(parent);
},
});
};
Following javascript module is a good start for the solution. Just sharing for others who are interested
/*---------------------------------------------------------
* OpenERP module
*---------------------------------------------------------*/
openerp.web_keypressed = function(instance) {
instance.web.InvisibleWidget = instance.web.Widget.extend({
template: 'InvisibleWidget',
init: function() {
this._super.apply(this, arguments);
instance.web.InvisibleWidget = this;
},
start: function() {
this._super.apply(this, arguments);
},
sessKeyPressed: function(ed, e) {
console.log('sessKeyPressed');
},
});
instance.web.WebClient = instance.web.WebClient.extend({
show_application: function() {
this._super.apply(this, arguments);
var self = this;
console.log('webclient extend');
self.invisible = new instance.web.InvisibleWidget(this);
self.invisible.appendTo(self.$el);
console.log(instance.web.InvisibleWidget);
$(document).bind('keypress.session', function (ed, e) {
instance.web.InvisibleWidget.sessKeyPressed(ed, e);
});
},
});
};
This is the flow of the application:
The shell.js loads the schoolyeardialog.js which contains the schoolyearbrowser.js which loads the schoolyearwizard.js via create or edit button.
When I repeat these steps multiple times: click create/edit button then I do multiple
requests in my SchoolyearWizard to this:
$.when(service.editSchoolyear(schoolyearId))
The reason is that the subscribed events are not correctly unsubscribed in my opinion.
I have tried different ways of unsubscribing in the SchoolyearDialog.js file.
Either the events did not fire - when I did the subscription.off(); after the app.on(...)
or It was unsubscribed at the wrong position.
Where should I unsubscribe correctly?
If you guys need a sample repo as visual studio solution I can provide this if it helps or maybe you see clearly and immediately the error?!
I have also thought about unsubscribing from the 2 events create/edit when the SchoolyearDialog module is "unloaded" because then both events could/would be unsubscribed not only the create OR edit subscription as it is now when I either click the add or edit button... how would I do that?
SHELL
define(['plugins/router', 'durandal/app', 'viewmodels/SchoolyearDialog', 'knockout'], function (router, app, schoolyearDialog, ko) {
self.schoolyearIsLoaded = ko.observable(false);
var saveTimeTableSubscription = app.on('savedTimeTable').then(function (options) {
// after coming the 2nd time here
if (!self.schoolyearIsLoaded()) {
router.map([{ route: 'lessonplanner', moduleId: 'viewmodels/lessonplanner', title: 'lesson planner', nav: true },
{ route: 'documentbrowser', moduleId: 'viewmodels/documentbrowser', title: 'document browser', nav: true }])
.buildNavigationModel();
self.schoolyearIsLoaded(true);
}
router.navigate("lessonplanner", true);
});
return {
router: router,
activate: function () {
router.map([{ route: '', moduleId: 'viewmodels/SchoolyearDialog', nav: true, title: 'Schoolyearbrowser' }
]).buildNavigationModel();
return router.activate('SchoolyearDialog');
}
};
});
SchoolyearDialog
define(['durandal/app', 'knockout', 'plugins/router', 'viewmodels/SchoolyearWizard'],
function (app, ko, router, wizard) {
var ctor = function () {
debugger;
var self = this;
self.createSubscribe = ko.observable();
self.editSubscribe = ko.observable();
self.activeScreen = ko.observable('viewmodels/SchoolyearBrowser'); // set the schoolyear browser as default module
var createWizardSubscription = app.on('createWizard').then(function () {
self.createSubscribe().off();
self.createSubscribe(null);
self.activeScreen(new wizard('create'));
}, self);
self.createSubscribe(createWizardSubscription);
var editWizardSubscription = app.on('editWizard').then(function (schoolyearId) {
self.editSubscribe().off();
self.editSubscribe(null);
self.activeScreen(new wizard('edit', schoolyearId));
}, self);
self.editSubscribe(editWizardSubscription);
}
return ctor;
});
SchoolyearBrowser
define(['durandal/app', 'plugins/dialog', 'knockout', 'services/dataservice', 'plugins/router'],
function (app, dialog, ko, dataservice, router) {
var SchoolyearBrowser = function () {
var self = this;
self.schoolyears = ko.observableArray();
$.when(dataservice.getSchoolyears())
.done(function (schoolyearModels) {
self.schoolyears(schoolyearModels);
});
self.create = function () {
app.trigger('createWizard');
}
self.edit = function () {
app.trigger('editWizard', 1);
}
};
return SchoolyearBrowser;
});
SchoolyearWizard
define(['durandal/activator', 'viewmodels/step1', 'viewmodels/step2', 'knockout', 'durandal/app', 'services/dataservice', 'viewmodels/CreateEditSchoolyearViewModel'],
function (activator, Step1, Step2, ko, app, service, CreateEditSchoolyearViewModel) {
var ctor = function (viewMode, schoolyearId) {
debugger;
// depending on the mode I could setup 2 different step modules for create and edit ? and the Wizard has one property called content
if (viewMode === 'edit') {
$.when(service.editSchoolyear(schoolyearId))
.done(function (response) {
debugger;
self.viewModel(new CreateEditSchoolyearViewModel(response));
}).fail(function (error) {
alert(error);
});
}
else if (viewMode === 'create') {
$.when(service.createSchoolyear())
.done(function (response) {
debugger;
self.viewModel(new CreateEditSchoolyearViewModel(response));
}).fail(function (error) {
alert(error);
});
}
var self = this;
var steps = [new Step1(viewMode), new Step2(viewMode)];
var step = ko.observable(0); // Start with first step
self.activeStep = activator.create();
var stepsLength = steps.length;
self.viewModel = ko.observable();
this.hasPrevious = ko.computed(function () {
return step() > 0;
});
self.caption = ko.observable();
this.activeStep(steps[step()]);
this.hasNext = ko.computed(function () {
if ((step() === stepsLength - 1) && self.activeStep().isValid()) {
// save
self.caption('save');
return true;
} else if ((step() < stepsLength - 1) && self.activeStep().isValid()) {
self.caption('next');
return true;
}
});
this.isLastStep = function () {
return step() === stepsLength - 1;
}
this.next = function () {
if (this.isLastStep()) {
var vm = this.activeStep(); //.viewModel;
$.when(service.saveCreateSchoolyear({ schoolyearId: 1 })).done(function () {
app.trigger('savedTimeTable', { isSuccess: true });
}).fail(function (e) {
alert(e);
});
}
else if (step() < stepsLength) {
step(step() + 1);
self.activeStep(steps[step()]);
}
}
this.previous = function () {
if (step() > 0) {
step(step() - 1);
self.activeStep(steps[step()]);
}
}
}
return ctor;
});
This helped me greatly:
activator.deactivate function allows the previous object to execute custom deactivation logic."
SchoolyearDialog.js
self.deactivate = function () {
self.createSubscribe().off();
self.editSubscribe().off();
}
When the schoolyearDialog is deactivated both events are unsubscribed independing wether button create/edit is clicked. This is for me a clean solution :)
I agree with your solution but I'd recommend not to use plain .off() without parameters as this will cause to deregister all the events in the application.
Rather pass the event name as a parameter to your off method:
self.createSubscribe().off('savedTimeTable');
I got the above error message when I ran my test. Below is my code (I'm using Backbone JS and Jasmine for testing). Does anyone know why this happens?
$(function() {
describe("Category", function() {
beforeEach(function() {
category = new Category;
sinon.spy(jQuery, "ajax");
}
it("should fetch notes", function() {
category.set({code: 123});
category.fetchNotes();
expect(category.trigger).toHaveBeenCalled();
}
})
}
You have to remove the spy after every test. Take a look at the example from the sinon docs:
{
setUp: function () {
sinon.spy(jQuery, "ajax");
},
tearDown: function () {
jQuery.ajax.restore(); // Unwraps the spy
},
"test should inspect jQuery.getJSON's usage of jQuery.ajax": function () {
jQuery.getJSON("/some/resource");
assert(jQuery.ajax.calledOnce);
assertEquals("/some/resource", jQuery.ajax.getCall(0).args[0].url);
assertEquals("json", jQuery.ajax.getCall(0).args[0].dataType);
}
}
So in your jasmine test should look like this:
$(function() {
describe("Category", function() {
beforeEach(function() {
category = new Category;
sinon.spy(jQuery, "ajax");
}
afterEach(function () {
jQuery.ajax.restore();
});
it("should fetch notes", function() {
category.set({code: 123});
category.fetchNotes();
expect(category.trigger).toHaveBeenCalled();
}
})
}
What you need in the very beginning is:
before ->
sandbox = sinon.sandbox.create()
afterEach ->
sandbox.restore()
Then call something like:
windowSpy = sandbox.spy windowService, 'scroll'
Please notice that I use coffee script.