Commit e83d6b94 authored by Thomas Lechauve's avatar Thomas Lechauve

New vifib project based on url routing

parent f7c8406d
# Vifib
# See LICENSE file for copyright and license details.
NAME = build
DEVDIR = ${NAME}_dev
RELDIR = ${NAME}
JSDIR = js
FINALJS = vifib.js
FINALCSS = vifib.css
all: test release
#########################################
# Dev environment
#########################################
# Sort files for concatenation
CATJSFILES = ${DEVDIR}/lib/jquery.js ${DEVDIR}/lib/sinon.js ${DEVDIR}/lib/mustache.js ${DEVDIR}/lib/spin.js ${DEVDIR}/lib/modernizr.js ${DEVDIR}/lib/swipe.js ${DEVDIR}/js/jquery.slapos.js ${DEVDIR}/js/init.js ${DEVDIR}/lib/jquery-mobile.js ${DEVDIR}/js/url.js ${DEVDIR}/js/route.js ${DEVDIR}/js/main.js ${DEVDIR}/js/render.js ${DEVDIR}/js/panels.js ${DEVDIR}/js/pages.js ${DEVDIR}/js/pages.mobile.js ${DEVDIR}/js/pages.tablet.js ${DEVDIR}/js/pages.desktop.js
CATCSSFILES = ${DEVDIR}/lib/qunit.css
# List all javascript files except tests files
JSFILES = $(find $(JSDIR) -name 'tests' -prune -o -name "*.js" -print)
dev: ${DEVDIR}/lib/sinon.js ${DEVDIR}/lib/jquery.js ${DEVDIR}/lib/qunit.js ${DEVDIR}/lib/qunit.css ${DEVDIR}/lib/jquery-mobile.js ${DEVDIR}/lib/modernizr.js ${DEVDIR}/lib/mustache.js ${DEVDIR}/lib/spin.js ${DEVDIR}/lib/swipe.js $(patsubst %.js, ${DEVDIR}/js/%.js, $(JSFILES)) ${DEVDIR}/index.html ${DEVDIR}/$(FINALJS) ${DEVDIR}/$(FINALCSS)
${DEVDIR}/index.html: index.html
@mkdir -p $(@D)
cp $< $@
# Lint javascript files #
${DEVDIR}/js/%.js: js/%.js
@mkdir -p $(@D)
#${JSLINT} --indent 2 --maxerr 3 $<
cp $< $@
# Dependencies #
${DEVDIR}/lib/qunit.%:
@mkdir -p $(@D)
curl -s -o $@ http://code.jquery.com/qunit/qunit-1.5.0$(suffix $@)
${DEVDIR}/lib/jquery.js:
@mkdir -p $(@D)
curl -s -o $@ http://code.jquery.com/jquery-1.7.2.js
${DEVDIR}/lib/sinon.js:
@mkdir -p $(@D)
curl -s -o $@ http://sinonjs.org/releases/sinon-1.3.4.js
${DEVDIR}/lib/jquery-mobile.js:
@mkdir -p $(@D)
curl -s -o $@ http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.js
${DEVDIR}/lib/mustache.js:
@mkdir -p $(@D)
curl -s -o $@ https://raw.github.com/janl/mustache.js/master/mustache.js
${DEVDIR}/lib/spin.js:
@mkdir -p $(@D)
curl -s -o $@ http://fgnass.github.com/spin.js/dist/spin.js
${DEVDIR}/lib/swipe.js:
@mkdir -p $(@D)
curl -s -o $@ https://raw.github.com/bradbirdsall/Swipe/master/swipe.js
${DEVDIR}/lib/modernizr.js:
@mkdir -p $(@D)
curl -s -o $@ http://modernizr.com/downloads/modernizr-2.5.3.js
# Concatenation #
${DEVDIR}/$(FINALJS): $(CATJSFILES)
@mkdir -p $(@D)
cat $^ > $@
${DEVDIR}/$(FINALCSS): $(CATCSSFILES)
@mkdir -p $(@D)
cat $^ > $@
#########################################
# Automated test
#########################################
test: dev $(patsubst js/tests/%_test.html, ${DEVDIR}/tests/%_test.html.ok, $(wildcard js/tests/*_test.html))
${DEVDIR}/tests/%_test.html: js/tests/%_test.html
@mkdir -p $(@D)
cp $< $@
${DEVDIR}/tests/%_test.js: js/tests/%_test.js
@mkdir -p $(@D)
cp $< $@
${DEVDIR}/tests/%_test.html.ok: ${DEVDIR}/tests/%_test.html ${DEVDIR}/tests/%_test.js ${DEVDIR}/js/%.js
xvfb-run phantomjs js/tests/run-qunit.js $<
@sleep 1
touch $@
#########################################
# Release
#########################################
release:
#########################################
# Cleaning
#########################################
clean:
@echo cleaning
rm -rf ${DEVDIR} ${RELDIR}
$(document).bind("mobileinit", function () {
var spinOptions = {color: "#FFFFFF", lines:30, length:0, width:5, radius:7, rotate:0, trail:60, speed:1.6};
$.vifib = {} || $.vifib;
//SlapOs configuration
$(document).slapos({
// REST API url
'host': 'http://10.8.2.34/t139/portal_vifib_rest_api/v1',
// Facebook application id
'fbappid': '322443267846597',
// Google application id
'ggappid': '380290002359.apps.googleusercontent.com'
});
//$(document).slapos('store', 'host', '/fake');
$.mobile.ajaxEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
// Disable transition
//$.mobile.defaultPageTransition = 'none';
// Remove page from DOM when it's being replaced
$('div[data-role="page"]').live('pagehide', function (event, ui) {
$(event.currentTarget).remove();
});
});
(function ($) {
'use strict';
var methods = {
init: function (options) {
return this.each(function () {
var settings = $.extend({
storage: 'localstorage'
}, options),
setting;
methods.store = settings.storage === 'localstorage' ? methods.lStore : methods.cStore;
for (setting in settings) {
if (settings.hasOwnProperty(setting)) {
$(this).slapos('store', setting, settings[setting]);
}
}
});
},
/* Getters & Setters shortcuts */
access_token: function (value) {
return $(this).slapos('store', 'access_token', value);
},
host: function (value) {
return $(this).slapos('store', 'host', value);
},
appid: function (value) {
return $(this).slapos('store', 'appid', value);
},
deleteStore: function (name) {
delete window.localStorage[name];
},
/* Local storage method */
lStore: function (name, value) {
if (Modernizr.localstorage) {
return value === undefined ? window.localStorage[name] : window.localStorage[name] = value;
}
return false;
},
/* Cookie storage method */
cStore: function (name, value) {
if (value !== undefined) {
document.cookie = name + '=' + value + ';domain=' + window.location.hostname + ';path=' + window.location.pathname;
} else {
var i, x, y, cookies = document.cookie.split(';');
for (i = 0; i < cookies.length; i += 1) {
x = cookies[i].substr(0, cookies[i].indexOf('='));
y = cookies[i].substr(cookies[i].indexOf('=') + 1);
x = x.replace(/^\s+|\s+$/g, '');
if (x === name) {
return unescape(y);
}
}
}
},
statusDefault: function () {
return {
0: function () { console.error('status error code: 0'); },
404: function () { console.error('status error code: Not Found !'); },
500: function () { console.error('Server error !'); }
};
},
request: function (type, method, args) {
var statusCode, data;
if (args.hasOwnProperty('statusCode')) {
statusCode = args.statusCode || methods.statusDefault();
} else {
statusCode = methods.statusDefault();
}
if (args.hasOwnProperty('data')) {
data = args.data || undefined;
} else {
data = undefined;
}
delete args.data;
$.extend(args, {statusCode: statusCode});
return this.each(function () {
var ajaxOptions = {
type: type,
url: $(this).slapos('host') + method,
contentType: 'application/json',
//cache: false,
data: JSON.stringify(data),
datatype: 'json',
context: $(this),
headers: {
'Accept': 'application/json',
},
beforeSend: function (xhr) {
if ($(this).slapos('access_token')) {
xhr.setRequestHeader('Authorization', $(this).slapos('store', 'token_type') + ' ' + $(this).slapos('access_token'));
}
}
};
$.extend(ajaxOptions, args);
$.ajax(ajaxOptions);
});
},
instanceList: function (args) {
return $(this).slapos('request', 'GET', '/instance', args);
},
instanceInfo: function (url, args) {
$.extend(args, {url: url});
return $(this).slapos('request', 'GET', '', args);
},
instanceRequest: function (args) {
return $(this).slapos('request', 'POST', '/instance', args);
},
instanceBang: function (url, args) {
$.extend(args, {url: url + '/bang'});
return $(this).slapos('request', 'POST', '', args);
},
instanceCertificate: function (url, args) {
$.extend(args, {url: url + '/certificate'});
return $(this).slapos('request', 'GET', '', args);
},
//softwareList: function (args) {
//return $(this).slapos('request', '', args);
//},
//softwareInfo: function (url, args) {
//return $(this).slapos('request', '', args);
//},
//computerList: function (args) {
//return $(this).slapos('request', '', args);
//},
computerInfo: function (url, args) {
$.extend(args, {url: url});
return $(this).slapos('request', 'GET', '', args);
}
};
$.fn.slapos = function (method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.slapos');
}
};
}(jQuery));
'use strict';
var getDevice = function (w) {
return 'mobile';
if (w < 600) {
return 'mobile';
}
if (w < 1281) {
return 'tablet';
}
return 'desktop';
},
device = getDevice($(window).width());
var body = $("body");
$.vifib.devices = {
"mobile": function (url) {
$('body')
.route('add', '')
.done($.vifib.mobile.overview);
$('body')
.route('add', '/login/facebook')
.done($.vifib.login.facebook);
$('body')
.route('add', '/login/google')
.done($.vifib.login.google);
$('body')
.route('add', '/overview')
.done($.vifib.mobile.overview);
$('body')
.route('add', '/library<path:url>')
.done($.vifib.mobile.library.dispatch);
$('body')
.route('add', '/dashboard<path:url>')
.done($.vifib.mobile.dashboard.dispatch);
},
"tablet": function () {
$('body')
.route('add', '')
.done($.vifib.tablet.overview);
$('body')
.route('add', '/overview')
.done($.vifib.tablet.overview);
$('body')
.route('add', '/library<path:url>')
.done($.vifib.tablet.library.dispatch);
$('body')
.route('add', '/dashboard<path:url>')
.done($.vifib.tablet.dashboard.dispatch);
},
"desktop": function () {
$('body')
.route('add', '')
.done($.vifib.desktop.redirect);
$('body')
.route('add', '<path:url>')
.done($.vifib.desktop.dispatch);
}
}
$.vifib.isauthenticated = function () {
return true;
}
$.vifib.startrouter = function () {
$('body')
.route('go', $.url.getPath())
.fail($.vifib.mobile.nopage);
}
/* Thanks to Ben Alman
* https://raw.github.com/cowboy/jquery-misc/master/jquery.ba-serializeobject.js
*/
$.fn.serializeObject = function(){
var obj = {};
$.each( this.serializeArray(), function(i,o){
var n = o.name,
v = o.value;
obj[n] = obj[n] === undefined ? v
: $.isArray( obj[n] ) ? obj[n].concat( v )
: [ obj[n], v ];
});
return obj;
}
$.fn.spin = function(opts) {
this.each(function() {
var $this = $(this),
data = $this.data();
if (data.spinner) {
data.spinner.stop();
delete data.spinner;
}
if (opts !== false) {
data.spinner = new Spinner($.extend({color: $this.css('color')}, opts)).spin(this);
}
});
return this;
}
$(document).ready(function () {
// bind on resize screen event
$(window).resize(function () {
setTimeout(function () {
var curdevice = getDevice($(window).width());
if (device !== curdevice) {
device = curdevice;
$.routereset();
$.vifib.devices[device]();
$.vifib.startrouter();
}
}, 800);
});
// Url change event
$.url.onhashchange(function () {
var options = $.url.getOptions();
if (options.hasOwnProperty('access_token')) {
$(document).slapos('access_token', options.access_token);
}
$.vifib.devices[device]();
$.vifib.startrouter();
});
});
$.vifib.desktop = {
redirect: function (route) {
$.url.go('/overview');
},
dispatch: function (route) {
var page = $.vifib.threepanel([
$.vifib.panel.sidemenu.main,
$.vifib.panel.blank,
$.vifib.panel.blank
], [
{links: [
{url: '#/library/', name: 'Library'},
{url: 'http://packages.python.org/slapos.core/', name: 'Documentation'}
]}
]);
// header
page.prepend(Mustache.render($.vifib.header.default, {title: 'Vifib'}));
// rendering
$.vifib.changepage($(page));
$('#panel-1')
.route('add', '/library<path:url>', 1)
.done($.vifib.desktop.library.dispatch);
$('#panel-1')
.route('add', '/overview', 1)
.done($.vifib.desktop.overview);
$('#panel-1')
.route('add', '/dashboard<path:url>', 1)
.done($.vifib.desktop.dashboard.dispatch);
$('#panel-1')
.route('go', $.url.getPath(), 1)
.fail(function () { $.vifib.replacepanel($(this), $.vifib.panel.failed)});
},
overview: function (route) {
$.vifib.replacepanel($(this), $.vifib.panel.carousel);
if ( Modernizr.csstransforms ) {
window.mySwipe = new Swipe(document.getElementById('slider'), {
speed: 800,
auto: 4000,
continous: true
});
}
$.vifib.replacepanel($('#panel-2'), $.vifib.panel.login);
window.mySwipe.begin();
},
library: {
dispatch: function (route) {
$.vifib.replacepanel($(this), $.vifib.panel.sidemenu.library, {
links: [
{url: '#/library/', name: 'Overview'},
{url: '#/library/all', name: 'See all softwares'}
],
categories: [
{url: '#/library/categorie/vm', name: 'Virtual Machine'},
{url: '#/library/categorie/db', name: 'Database'}
]
});
$('#panel-2')
.route('add', '/library/', 2)
.done($.vifib.desktop.library.overview);
$('#panel-2')
.route('add', '/library/software/<softid>', 2)
.done($.vifib.desktop.library.software);
$('#panel-2')
.route('add', '/library/all', 2)
.done($.vifib.desktop.library.all);
$('#panel-2')
.route('go', $.url.getPath(), 2)
.fail(function () { $.vifib.replacepanel($(this), $.vifib.panel.failed)});
},
overview: function (route) {
$.vifib.replacepanel($(this), $.vifib.panel.library, {
most: [
{url: '#/library/software/kvm', name: 'Kvm'},
],
newest: [
{url: '#/library/software/html5', name: 'html5 AS'}
]
});
},
software: function (softid) {
$(this).slapos('softwareInfo', softid, {
success: function (response) {
$.vifib.replacepanel($(this), $.vifib.panel.software, response);
}
});
},
all: function () {
$.vifib.replacepanel($(this), $.vifib.panel.allsoftware);
$.vifib.softwareList($(this));
}
},
dashboard: {
dispatch: function (route) {
$.vifib.replacepanel($(this), $.vifib.panel.simplelist, {
links: [
{url: '#/dashboard/instance/list', name: 'Instances'},
{url: '#/dashboard/computer/list', name: 'Computers'}
]
});
$('#panel-2')
.route('add', '/dashboard/', 2)
.done($.vifib.desktop.dashboard.instancelist);
$('#panel-2')
.route('add', '/dashboard/instance/list', 2)
.done($.vifib.desktop.dashboard.instancelist);
$('#panel-2')
.route('add', '/dashboard/instance/id/<instid>', 2)
.done($.vifib.desktop.dashboard.instance);
$('#panel-2')
.route('add', '/dashboard/computer/list', 2)
.done($.vifib.desktop.dashboard.computerlist);
$('#panel-2')
.route('add', '/dashboard/computer/id/<compid>', 2)
.done($.vifib.desktop.dashboard.computer);
$('#panel-2')
.route('go', $.url.getPath(), 2)
.fail(function () { $.vifib.replacepanel($(this), $.vifib.panel.failed)});
},
instancelist: function (route) {
$.vifib.replacepanel($(this), $.vifib.panel.allinstance);
$.vifib.instanceList($(this));
},
instance: function (instid) {
$(this).slapos('instanceInfo', instid, {
success: function (response) {
$.vifib.replacepanel($(this), $.vifib.panel.instance, response);
}
});
},
computerlist: function (route) {
$.vifib.replacepanel($(this), $.vifib.panel.allcomputer);
$.vifib.computerList($(this));
},
computer: function (compid) {
$(this).slapos('computerInfo', compid, {
success: function (response) {
$.vifib.replacepanel($(this), $.vifib.panel.computer, response);
}
});
}
}
};
$.vifib.login = {
facebook: function (params) {
var redirect = window.location.origin + window.location.pathname + '#/dashboard/' + '?',
fburl = 'https://www.facebook.com/dialog/oauth?' +
'client_id=' + $(document).slapos('store', 'fbappid') +
'&redirect_uri=' + encodeURIComponent(redirect) +
'&scope=email' +
'&response_type=token';
// set token type to Facebook for js library
$(document).slapos('store', 'token_type', 'Facebook');
window.location.href = fburl;
},
google: function (params) {
var redirect = window.location.origin + window.location.pathname + '?',
ggurl = 'https://accounts.google.com/o/oauth2/auth?' +
'client_id=' + $(document).slapos('store', 'ggappid') +
'&redirect_uri=' + encodeURIComponent(redirect) +
'&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email++https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile' +
'&response_type=token';
console.log(ggurl);
$(document).slapos('store', 'token_type', 'Google');
window.location.href = ggurl;
}
}
$.vifib.statuscode = {
400: function (jqxhr, textstatus) {
$.vifib.replacepanel($(this), $.vifib.panel.badrequest);
},
401: function (jqxhr, textstatus) {
$.url.redirect('/login');
},
402: function (jqxhr, textstatus) {
$.vifib.replacepanel($(this), $.vifib.panel.payment);
},
404: function (jqxhr, textstatus) {
$.vifib.replacepanel($(this), $.vifib.panel.notfound);
},
500: function (jqxhr, textstatus) {
$.vifib.replacepanel($(this), $.vifib.panel.internalerror);
},
}
$.vifib.softwareList = function (context) {
var list;
return context.each(function () {
list = $(this).find('ul');
$(this).slapos('softwareList', {
success: function (response) {
$.each(response.list, function (index, soft) {
var row = $.vifib.fillRowSoftware($('<li></li>'), soft);
list.append(row);
});
list.listview('refresh');
}
});
});
}
$.vifib.instanceList = function (context) {
var list;
return context.each(function () {
list = $(this).find('ul');
$(this).slapos('instanceList', {
success: function (response) {
$.each(response.list, function (index, inst) {
var row = $.vifib.fillRowInstance($('<li></li>'), inst);
list.append(row);
});
list.listview('refresh');
}
});
});
}
$.vifib.computerList = function (context) {
var list;
return context.each(function () {
list = $(this).find('ul');
$(this).slapos('computerList', {
success: function (response) {
$.each(response.list, function (index, comp) {
var row = $.vifib.fillRowComputer($('<li></li>'), comp);
list.append(row);
});
list.listview('refresh');
}
});
});
}
$.vifib.fillRowSoftware = function (context, softid) {
return context.each(function () {
$(this).slapos('softwareInfo', softid, {
success: function (response) {
$.extend(response, {softurl: '#/library/software/' + softid});
$(this).html(Mustache.render($.vifib.panel.rowsoftware, response));
}
});
})
}
$.vifib.fillRowInstance = function (context, instid) {
return context.each(function () {
$(this).slapos('instanceInfo', instid, {
success: function (response) {
$.extend(response, {insturl: '#/dashboard/instance/id' + instid});
$(this).html(Mustache.render($.vifib.panel.rowinstance, response));
}
});
})
}
$.vifib.fillRowComputer = function (context, compid) {
return context.each(function () {
$(this).slapos('computerInfo', compid, {
success: function (response) {
$.extend(response, {compurl: '#/dashboard/computer/id/' + compid});
$(this).html(Mustache.render($.vifib.panel.rowcomputer, response));
}
});
})
}
$.vifib.mobile = {
nopage: function () {
var page = $.vifib.onepanel($.vifib.panel.failed);
page.prepend(Mustache.render($.vifib.header.default, {title: 'Oops'}));
$.vifib.changepage($(page));
},
overview: function (route) {
var page;
// rendering
page = $.vifib.onepanel($.vifib.panel.login);
// header
page.prepend(Mustache.render($.vifib.header.default, {title: 'Vifib'}));
// footer navbar
page.append($.vifib.footer.overview);
// rendering
$.vifib.changepage($(page));
},
library: {
dispatch: function (route) {
$('body')
.route('add', '/library/', 1)
.done($.vifib.mobile.library.overview);
$('body')
.route('add', '/library/software/<softid>', 1)
.done($.vifib.mobile.library.software);
$('body')
.route('add', '/library/all', 1)
.done($.vifib.mobile.library.all);
$('body')
.route('go', $.url.getPath(), 1)
.fail($.vifib.mobile.nopage);
},
overview: function () {
page = $.vifib.onepanel($.vifib.panel.library, {
most: [
{url: '#/library/software/kvm', name: 'Kvm'},
],
newest: [
{url: '#/library/software/html5', name: 'html5 AS'}
]
});
// header
page.prepend(Mustache.render($.vifib.header.default, {title: 'Library'}));
page.append(Mustache.render($.vifib.panel.simplelist, {
links: [
{url: '#/library/all', name: 'See all softwares'},
{url: '#/library/categories', name: 'See categories'}
]
}));
// footer navbar
page.append($.vifib.footer.overview);
// rendering
$.vifib.changepage($(page));
},
software: function (softid) {
$('body').slapos('softwareInfo', softid, {
success: function (response) {
var page;
page = $.vifib.onepanel($.vifib.panel.software, response);
// header
page.prepend(Mustache.render($.vifib.header.default, {title: response.name}));
// footer navbar
page.append($.vifib.footer.overview);
// rendering
$.vifib.changepage($(page));
}
});
},
all: function () {
var page = $.vifib.onepanel($.vifib.panel.allsoftware);
$.vifib.softwareList($(page));
page.prepend(Mustache.render($.vifib.header.default, {title: 'All softwares'}));
page.append($.vifib.footer.overview);
$.vifib.changepage($(page));
}
},
dashboard: {
dispatch: function (route) {
$('body')
.route('add', '/dashboard/', 1)
.done($.vifib.mobile.dashboard.home);
$('body')
.route('add', '/dashboard/instance/list', 1)
.done($.vifib.mobile.dashboard.instancelist);
$('body')
.route('add', '/dashboard/instance/request', 1)
.done($.vifib.mobile.dashboard.instancerequest);
$('body')
.route('add', '/dashboard/instance/id<path:instid>', 1)
.done($.vifib.mobile.dashboard.instance);
$('body')
.route('add', '/dashboard/computer/list', 1)
.done($.vifib.mobile.dashboard.computerlist);
$('body')
.route('add', '/dashboard/computer/id/<compid>', 1)
.done($.vifib.mobile.dashboard.computer);
$('body')
.route('go', $.url.getPath(), 1)
.fail($.vifib.mobile.nopage);
},
home: function (route) {
var page = $.vifib.onepanel($.vifib.panel.simplelist, {
links: [
{url: '#/dashboard/instance/list', name: 'Instances'},
{url: '#/dashboard/computer/list', name: 'Computers'}
]
});
page.prepend(Mustache.render($.vifib.header.default, {title: 'Dashboard'}));
$.vifib.changepage($(page));
},
instancelist: function (route) {
var page = $.vifib.onepanel($.vifib.panel.instancelist);
page.prepend(Mustache.render($.vifib.header.default, {title: 'Instances'}));
$.vifib.changepage($(page));
$.vifib.instanceList($(page));
},
instancerequest: function (route) {
var page = $.vifib.onepanel($.vifib.panel.instancerequest);
page.prepend(Mustache.render($.vifib.header.default, {title: 'Request instance'}));
$.vifib.changepage($(page));
$("#instancerequest").submit(function () {
var data = {
"status": "started",
"slave": false,
"software_release": "http://example.com/example.cfg",
"software_type": "type_provided_by_the_software",
"parameter": {
"Custom1": "one string",
"Custom2": "one float",
"Custom3": [
"abc",
"def"
]
},
"sla": {
"computer_id": "COMP-0"
}
};
$.extend(data, $(this).serializeObject());
$(this).slapos('instanceRequest', {
data: data,
success: function (response) {
$.url.redirect('/dashboard/instance/list');
}
});
return false;
});
},
instance: function (instid) {
var page;
$(this).slapos('instanceInfo', instid, {
success: function (response) {
page = $.vifib.onepanel($.vifib.panel.instance, response);
page.prepend(Mustache.render($.vifib.header.default, {title: 'Instance'}));
$.vifib.changepage($(page));
}
});
},
computerlist: function (route) {
var page = $.vifib.onepanel($.vifib.panel.allcomputer);
page.prepend(Mustache.render($.vifib.header.default, {title: 'Computers'}));
$.vifib.changepage($(page));
$.vifib.computerList($(page));
},
computer: function (compid) {
var page;
$(this).slapos('computerInfo', compid, {
success: function (response) {
page = $.vifib.onepanel($.vifib.panel.computer, response);
page.prepend(Mustache.render($.vifib.header.default, {title: 'Computer'}));
$.vifib.changepage($(page));
}
});
}
}
};
$.vifib.tablet = {
overview: function (route) {
var page = $.vifib.twopanel([
$.vifib.panel.sidemenu.main,
$.vifib.panel.login
], [
{links: [
{url: '#/library/', name: 'Library'},
{url: 'http://packages.python.org/slapos.core/', name: 'Documentation'}
]}
]);
// header
page.prepend(Mustache.render($.vifib.header.default, {title: 'Vifib'}));
// rendering
$.vifib.changepage($(page));
},
library: {
dispatch: function (route) {
var page = $.vifib.twopanel([
$.vifib.panel.sidemenu.library,
$.vifib.panel.blank
], [
{links: [
{url: '#/library/', name: 'Overview'},
{url: '#/library/all', name: 'See all softwares'}
],categories: [
{url: '#/library/categorie/vm', name: 'Virtual Machine'},
{url: '#/library/categorie/db', name: 'Database'}
]}
]);
// header
page.prepend(Mustache.render($.vifib.header.default, {title: 'Library'}));
// rendering
$.vifib.changepage($(page));
$('#panel-1')
.route('add', '/library/', 1)
.done($.vifib.tablet.library.overview);
$('#panel-1')
.route('add', '/library/software/<softid>', 1)
.done($.vifib.tablet.library.software);
$('#panel-1')
.route('add', '/library/all', 1)
.done($.vifib.tablet.library.all);
$('#panel-1')
.route('go', $.url.getPath(), 1)
.fail(function () { $.vifib.replacepanel($(this), $.vifib.panel.failed)});
},
overview: function () {
$.vifib.replacepanel($(this), $.vifib.panel.library, {
most: [{url: '#/library/software/kvm', name: 'Kvm'},],
newest: [{url: '#/library/software/html5', name: 'html5 AS'}]
});
},
software: function (softid) {
$(this).slapos('softwareInfo', softid, {
success: function (response) {
$.vifib.replacepanel($(this), $.vifib.panel.software, response);
},
statusCode: $.extend(false, $.vifib.statuscode, {
404: function (jqxhr, textstatus) {
$.vifib.replacepanel($(this), $.vifib.panel.nosoftware, {name: softid});
}
})
});
},
all: function (softid) {
$.vifib.replacepanel($(this), $.vifib.panel.allsoftware);
$.vifib.softwareList($(this));
}
},
dashboard: {
dispatch: function (route) {
var page = $.vifib.twopanel([
$.vifib.panel.simplelist,
$.vifib.panel.blank
], [
{links: [
{url: '#/library/', name: 'Library'},
{url: 'http://packages.python.org/slapos.core/', name: 'Documentation'},
{url: '#/dashboard/instance/list', name: 'Instances'},
{url: '#/dashboard/computer/list', name: 'Computers'}
]}
]);
page.prepend(Mustache.render($.vifib.header.default, {title: 'Dashboard'}));
$.vifib.changepage($(page));
$('#panel-1')
.route('add', '/dashboard/', 1)
.done($.vifib.tablet.dashboard.instancelist);
$('#panel-1')
.route('add', '/dashboard/instance/list', 1)
.done($.vifib.tablet.dashboard.instancelist);
$('#panel-1')
.route('add', '/dashboard/instance/id/<instid>', 1)
.done($.vifib.tablet.dashboard.instance);
$('#panel-1')
.route('add', '/dashboard/computer/list', 1)
.done($.vifib.tablet.dashboard.computerlist);
$('#panel-1')
.route('add', '/dashboard/computer/id/<compid>', 1)
.done($.vifib.tablet.dashboard.computer);
$('#panel-1')
.route('go', $.url.getPath(), 1)
.fail(function () { $.vifib.replacepanel($(this), $.vifib.panel.failed)});
},
instancelist: function (route) {
$.vifib.replacepanel($(this), $.vifib.panel.allinstance);
$.vifib.instanceList($(this));
},
instance: function (instid) {
$(this).slapos('instanceInfo', instid, {
success: function (response) {
$.vifib.replacepanel($(this), $.vifib.panel.instance, response);
},
statusCode: $.extend(false, $.vifib.statuscode, {
404: function (jqxhr, textstatus) {
$.vifib.replacepanel($(this), $.vifib.panel.noinstance, {name: instid});
}
})
});
},
computerlist: function (route) {
$.vifib.replacepanel($(this), $.vifib.panel.allcomputer);
$.vifib.computerList($(this));
},
computer: function (compid) {
$(this).slapos('computerInfo', compid, {
success: function (response) {
$.vifib.replacepanel($(this), $.vifib.panel.computer, response);
},
statusCode: $.extend(false, $.vifib.statuscode, {
404: function (jqxhr, textstatus) {
$.vifib.replacepanel($(this), $.vifib.panel.nocomputer, {name: compid});
}
})
});
}
}
};
$.vifib.panel = {
carousel:
'<article id="slider">' +
'<ul>' +
'<li style="display: block">' +
'<h2>Paas Without limit</h2>' +
'<p>c c++ java javascript perl php python</p><p>kumofs mysql mariadb memcached</p><p>apache nodejs flask tomcat zope</p>' +
'</li>' +
'<li style="display: none">' +
'<h2>Iaas broker</h2>' +
'<p>xen kvm hyperv vmware openstack</p><p>opennebula amazon eucalyptus</p><p> niftyname gandi rackspace</p>' +
'</li>' +
'<li style="display: none">' +
'<h2>Resilient Cloud Computing</h2>' +
'<fieldset class="ui-grid-a">' +
'<div class="ui-block-a">' +
'<ul>' +
'<li>decentralized</li>' +
'<li>open-source</li>' +
'</ul>' +
'</div>' +
'<div class="ui-block-b">' +
'<ul>' +
'<li>10x cost efficient</li>' +
'<li>tremendously simpler</li>' +
'</ul>' +
'</div>' +
'</fieldset>' +
'</li>' +
'<li style="display: none">' +
'<h2>Mobile Edge Computing</h2>' +
'<p>bsd linux macos windows android tizen</p>' +
'</li>' +
'<li style="display: none">' +
'<h2>Billing</h2>' +
'<p>accoutning billing charging crm portal market</p>' +
'</li>' +
'<li style="display: none">' +
'<h2>Saas for free</h2>' +
'<p>wordpress drupal erp5 prestashop joomla</p><p>xwiki mediawiki oscommerce sugarcrm</p><p>phpbb facturalux zabbix</p>' +
'</li>' +
'</ul>' +
'</article>',
simplelist:
'<article>' +
'<ul data-role="listview">' +
'{{# links }}' +
'<li><a href="{{ url }}">{{ name }}</a></li>' +
'{{/ links }}' +
'</ul>' +
'</article>',
failed:
'<article>' +
'<center><h4>This page does not exist</h4></center>' +
'</article>',
blank:
'<article></article>',
login:
'<article>' +
'<h2>Sign in with</h2>' +
'<a data-role="button" href="#/login/facebook">Facebook</a><br/>' +
'<a data-role="button" href="#/login/google">Google</a>' +
'</article>',
sidemenu: {
main: '<aside><nav><ul data-role="listview">{{# links }}<li><a href="{{ url }}">{{ name }}</a></li>{{/ links }}</ul></nav></aside>',
library:
'<aside><nav>' +
'<ul data-role="listview" data-theme="d">' +
'{{# links }}' +
'<li><a href="{{ url }}">{{ name }}</a></li>' +
'{{/ links }}' +
'<li data-role="divider">Categories</li>' +
'{{# categories }}' +
'<li><a href="{{ url }}">{{ name }}</a></li>' +
'{{/ categories }}' +
'</ul></nav></aside>'
},
categories:
'<article><ul data-role="listview"><li data-role="divider">Categories</li>{{# categories }}<li><a href="{{ url }}">{{ name }}</a></li>{{/ categories }}</ul></article>',
library:
'<article>' +
'<form id="search-library">' +
'<div data-role="fieldcontain" class="ui-hide-label">' +
'<label for="search"></label>' +
'<input type="search" name="search" placeholder="Search"/>' +
'</div>' +
'</form>' +
'<ul data-role="listview" data-inset="true">' +
'<li data-role="list-divider">Most downloaded</li>' +
'{{# most }}' +
'<li><a href="{{ url }}"><h4>{{ name }}</h4></a></li>' +
'{{/ most }}' +
'<li data-role="list-divider">Brand new</li>' +
'{{# newest }}' +
'<li><a href="{{ url }}"><h4>{{ name }}</h4></a></li>' +
'{{/ newest }}' +
'</ul></article>',
software:
'<article>' +
'<img src="{{ image_url }}">' +
'<p><b>{{ description }}</b></p>' +
'<a data-role="button" href="#/login">Buy it for {{ price }}&euro;</a>' +
'</article>',
allsoftware:
'<article>' +
'<ul data-role="listview">' +
'</ul>' +
'</article>',
rowsoftware:
'<a href="{{ softurl }}">' +
'{{# thumb_url }}' +
'<img src="{{ thumb_url }}">'+
'{{/ thumb_url }}' +
'<h3>{{ name }}</h3>' +
'</a>',
instancerequest:
'<article>' +
'<form id="instancerequest">' +
'<div data-role="fieldcontain">' +
'<label for="title" class="ui-input-text">Title:</label>' +
'<input type="text" name="title" required/>' +
'</div>' +
'<div data-role="fieldcontain">' +
'<label for="software_release" class="ui-input-text">Software release:</label>' +
'<input type="text" name="software_release" value="http://example.com/example.cfg"/>' +
'</div>' +
'<button value="Submit" type="submit">Submit</button>' +
'</form>' +
'</article>',
instance:
'<article>' +
'{{# image_url }}' +
'<img src="{{ image_url }}">' +
'{{/ image_url }}' +
'<h2>{{ instance_id }}</h2>' +
'</article>',
instancelist:
'<article>' +
'<a href="#/dashboard/instance/request" data-role="button">Create a new instance</a>' +
'<ul data-role="listview">' +
'</ul>' +
'</article>',
rowinstance:
'<a href="{{ insturl }}">' +
'{{# thumb_url }}' +
'<img src="{{ thumb_url }}">'+
'{{/ thumb_url }}' +
'{{ instance_id }}' +
'</a>',
computer:
'<article>' +
'<h2>{{ computer_id }}</h2>' +
'</article>',
allcomputer:
'<article>' +
'<ul data-role="listview">' +
'</ul>' +
'</article>',
rowcomputer:
'<a href="{{ compurl }}">' +
'{{ computer_id }}' +
'</a>',
notfound:
'<article>' +
'<center><h4>This resource could not be found</h4></center>' +
'</article>',
badrequest:
'<article>' +
'<center><h4>Something went wrong, the server receive an incorrect request</h4></center>' +
'</article>',
payment:
'<article>' +
'<center><h4>Your account is locked because of non payment/h4></center>' +
'</article>',
internalerror:
'<article>' +
'<center><h4>This resource could not be found</h4></center>' +
'</article>',
nosoftware:
'<article>' +
'<h4>The software you are looking for, named "{{ name }}", does not exist</h4>' +
'</article>',
noinstance:
'<article>' +
'<h4>The instance you are looking for, named "{{ name }}", does not exist</h4>' +
'</article>',
nocomputer:
'<article>' +
'<h4>The computer you are looking for, named "{{ name }}", does not exist</h4>' +
'</article>',
}
$.vifib.header = {
default: '<header data-role="header"><a href="#" data-icon="home" data-iconpos="notext"></a><h2>{{ title }}</h2><div id="loading" style="h"></div></header>'
}
$.vifib.footer = {
overview: '<footer data-role="footer"><div data-role="navbar"><ul><li><a href="#/library/">Library</a></li><li><a href="http://packages.python.org/slapos.core/">Documentation</a></li></ul></div></footer>'
}
$.vifib.onepanel = function (panel, data) {
var page = $('<div data-role="page"></div>')
content = $('<div data-role="content"></div>')
.append(Mustache.render(panel, data));
page.append(content);
return $(page);
}
$.vifib.twopanel = function (panels, data) {
var page = $('<div data-role="page"></div>')
.append($.vifib.makecontent(panels, data));
return $(page);
}
$.vifib.threepanel = function (panels, data) {
var page = $('<div data-role="page"></div>')
.append($.vifib.makecontent(panels, data));
return $(page);
}
$.vifib.replacepanel = function (context, panel, data) {
context.html(Mustache.render(panel, data)).trigger('pagecreate');
}
$.vifib.makecontent = function (panels, data) {
var i = 0,
pandata,
gridname = {
2: 'ui-grid-a',
3: 'ui-grid-b',
4: 'ui-grid-c',
5: 'ui-grid-d',
},
divcontent = $('<div data-role="content" class="' + gridname[panels.length] + '"></div>');
for (i; i < panels.length; i ++) {
pandata = data === undefined ? undefined : data[i];
divcontent.append($.vifib.makepanel(panels[i], pandata, i));
}
return divcontent;
}
$.vifib.makepanel = function (panel, data, index) {
var blockname = [
'ui-block-a',
'ui-block-b',
'ui-block-c',
'ui-block-d',
'ui-block-e',
],
divpane = $('<div class="' + blockname[index] + '">')
.append('<section id="panel-' + index + '">' + Mustache.render(panel, data) + '</section>');
return divpane;
}
$.vifib.changepage = function (page) {
$('[id^=panel]').remove();
$('#slider').remove();
$('#loading').remove();
$('body').append($(page));
$.mobile.changePage($(page), {
changeHash: false,
transition: $.mobile.defaultPageTransition
});
}
/*global window, jQuery */
/*!
* route.js v1.0.0
*
* Copyright 2012, Romain Courteaud
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Date: Mon Jul 16 2012
*/
"use strict";
(function (window, $) {
$.extend({
StatelessDeferred: function () {
var doneList = $.Callbacks("memory"),
promise = {
done: doneList.add,
// Get a promise for this deferred
// If obj is provided, the promise aspect is added to the object
promise: function (obj) {
var i,
keys = ['done', 'promise'];
if (obj === undefined) {
obj = promise;
} else {
for (i = 0; i < keys.length; i += 1) {
obj[keys[i]] = promise[keys[i]];
}
}
return obj;
}
},
deferred = promise.promise({});
deferred.resolveWith = doneList.fireWith;
// All done!
return deferred;
}
});
var routes = [],
current_priority = 0,
methods = {
add: function (pattern, priority) {
var i = 0,
inserted = false,
length = routes.length,
dfr = $.StatelessDeferred(),
context = $(this),
escapepattern,
matchingpattern;
if (priority === undefined) {
priority = 0;
}
if (pattern !== undefined) {
// http://simonwillison.net/2006/Jan/20/escape/
escapepattern = pattern.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
matchingpattern = escapepattern
.replace(/<int:\w+>/g, "(\\d+)")
.replace(/<path:\w+>/g, "(.+)")
.replace(/<\w+>/g, "([^/]+)");
while (!inserted) {
if ((i === length) || (priority >= routes[i][2])) {
routes.splice(i, 0, [new RegExp('^' + matchingpattern + '$'), dfr, priority, context]);
inserted = true;
} else {
i += 1;
}
}
}
return dfr.promise();
},
go: function (path, min_priority) {
var dfr = $.Deferred(),
context = $(this),
result;
if (min_priority === undefined) {
min_priority = 0;
}
setTimeout(function () {
var i = 0,
found = false,
slice_index = -1,
slice_priority = -1;
for (i = 0; i < routes.length; i += 1) {
if (slice_priority !== routes[i][2]) {
slice_priority = routes[i][2];
slice_index = i;
}
if (routes[i][2] < min_priority) {
break;
} else if (routes[i][0].test(path)) {
result = routes[i][0].exec(path);
dfr = routes[i][1];
context = routes[i][3];
current_priority = routes[i][2];
found = true;
break;
}
}
if (i === routes.length) {
slice_index = i;
}
if (slice_index > -1) {
routes = routes.slice(slice_index);
}
if (found) {
dfr.resolveWith(
context,
result.slice(1)
);
} else {
dfr.rejectWith(context);
}
});
return dfr.promise();
},
};
$.routereset = function () {
routes = [];
current_priority = 0;
};
$.routepriority = function () {
return current_priority;
};
$.fn.route = function (method) {
var result;
if (methods.hasOwnProperty(method)) {
result = methods[method].apply(
this,
Array.prototype.slice.call(arguments, 1)
);
} else {
$.error('Method ' + method +
' does not exist on jQuery.route');
}
return result;
};
}(window, jQuery));
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery Slapos Test Suite</title>
<!-- Load local jQuery, removing access to $ (use jQuery, not $). -->
<script src="../lib/jquery.js"></script>
<script>jQuery.noConflict()</script>
<!-- Load local Modernizr -->
<script type="text/javascript" src="../lib/modernizr.js"></script>
<!-- Load local QUnit (grunt requires v1.0.0 or newer). -->
<link rel="stylesheet" href="../lib/qunit.css" media="screen">
<script src="../lib/qunit.js"></script>
<!-- Load local SinonJs -->
<script type="text/javascript" src="../lib/sinon.js"></script>
<!--<script type="text/javascript" src="../lib/sinon-qunit-1.0.0.js"></script>-->
<!-- Load local lib and tests. -->
<script src="../js/jquery.slapos.js"></script>
<script src="../tests/jquery.slapos_test.js"></script>
</head>
<body>
<h1 id="qunit-header">jQuery Slapos Test Suite</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">
<span>lame test markup</span>
<span>normal test markup</span>
<span>awesome test markup</span>
</div>
</body>
</html>
jQuery(function(){
var response, responseBody, url, data;
module("Cross-domain Tests");
//test("200 response", function(){
//expect(1);
//stop(1);
//jQuery.ajax({
//url: 'http://sheldy.com:5000/200',
//complete: function() { start(); },
//statusCode: {
//200: function(){ ok(true, "should get 200 status");}
//}
//});
//});
//test("404 response", function(){
//expect(1);
//stop(1);
//jQuery.ajax({
//url: 'http://sheldy.com:5000/request',
//complete: function() { start(); },
//statusCode: {
//404: function(xhr){
//ok(true, "should get 404 error status status="+xhr.status);
//},
//0: function(){
//ok(false, "should get 404 not but receive 0");
//}
//}});
//});
module("Storage Test", {
setup: function() {
this.myhost = 'http://www.example.com/api';
jQuery(document).slapos({'host': this.myhost});
}
});
test("", function() {
expect(5);
var test = "testValue",
newToken = "newToken",
nnToken = "";
equal(this.myhost, jQuery(document).slapos('host'), "should contain the same host when initialized");
jQuery(document).slapos('store', 'test', test);
equal(test, window.localStorage.test, 'should add new key "test" in local storage');
jQuery(document).slapos('access_token', newToken);
equal(newToken, window.localStorage.access_token, 'should add new key "access_token" by using its shortcut method');
nnToken = jQuery(document).slapos('access_token');
equal(nnToken, newToken, 'should put "newToken" value in nnToken')
jQuery(document).slapos('deleteStore', 'access_token');
ok(window.localStorage.getItem('access_token') === null, 'should delete "access_token" from localStorage');
});
module("Callback Tests", {
setup: function(){
this.server = sinon.sandbox.useFakeServer();
this.header = {"Content-Type":"application/json"};
// Discovery response
var discoBody = {
"request_instance": {
"authentication": true,
"url": "/request_instance",
"method": "POST",
"required": {
"status": "unicode",
"slave": "bool",
"title": "unicode",
"software_release": "unicode",
"software_type": "unicode",
"parameter": "object",
"sla": "object"
},
"optional": {}
}
};
var discoResponse = [200, this.header, JSON.stringify(discoBody)];
this.server.respondWith("GET", '/api', discoResponse);
// Error responses
this.bad_request = [400, this.header, 'Bad Request'];
this.unauthorized = [401, this.header, 'Unauthorized'];
this.payment = [402, this.header, 'Payment required'];
this.not_found = [404, this.header, 'Not found'];
this.server_error = [500, this.header, 'Internal server error'];
jQuery(document).slapos({'host': '/api'});
},
teardown: function(){
this.server.restore();
}
});
test("Bad request", function(){
expect(1);
this.server.respondWith("POST", "/request_instance", this.bad_request);
var callback = function(){
ok(true, "should use 400 callback");
},
statusCode = {
400: callback
};
var i = jQuery(document).slapos('instanceRequest', {
url: "/request_instance",
statusCode: statusCode,
complete: function () { start() }
});
this.server.respond();
});
test("Unauthorized", function(){
expect(1);
this.server.respondWith("POST", "/request_instance", this.unauthorized);
var callback = function(){
ok(true, "should use 401 callback");
},
statusCode = {
401: callback
};
jQuery(document).slapos('instanceRequest', {
url: "/request_instance",
statusCode: statusCode,
complete: function () { start() }
});
this.server.respond();
});
test("Payment required", function(){
expect(1);
this.server.respondWith("POST", "/request_instance", this.payment);
var callback = function(){
ok(true, "should use 402 callback");
},
statusCode = {
402: callback
};
jQuery(document).slapos('instanceRequest', {
url: "/request_instance",
statusCode: statusCode,
complete: function () { start() }
});
this.server.respond();
});
test("Not found", function(){
expect(1);
this.server.respondWith("POST", "/request_instance", this.not_found);
var callback = function(){
ok(true, "should use 404 callback");
},
statusCode = {
404: callback
};
jQuery(document).slapos('instanceRequest', {
url: "/request_instance",
statusCode: statusCode,
complete: function () { start() }
});
this.server.respond();
});
test("Internal server error", function(){
expect(1);
this.server.respondWith("POST", "/request_instance", this.server_error);
var callback = function(){
ok(true, "should use 500 callback");
},
statusCode = {
500: callback
};
jQuery(document).slapos('instanceRequest', {
url: "/request_instance",
statusCode: statusCode,
complete: function () { start() }
});
this.server.respond();
});
});
/**
* Wait until the test condition is true or a timeout occurs. Useful for waiting
* on a server response or for a ui change (fadeIn, etc.) to occur.
*
* @param testFx javascript condition that evaluates to a boolean,
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
* as a callback function.
* @param onReady what to do when testFx condition is fulfilled,
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
* as a callback function.
* @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
*/
function waitFor(testFx, onReady, timeOutMillis) {
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3001, //< Default Max Timout is 3s
start = new Date().getTime(),
condition = false,
interval = setInterval(function() {
if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
// If not time-out yet and condition not yet fulfilled
condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
} else {
if(!condition) {
// If condition still not fulfilled (timeout but condition is 'false')
console.log("'waitFor()' timeout");
phantom.exit(1);
} else {
// Condition fulfilled (timeout and/or condition is 'true')
console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
clearInterval(interval); //< Stop this interval
}
}
}, 100); //< repeat check every 250ms
};
if (phantom.args.length === 0 || phantom.args.length > 2) {
console.log('Usage: run-qunit.js URL');
phantom.exit();
}
var page = new WebPage();
// Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this")
page.onConsoleMessage = function(msg) {
console.log(msg);
};
page.open(phantom.args[0], function(status){
if (status !== "success") {
console.log("Unable to access network");
phantom.exit();
} else {
waitFor(function(){
return page.evaluate(function(){
var el = document.getElementById('qunit-testresult');
if (el && el.innerText.match('completed')) {
return true;
}
return false;
});
}, function(){
var failedNum = page.evaluate(function(){
var el = document.getElementById('qunit-testresult');
console.log(el.innerText);
try {
return el.getElementsByClassName('failed')[0].innerHTML;
} catch (e) { }
return 10000;
});
phantom.exit((parseInt(failedNum, 10) > 0) ? 1 : 0);
});
}
});
/*global window, jQuery */
/*!
* url.js v1.0.0
*
* Copyright 2012, Romain Courteaud
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Date: Mon Jul 16 2012
*/
"use strict";
(function (window, $) {
var hashchangeinitialized = false,
previousurl,
currentcallback,
getRawHash = function () {
return window.location.toString().split('#')[1];
},
callbackwrapper = function () {
if (previousurl !== window.location.hash) {
previousurl = window.location.hash;
if (currentcallback !== undefined) {
currentcallback();
}
}
},
timeoutwrapper = function () {
callbackwrapper();
window.setTimeout(timeoutwrapper, 500);
};
function UrlHandler() {}
UrlHandler.prototype = {
'generateUrl': function (path, options) {
var pathhash,
hash = '#',
key;
if (path !== undefined) {
hash += encodeURIComponent(path);
}
hash = hash.replace(/%2F/g, '/');
pathhash = hash;
for (key in options) {
if (options.hasOwnProperty(key)) {
if (hash === pathhash) {
hash = hash + '?';
} else {
hash = hash + '&';
}
hash += encodeURIComponent(key) +
'=' + encodeURIComponent(options[key]);
}
}
return hash;
},
'go': function (path, options) {
window.location.hash = this.generateUrl(path, options);
},
'redirect': function (path, options) {
var host = window.location.protocol + '//' +
window.location.host +
window.location.pathname +
window.location.search;
window.location.replace(host + this.generateUrl(path, options));
// window.location.replace(window.location.href.replace(/#.*/, ""));
},
'getPath': function () {
var hash = getRawHash(),
result = '';
if (hash !== undefined) {
result = decodeURIComponent(hash.split('?')[0]);
}
return result;
},
'getOptions': function () {
var options = {},
hash = getRawHash(),
subhashes,
subhash,
index,
keyvalue;
if (hash !== undefined) {
hash = hash.split('?')[1];
if (hash !== undefined) {
subhashes = hash.split('&');
for (index in subhashes) {
if (subhashes.hasOwnProperty(index)) {
subhash = subhashes[index];
if (subhash !== '') {
keyvalue = subhash.split('=');
if (keyvalue.length === 2) {
options[decodeURIComponent(keyvalue[0])] =
decodeURIComponent(keyvalue[1]);
}
}
}
}
}
}
return options;
},
'onhashchange': function (callback) {
previousurl = undefined;
currentcallback = callback;
if (!hashchangeinitialized) {
if (window.onhashchange !== undefined) {
$(window).bind('hashchange', callbackwrapper);
window.setTimeout(callbackwrapper);
} else {
timeoutwrapper();
}
hashchangeinitialized = true;
}
},
};
// Expose to the global object
$.url = new UrlHandler();
}(window, jQuery));
var comp = {
computer_id: "COMP-0",
software: [{software_release: "http://example.com/example.cfg",status: "install"}],
partition: [
{title: "slapart1",
instance_id: "foo",
status: "start",
software_release: "http://example.com/example.cfg"},
{title: "slapart2",
instance_id: "bar",
status: "stop",
software_release: "http://example.com/example.cfg"}
]
};
var inst ={
instance_id: "INST-1",
status: "stop_requested",
software_release: "http://example.com/example.cfg",
software_type: "type_provided_by_the_software",
slave: "False",
connection: [{
key: "foo",
key: "bar"}],
parameter: {
Custom1: "one string",
Custom2: "one float",
Custom3: ["abc", "def"]},
sla: {computer_id: "COMP-0"},
children_id_list: ["subinstance1", "subinstance2"],
partition: {
public_ip: ["::1", "91.121.63.94"],
private_ip: ["127.0.0.1"],
tap_interface: "tap2"}
};
var soft = {
name: 'Kvm',
image_url: 'http://www.linux-kvm.org/wiki/skins/kvm/kvmbanner-logo2.png',
thumb_url: 'http://www.system-linux.eu/public/images/kvm-logo.png',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae metus a est convallis pretium. Pellentesque habitant morbi tristique senectus.',
price: '1',
};
var html5 = {
name: 'Html5 AS',
image_url: 'http://7.mshcdn.com/wp-content/uploads/2011/01/html5-logo-1.jpg',
thumb_url: 'http://www.w3.org/html/logo/downloads/HTML5_Badge_512.png',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae metus a est convallis pretium. Pellentesque habitant morbi tristique senectus.',
price: '1337',
};
var software_list = {
list: [
'/fake/software_info/kvm',
'/fake/software_info/html5',
]
};
var instance_list = {
list: [
'/fake/instance_info/kvm'
]
};
var computer_list = {
list: [
'/fake/computer_info/comp'
]
};
var fakeserver = sinon.fakeServer.create();
// Get instances list
fakeserver.respondWith('GET', '/fake/instance', [
200, {'Content-Type': 'application/json'}, JSON.stringify(instance_list)
]);
// Get instance info
fakeserver.respondWith("GET", '/fake/instance_info/kvm', [
200, {"Content-Type":"application/json; charset=utf-8"}, JSON.stringify(inst)
]);
// Get softwares list
fakeserver.respondWith('GET', '/fake/software', [
200, {'Content-Type': 'application/json'}, JSON.stringify(software_list)
]);
// Get software info
fakeserver.respondWith('GET', '/fake/software_info/kvm', [
200, {'Content-Type': 'application/json'}, JSON.stringify(soft)
]);
fakeserver.respondWith('GET', '/fake/software_info/html5', [
200, {'Content-Type': 'application/json'}, JSON.stringify(html5)
]);
fakeserver.respondWith('GET', '/fake/software_info/nas', [
404, {'Content-Type': 'application/json'}, ''
]);
// Get computers list
fakeserver.respondWith('GET', '/fake/computer', [
200, {'Content-Type': 'application/json'}, JSON.stringify(computer_list)
]);
// Get computer info
fakeserver.respondWith('GET', '/fake/computer_info/comp', [
200, {'Content-Type': 'application/json'}, JSON.stringify(comp)
]);
var tmp = $.ajax;
$.ajax = function(url, options){
// it will not work with cache set to false
if (url.hasOwnProperty('cache')) { url.cache = true; }
var result = tmp(url, options);
fakeserver.respond();
return result;
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment