JGonera has uploaded a new change for review.
https://gerrit.wikimedia.org/r/69959
Change subject: Introduce Class
......................................................................
Introduce Class
Make our inheritance model more consistent. This is mostly copy and
paste + making sure that child classes call parent's constructor.
Change-Id: Ifd38f20ab08cbb311adfef5c53e6707cf1789410
---
M includes/Resources.php
R javascripts/common/Class.js
M javascripts/common/Overlay.js
M javascripts/common/eventemitter.js
M javascripts/common/mf-api.js
M javascripts/common/mf-view.js
M javascripts/common/uploads/PhotoUploader.js
M javascripts/common/uploads/PhotoUploaderPreview.js
M javascripts/modules/editor/EditorOverlay.js
M javascripts/specials/uploads.js
M javascripts/views/page.js
A tests/javascripts/common/test_Class.js
D tests/javascripts/common/test_mf-oop.js
13 files changed, 328 insertions(+), 320 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MobileFrontend
refs/changes/59/69959/1
diff --git a/includes/Resources.php b/includes/Resources.php
index 31d3ab4..f9db0a8 100644
--- a/includes/Resources.php
+++ b/includes/Resources.php
@@ -158,6 +158,7 @@
),
'scripts' => array(
'javascripts/externals/hogan.js',
+ 'javascripts/common/Class.js',
'javascripts/common/eventemitter.js',
'javascripts/common/Router.js',
'javascripts/common/mf-application.js',
@@ -397,7 +398,6 @@
'mediawiki.jqueryMsg',
),
'scripts' => array(
- 'javascripts/common/mf-oop.js',
'javascripts/common/mf-api.js',
'javascripts/common/mf-view.js',
'javascripts/common/Drawer.js',
diff --git a/javascripts/common/mf-oop.js b/javascripts/common/Class.js
similarity index 87%
rename from javascripts/common/mf-oop.js
rename to javascripts/common/Class.js
index d3c3bb7..cc5e604 100644
--- a/javascripts/common/mf-oop.js
+++ b/javascripts/common/Class.js
@@ -40,8 +40,12 @@
return Child;
}
- M.define( 'oop', {
- extend: extend
- } );
+ function Class() {
+ this.initialize.apply( this, arguments );
+ }
+ Class.prototype.initialize = function() {};
+ Class.extend = extend;
+
+ M.define( 'Class', Class );
}( mw.mobileFrontend ) );
diff --git a/javascripts/common/Overlay.js b/javascripts/common/Overlay.js
index c076ded..808261b 100644
--- a/javascripts/common/Overlay.js
+++ b/javascripts/common/Overlay.js
@@ -12,7 +12,7 @@
closeOnBack: false,
initialize: function( options ) {
var self = this;
- this._super( options );
+ options = options || {};
this.parent = options.parent;
this.isOpened = false;
@@ -28,6 +28,8 @@
if ( this.closeOnBack ) {
hideOnRoute();
}
+
+ this._super( options );
},
postRender: function() {
var self = this;
diff --git a/javascripts/common/eventemitter.js
b/javascripts/common/eventemitter.js
index 33226b6..4a6afd7 100644
--- a/javascripts/common/eventemitter.js
+++ b/javascripts/common/eventemitter.js
@@ -1,5 +1,7 @@
( function( M, $ ) {
+ var Class = M.require( 'Class' ), EventEmitter;
+
function callbackProxy( callback ) {
return function() {
var args = Array.prototype.slice.call( arguments, 1 );
@@ -7,44 +9,44 @@
};
}
- function EventEmitter() {}
+ EventEmitter = Class.extend( {
+ /**
+ * Bind a callback to the event.
+ *
+ * @param {string} event Event name.
+ * @param {Function} callback Callback to be bound.
+ */
+ on: function( event, callback ) {
+ $( this ).on( event, callbackProxy( callback ) );
+ return this;
+ },
- /**
- * Bind a callback to the event.
- *
- * @param {string} event Event name.
- * @param {Function} callback Callback to be bound.
- */
- EventEmitter.prototype.on = function( event, callback ) {
- $( this ).on( event, callbackProxy( callback ) );
- return this;
- };
+ /**
+ * Bind a callback to the event and run it only once.
+ *
+ * @param {string} event Event name.
+ * @param {Function} callback Callback to be bound.
+ */
+ one: function( event, callback ) {
+ $( this ).one( event, callbackProxy( callback ) );
+ return this;
+ },
- /**
- * Bind a callback to the event and run it only once.
- *
- * @param {string} event Event name.
- * @param {Function} callback Callback to be bound.
- */
- EventEmitter.prototype.one = function( event, callback ) {
- $( this ).one( event, callbackProxy( callback ) );
- return this;
- };
-
- /**
- * Emit an event. This causes all bound callbacks to be run.
- *
- * @param {string} event Event name.
- * @param {*} [arguments] Optional arguments to be passed to callbacks.
- */
- EventEmitter.prototype.emit = function( event /* , arg1, arg2, ... */ )
{
- var args = Array.prototype.slice.call( arguments, 1 );
- // use .triggerHandler() for emitting events to avoid
accidentally
- // invoking object's functions, e.g. don't call obj.something()
when
- // doing obj.emit( 'something' )
- $( this ).triggerHandler( event, args );
- return this;
- };
+ /**
+ * Emit an event. This causes all bound callbacks to be run.
+ *
+ * @param {string} event Event name.
+ * @param {*} [arguments] Optional arguments to be passed to
callbacks.
+ */
+ emit: function( event /* , arg1, arg2, ... */ ) {
+ var args = Array.prototype.slice.call( arguments, 1 );
+ // use .triggerHandler() for emitting events to avoid
accidentally
+ // invoking object's functions, e.g. don't call
obj.something() when
+ // doing obj.emit( 'something' )
+ $( this ).triggerHandler( event, args );
+ return this;
+ }
+ } );
M.define( 'eventemitter', EventEmitter );
diff --git a/javascripts/common/mf-api.js b/javascripts/common/mf-api.js
index 2c255c8..2d885c6 100644
--- a/javascripts/common/mf-api.js
+++ b/javascripts/common/mf-api.js
@@ -1,8 +1,7 @@
( function( M, $ ) {
- var oop = M.require( 'oop' ),
- EventEmitter = M.require( 'eventemitter' ),
- api;
+ var EventEmitter = M.require( 'eventemitter' ),
+ Api, api;
// TODO: this might be dangerous and cause conflicts with other code
// should we move it to Api#ajax?
@@ -14,153 +13,148 @@
}
} );
- function Api( options ) {
- this.requests = [];
- this.tokenCache = {};
- this.initialize( options );
- }
+ Api = EventEmitter.extend( {
+ /**
+ * Constructor, if you override it, use _super().
+ *
+ * @param {Object} options Object passed to the constructor.
+ */
+ initialize: function() {
+ this.requests = [];
+ this.tokenCache = {};
+ },
- Api.prototype = new EventEmitter();
+ /**
+ * A wrapper for $.ajax() to be used when calling server APIs.
+ * Preprocesses data argument in the following way:
+ * - removes boolean values equal to false
+ * - concatenates Array values with '|'
+ *
+ * @example
+ * <code>
+ * ajax( { a: false, b: [1, 2, 3] }, { type: 'post' } );
+ * // is equal to
+ * $.ajax( {
+ * type: 'post',
+ * data: { b: '1|2|3' }
+ * } );
+ * </code>
+ *
+ * @param {Object} data Data to be preprocessed and added to
options
+ * @param {Object} options Parameters passed to $.ajax()
+ * @return {jQuery.Deferred} Object returned by $.ajax()
+ */
+ ajax: function( data, options ) {
+ var key, request;
+ options = $.extend( {}, options );
- // FIXME: make Api and View inherit from an abstract Class object
- /**
- * Constructor that can be overriden.
- *
- * @param {Object} options Object passed to the constructor.
- */
- Api.prototype.initialize = function() {};
-
- /**
- * A wrapper for $.ajax() to be used when calling server APIs.
- * Preprocesses data argument in the following way:
- * - removes boolean values equal to false
- * - concatenates Array values with '|'
- *
- * @example
- * <code>
- * ajax( { a: false, b: [1, 2, 3] }, { type: 'post' } );
- * // is equal to
- * $.ajax( {
- * type: 'post',
- * data: { b: '1|2|3' }
- * } );
- * </code>
- *
- * @param {Object} data Data to be preprocessed and added to options
- * @param {Object} options Parameters passed to $.ajax()
- * @return {jQuery.Deferred} Object returned by $.ajax()
- */
- Api.prototype.ajax = function( data, options ) {
- var key, request;
- options = $.extend( {}, options );
-
- if (
- typeof data !== 'string' &&
- ( typeof FormData === 'undefined' || !( data instanceof
FormData ) )
- ) {
- for ( key in data ) {
- if ( data[key] === false ) {
- delete data[key];
- } else if ( $.isArray( data[key] ) ) {
- data[key] = data[key].join( '|' );
- }
- }
- }
- options.data = data;
-
- // FIXME: uncomment when
https://bugzilla.wikimedia.org/show_bug.cgi?id=44921 is resolved
- /*
- options.xhr = function() {
- var xhr = $.ajaxSettings.xhr();
- if ( xhr.upload ) {
- // need to bind this event before we open the
connection (see note at
- //
https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress)
- xhr.upload.addEventListener( 'progress',
function( ev ) {
- if ( ev.lengthComputable ) {
- self.emit( 'progress', request,
ev.loaded / ev.total );
+ if (
+ typeof data !== 'string' &&
+ ( typeof FormData === 'undefined' || !(
data instanceof FormData ) )
+ ) {
+ for ( key in data ) {
+ if ( data[key] === false ) {
+ delete data[key];
+ } else if ( $.isArray( data[key] ) ) {
+ data[key] = data[key].join( '|'
);
}
- } );
- }
- return xhr;
- };
- */
-
- request = $.ajax( options );
- this.requests.push( request );
- return request;
- };
-
- /**
- * A wrapper for $.ajax() to be used when calling server APIs.
- * Sends a GET request. See ajax() for details.
- *
- * @param {Object} data Data to be preprocessed and added to options
- * @param {Object} options Parameters passed to $.ajax()
- * @return {jQuery.Deferred} Object returned by $.ajax()
- */
- Api.prototype.get = function( data, options ) {
- options = $.extend( {}, options, { type: 'GET' } );
- return this.ajax( data, options );
- };
-
- /**
- * A wrapper for $.ajax() to be used when calling server APIs.
- * Sends a POST request. See ajax() for details.
- *
- * @param {Object} data Data to be preprocessed and added to options
- * @param {Object} options Parameters passed to $.ajax()
- * @return {jQuery.Deferred} Object returned by $.ajax()
- */
- Api.prototype.post = function( data, options ) {
- options = $.extend( {}, options, { type: 'POST' } );
- return this.ajax( data, options );
- };
-
- /**
- * Abort all unfinished requests issued by this Api object.
- */
- Api.prototype.abort = function() {
- this.requests.forEach( function( request ) {
- request.abort();
- } );
- };
-
- /**
- * Retrieves a token for a given endpoint
- *
- * @param {String} tokenType: Name of the type of token needed e.g.
edit, upload - defaults to edit
- * @param {String} endpoint: Optional alternative host to query via CORS
- * @param {String} caToken: Optional additional CentralAuth token to be
- * sent with the request. This is needed for requests to external wikis
- * where the user is not logged in. caToken is for single use only.
- * @return {jQuery.Deferred} Object returned by $.ajax(), callback will
be passed
- * the token string, false if the user is anon or undefined where not
available or a warning is set
- */
- Api.prototype.getToken = function( tokenType, endpoint, caToken ) {
- var data, d = $.Deferred(), isCacheable;
-
- tokenType = tokenType || 'edit';
- isCacheable = tokenType !== 'centralauth';
-
- if ( !this.tokenCache[ endpoint ] ) {
- this.tokenCache[ endpoint ] = {};
- }
- if ( !M.isLoggedIn() ) {
- return d.reject( 'Token requested when not logged in.'
);
- } else if ( isCacheable && this.tokenCache[ endpoint
].hasOwnProperty( tokenType ) ) {
- return this.tokenCache[ endpoint ][ tokenType ];
- } else {
- data = {
- action: 'tokens',
- type: tokenType
- };
- if ( endpoint ) {
- data.origin = M.getOrigin();
- if ( caToken ) {
- data.centralauthtoken = caToken;
}
}
- this.ajax( data, {
+ options.data = data;
+
+ // FIXME: uncomment when
https://bugzilla.wikimedia.org/show_bug.cgi?id=44921 is resolved
+ /*
+ options.xhr = function() {
+ var xhr = $.ajaxSettings.xhr();
+ if ( xhr.upload ) {
+ // need to bind this event before we
open the connection (see note at
+ //
https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress)
+ xhr.upload.addEventListener(
'progress', function( ev ) {
+ if ( ev.lengthComputable ) {
+ self.emit( 'progress',
request, ev.loaded / ev.total );
+ }
+ } );
+ }
+ return xhr;
+ };
+ */
+
+ request = $.ajax( options );
+ this.requests.push( request );
+ return request;
+ },
+
+ /**
+ * A wrapper for $.ajax() to be used when calling server APIs.
+ * Sends a GET request. See ajax() for details.
+ *
+ * @param {Object} data Data to be preprocessed and added to
options
+ * @param {Object} options Parameters passed to $.ajax()
+ * @return {jQuery.Deferred} Object returned by $.ajax()
+ */
+ get: function( data, options ) {
+ options = $.extend( {}, options, { type: 'GET' } );
+ return this.ajax( data, options );
+ },
+
+ /**
+ * A wrapper for $.ajax() to be used when calling server APIs.
+ * Sends a POST request. See ajax() for details.
+ *
+ * @param {Object} data Data to be preprocessed and added to
options
+ * @param {Object} options Parameters passed to $.ajax()
+ * @return {jQuery.Deferred} Object returned by $.ajax()
+ */
+ post: function( data, options ) {
+ options = $.extend( {}, options, { type: 'POST' } );
+ return this.ajax( data, options );
+ },
+
+ /**
+ * Abort all unfinished requests issued by this Api object.
+ */
+ abort: function() {
+ this.requests.forEach( function( request ) {
+ request.abort();
+ } );
+ },
+
+ /**
+ * Retrieves a token for a given endpoint
+ *
+ * @param {String} tokenType: Name of the type of token needed
e.g. edit, upload - defaults to edit
+ * @param {String} endpoint: Optional alternative host to query
via CORS
+ * @param {String} caToken: Optional additional CentralAuth
token to be
+ * sent with the request. This is needed for requests to
external wikis
+ * where the user is not logged in. caToken is for single use
only.
+ * @return {jQuery.Deferred} Object returned by $.ajax(),
callback will be passed
+ * the token string, false if the user is anon or undefined
where not available or a warning is set
+ */
+ getToken: function( tokenType, endpoint, caToken ) {
+ var data, d = $.Deferred(), isCacheable;
+
+ tokenType = tokenType || 'edit';
+ isCacheable = tokenType !== 'centralauth';
+
+ if ( !this.tokenCache[ endpoint ] ) {
+ this.tokenCache[ endpoint ] = {};
+ }
+ if ( !M.isLoggedIn() ) {
+ return d.reject( 'Token requested when not
logged in.' );
+ } else if ( isCacheable && this.tokenCache[ endpoint
].hasOwnProperty( tokenType ) ) {
+ return this.tokenCache[ endpoint ][ tokenType ];
+ } else {
+ data = {
+ action: 'tokens',
+ type: tokenType
+ };
+ if ( endpoint ) {
+ data.origin = M.getOrigin();
+ if ( caToken ) {
+ data.centralauthtoken = caToken;
+ }
+ }
+ this.ajax( data, {
url: endpoint || M.getApiUrl(),
xhrFields: { withCredentials: true }
} ).then( function( tokenData ) {
@@ -176,12 +170,11 @@
d.reject( 'Bad token name.' );
}
} );
- this.tokenCache[ endpoint ][ tokenType ] = d;
- return d;
+ this.tokenCache[ endpoint ][ tokenType ] = d;
+ return d;
+ }
}
- };
-
- Api.extend = oop.extend;
+ } );
api = new Api();
api.Api = Api;
diff --git a/javascripts/common/mf-view.js b/javascripts/common/mf-view.js
index 4b59ff8..7a4ea76 100644
--- a/javascripts/common/mf-view.js
+++ b/javascripts/common/mf-view.js
@@ -1,7 +1,6 @@
( function( M, $ ) {
- var oop = M.require( 'oop' ),
- EventEmitter = M.require( 'eventemitter' );
+ var EventEmitter = M.require( 'eventemitter' ), View;
/**
* An abstraction over a jQuery element. Should be extended using
extend().
@@ -48,78 +47,76 @@
* @param {Object} options Options for the view, containing the el or
* template data or any other information you want to use in the view.
*/
- function View( options ) {
- options = $.extend( {}, this.defaults, options );
- if ( options.el ) {
- this.$el = $( options.el );
- } else {
- this.$el = $( '<' + this.tagName + '>' );
+ View = EventEmitter.extend( {
+ tagName: 'div',
+
+ /**
+ * Constructor, if you override it, use _super().
+ *
+ * @param {Object} options Object passed to the constructor.
+ */
+ initialize: function( options ) {
+ this._super();
+ options = $.extend( {}, this.defaults, options );
+ if ( options.el ) {
+ this.$el = $( options.el );
+ } else {
+ this.$el = $( '<' + this.tagName + '>' );
+ }
+ this.$el.addClass( this.className );
+
+ // TODO: if template compilation is too slow, don't
compile them on a
+ // per object basis, but don't worry about it now
(maybe add cache to
+ // M.template.compile())
+ if ( typeof this.template === 'string' ) {
+ this.template = M.template.compile(
this.template );
+ }
+
+ this.options = options;
+ this.render( options );
+ },
+
+ /**
+ * Function called before the view is rendered. Can be
redefined in
+ * objects that extend View.
+ *
+ * @param {Object} options Object passed to the constructor.
+ */
+ preRender: function() {},
+
+ /**
+ * Function called after the view is rendered. Can be redefined
in
+ * objects that extend View.
+ *
+ * @param {Object} options Object passed to the constructor.
+ */
+ postRender: function() {},
+
+ /**
+ * Fill this.$el with template rendered using data if template
is set.
+ *
+ * @param {Object} data Template data.
+ */
+ render: function( data ) {
+ data = data || this.options;
+ this.preRender( data );
+ if ( this.template ) {
+ this.$el.html( this.template.render( data ) );
+ }
+ this.postRender( data );
+ },
+
+ /**
+ * Wraps this.$el.find, so that you can search for elements in
the view's
+ * ($el's) scope.
+ *
+ * @param {string} query A jQuery CSS selector.
+ * @return {jQuery} jQuery object containing results of the
search.
+ */
+ $: function( query ) {
+ return this.$el.find( query );
}
- this.$el.addClass( this.className );
-
- // TODO: if template compilation is too slow, don't compile
them on a
- // per object basis, but don't worry about it now (maybe add
cache to
- // M.template.compile())
- if ( typeof this.template === 'string' ) {
- this.template = M.template.compile( this.template );
- }
-
- this.options = options;
- this.initialize( options );
- this.render( options );
- }
-
- View.prototype = new EventEmitter();
- View.prototype.tagName = 'div';
-
- // FIXME: make Api and View inherit from an abstract Class object
- /**
- * Constructor that can be overriden.
- *
- * @param {Object} options Object passed to the constructor.
- */
- View.prototype.initialize = function() {};
-
- /**
- * Function called before the view is rendered. Can be redefined in
- * objects that extend View.
- *
- * @param {Object} options Object passed to the constructor.
- */
- View.prototype.preRender = function() {};
-
- /**
- * Function called after the view is rendered. Can be redefined in
- * objects that extend View.
- *
- * @param {Object} options Object passed to the constructor.
- */
- View.prototype.postRender = function() {};
-
- /**
- * Fill this.$el with template rendered using data if template is set.
- *
- * @param {Object} data Template data.
- */
- View.prototype.render = function( data ) {
- data = data || this.options;
- this.preRender( data );
- if ( this.template ) {
- this.$el.html( this.template.render( data ) );
- }
- this.postRender( data );
- };
-
- /**
- * Wraps this.$el.find, so that you can search for elements in the
view's
- * ($el's) scope.
- *
- * @param {string} query A jQuery CSS selector.
- * @return {jQuery} jQuery object containing results of the search.
- */
- View.prototype.$ = function( query ) {
- return this.$el.find( query );
- };
+ } );
[
'append',
@@ -138,8 +135,6 @@
return this;
};
} );
-
- View.extend = oop.extend;
M.define( 'view', View );
diff --git a/javascripts/common/uploads/PhotoUploader.js
b/javascripts/common/uploads/PhotoUploader.js
index fba9518..b433635 100644
--- a/javascripts/common/uploads/PhotoUploader.js
+++ b/javascripts/common/uploads/PhotoUploader.js
@@ -99,6 +99,7 @@
initialize: function( options ) {
this.log = getLog( options.funnel );
+ this._super( options );
},
postRender: function() {
diff --git a/javascripts/common/uploads/PhotoUploaderPreview.js
b/javascripts/common/uploads/PhotoUploaderPreview.js
index 23e5914..f9f5592 100644
--- a/javascripts/common/uploads/PhotoUploaderPreview.js
+++ b/javascripts/common/uploads/PhotoUploaderPreview.js
@@ -20,6 +20,7 @@
initialize: function( options ) {
this.log = options.log;
+ this._super( options );
},
postRender: function() {
diff --git a/javascripts/modules/editor/EditorOverlay.js
b/javascripts/modules/editor/EditorOverlay.js
index a660719..098be85 100644
--- a/javascripts/modules/editor/EditorOverlay.js
+++ b/javascripts/modules/editor/EditorOverlay.js
@@ -41,9 +41,9 @@
},
initialize: function( options ) {
- this._super( options );
this.api = new EditorApi( { title: options.title,
isNew: options.isNew } );
this.sectionCount = options.sectionCount;
+ this._super( options );
},
postRender: function( options ) {
diff --git a/javascripts/specials/uploads.js b/javascripts/specials/uploads.js
index 165e915..f915ad0 100644
--- a/javascripts/specials/uploads.js
+++ b/javascripts/specials/uploads.js
@@ -12,6 +12,7 @@
UserGalleryApi = Api.extend( {
initialize: function() {
+ this._super();
this.limit = 10;
},
getPhotos: function() {
@@ -71,6 +72,7 @@
this.threshold = 1000;
this.loading = false;
this.api = new UserGalleryApi();
+ this._super();
},
postRender: function() {
this.$end = this.$( '.end' );
diff --git a/javascripts/views/page.js b/javascripts/views/page.js
index 89a3237..3ff065b 100644
--- a/javascripts/views/page.js
+++ b/javascripts/views/page.js
@@ -7,18 +7,18 @@
Section = View.extend( {
template: M.template.get( 'section' ),
defaults: {
- hasReferences: false, // flag for references
heading: '',
- content: '',
- index: -1, // index of this section in the given page
- id: null
+ content: ''
},
initialize: function( options ) {
this.heading = options.heading;
- this.index = options.index;
+ // index of this section in the given page
+ this.index = options.index || -1;
this.content = options.content;
- this.hasReferences = options.hasReferences;
- this.id = options.id;
+ // flag for references
+ this.hasReferences = options.hasReferences || false;
+ this.id = options.id || null;
+ this._super( options );
}
} );
diff --git a/tests/javascripts/common/test_Class.js
b/tests/javascripts/common/test_Class.js
new file mode 100644
index 0000000..a7ea225
--- /dev/null
+++ b/tests/javascripts/common/test_Class.js
@@ -0,0 +1,54 @@
+( function( M ) {
+
+ var Class = M.require( 'Class' );
+
+ QUnit.module( 'MobileFrontend Class' );
+
+ QUnit.test( '.extend', 5, function( assert ) {
+ var Parent, Child, child;
+
+ Parent = Class.extend( {
+ parent: function() {
+ return 'parent';
+ },
+ override: function() {
+ return 'override';
+ },
+ callSuper: function() {
+ return 'super';
+ }
+ } );
+
+ Child = Parent.extend( {
+ override: function() {
+ return 'overriden';
+ },
+ child: function() {
+ return 'child';
+ },
+ callSuper: function() {
+ return this._super() + ' duper';
+ }
+ } );
+
+ child = new Child();
+ assert.strictEqual( child.parent(), 'parent', 'inherit parent
properties' );
+ assert.strictEqual( child.override(), 'overriden', 'override
parent properties' );
+ assert.strictEqual( child.child(), 'child', 'add new
properties' );
+ assert.strictEqual( child.callSuper(), 'super duper', "call
parent's functions" );
+ assert.strictEqual( Child.extend, Class.extend, 'make Child
extendeable' );
+ } );
+
+ QUnit.test( '#initialize', 1, function( assert ) {
+ var Thing, spy = sinon.spy();
+
+ Thing = Class.extend( {
+ initialize: spy
+ } );
+
+ new Thing( 'abc', 123 );
+
+ assert.ok( spy.calledWith( 'abc', 123 ), 'call #initialize when
creating new instance' );
+ } );
+
+}( mw.mobileFrontend ) );
diff --git a/tests/javascripts/common/test_mf-oop.js
b/tests/javascripts/common/test_mf-oop.js
deleted file mode 100644
index 71367ac..0000000
--- a/tests/javascripts/common/test_mf-oop.js
+++ /dev/null
@@ -1,46 +0,0 @@
-( function( M ) {
-
-var oop = M.require( 'oop' );
-
-QUnit.module( 'MobileFrontend oop' );
-
-QUnit.test( '#extend', 5, function() {
- var Child, child;
-
- function Parent() {}
-
- Parent.prototype.parent = function() {
- return 'parent';
- };
-
- Parent.prototype.override = function() {
- return 'override';
- };
-
- Parent.prototype.callSuper = function() {
- return 'super';
- };
-
- Parent.extend = oop.extend;
-
- Child = Parent.extend( {
- override: function() {
- return 'overriden';
- },
- child: function() {
- return 'child';
- },
- callSuper: function() {
- return this._super() + ' duper';
- }
- } );
-
- child = new Child();
- strictEqual( child.parent(), 'parent', 'inherit parent properties' );
- strictEqual( child.override(), 'overriden', 'override parent
properties' );
- strictEqual( child.child(), 'child', 'add new properties' );
- strictEqual( child.callSuper(), 'super duper', "call parent's
functions" );
- strictEqual( Child.extend, oop.extend, 'make Child extendeable' );
-} );
-
-}( mw.mobileFrontend ) );
--
To view, visit https://gerrit.wikimedia.org/r/69959
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ifd38f20ab08cbb311adfef5c53e6707cf1789410
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: JGonera <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits