leonardojs
Advanced tools
Comparing version 1.0.8 to 1.0.9
@@ -78,2 +78,7 @@ angular.module('leonardo', ['leonardo.templates', 'ngMockE2E']) | ||
// Common.js package manager support (e.g. ComponentJS, WebPack) | ||
if (typeof module !== "undefined" && typeof exports !== "undefined" && module.exports === exports) { | ||
module.exports = 'leonardo'; | ||
} | ||
angular.module('leonardo').provider('$leonardo', function LeonardoProvider() { | ||
@@ -101,29 +106,29 @@ var pref = ''; | ||
_requestsLog = [], | ||
_savedStates = [], | ||
// Core API | ||
// ---------------- | ||
api = { | ||
// Add a new state which you wish to mock - there a two types of states - one with url and one without. | ||
addState: addState, | ||
addStates: addStates, | ||
getState: getState, | ||
getStates: fetchStates, | ||
deactivateState: deactivateState, | ||
deactivateAllStates: deactivateAll, | ||
activateStateOption: activateStateOption, | ||
addScenario: addScenario, | ||
addScenarios: addScenarios, | ||
getScenario: getScenario, | ||
getScenarios: getScenarios, | ||
setActiveScenario: setActiveScenario, | ||
getRecordedStates: getRecordedStates, | ||
getRequestsLog: getRequestsLog, | ||
loadSavedStates: loadSavedStates, | ||
addSavedState: addSavedState, | ||
//Private api for passing through unregistered urls to $htto | ||
_requestSubmitted: requestSubmitted, | ||
_logRequest: logRequest | ||
}; | ||
return api; | ||
_savedStates = []; | ||
// Core API | ||
// ---------------- | ||
return { | ||
// Add a new state which you wish to mock - there a two types of states - one with url and one without. | ||
addState: addState, | ||
addStates: addStates, | ||
getState: getState, | ||
getStates: fetchStates, | ||
deactivateState: deactivateState, | ||
deactivateAllStates: deactivateAll, | ||
activateStateOption: activateStateOption, | ||
addScenario: addScenario, | ||
addScenarios: addScenarios, | ||
getScenario: getScenario, | ||
getScenarios: getScenarios, | ||
setActiveScenario: setActiveScenario, | ||
getRecordedStates: getRecordedStates, | ||
getRequestsLog: getRequestsLog, | ||
loadSavedStates: loadSavedStates, | ||
addSavedState: addSavedState, | ||
//Private api for passing through unregistered urls to $http | ||
_requestSubmitted: requestSubmitted, | ||
_logRequest: logRequest | ||
}; | ||
function upsertOption(state, name, active) { | ||
@@ -141,6 +146,6 @@ var _states = leoStorage.getStates(); | ||
function fetchStatesByUrl(url){ | ||
return fetchStates().filter(function(state){ | ||
return state.url === url; | ||
}); | ||
function fetchStatesByUrl(url, method){ | ||
return fetchStates().filter(function(state){ | ||
return state.url && new RegExp(state.url).test(url) && state.verb.toLowerCase() === method.toLowerCase(); | ||
}); | ||
} | ||
@@ -180,4 +185,4 @@ | ||
function sync(){ | ||
fetchStates().forEach(function (state, i) { | ||
function sync() { | ||
fetchStates().forEach(function (state) { | ||
var option, responseHandler; | ||
@@ -189,3 +194,2 @@ if (state.url) { | ||
responseHandler.respond(function () { | ||
console.log(i); | ||
$httpBackend.setDelay(option.delay); | ||
@@ -245,3 +249,3 @@ return [option.status, angular.isFunction(option.data) ? option.data() : option.data]; | ||
} else { | ||
console.warn('addStates should get an array'); | ||
console.warn('leonardo: addStates should get an array'); | ||
} | ||
@@ -263,3 +267,3 @@ } | ||
if (!state) { | ||
console.log("cannot upsert - state is mandatory"); | ||
console.log("leonardo: cannot upsert - state is mandatory"); | ||
return; | ||
@@ -297,8 +301,2 @@ } | ||
function upsertMany(items){ | ||
items.forEach(function(item) { | ||
upsert(item); | ||
}); | ||
} | ||
function addScenario(scenario){ | ||
@@ -308,3 +306,3 @@ if (scenario && typeof scenario.name === 'string') { | ||
} else { | ||
throw 'addScnerio method expects a scenario object with name property'; | ||
throw 'addScenario method expects a scenario object with name property'; | ||
} | ||
@@ -322,7 +320,5 @@ } | ||
function getScenario(name){ | ||
console.log(name); | ||
if (!_scenarios[name]) { | ||
return; | ||
} | ||
console.log('return scenario', _scenarios[name].states); | ||
return _scenarios[name].states; | ||
@@ -332,4 +328,9 @@ } | ||
function setActiveScenario(name){ | ||
var scenario = getScenario(name); | ||
if (!scenario) { | ||
console.warn("leonardo: could not find scenario named " + name); | ||
return; | ||
} | ||
deactivateAll(); | ||
getScenario(name).forEach(function(state){ | ||
scenario.forEach(function(state){ | ||
upsertOption(state.name, state.option, true); | ||
@@ -348,6 +349,9 @@ }); | ||
function requestSubmitted(requestConfig){ | ||
var state = fetchStatesByUrl(requestConfig.url)[0]; | ||
var url = requestConfig.url; | ||
var method = requestConfig.method; | ||
var state = fetchStatesByUrl(url, method)[0]; | ||
var handler = getResponseHandler(state || { | ||
url: requestConfig.url, | ||
verb: requestConfig.method | ||
url: url, | ||
verb: method | ||
}); | ||
@@ -368,3 +372,3 @@ if (!state) { | ||
}; | ||
req.state = getStateByRequest(req); | ||
req.state = fetchStatesByUrl(req.url, req.verb)[0]; | ||
_requestsLog.push(req); | ||
@@ -374,9 +378,2 @@ } | ||
function getStateByRequest(req) { | ||
return fetchStates().filter(function(state) { | ||
if (!state.url) return false; | ||
return state.url === req.url && state.verb.toLowerCase() === req.verb.toLowerCase(); | ||
})[0]; | ||
} | ||
function getRequestsLog() { | ||
@@ -400,3 +397,3 @@ return _requestsLog; | ||
.map(function(req){ | ||
var state = getStateByRequest(req); | ||
var state = fetchStatesByUrl(req.url, req.verb)[0]; | ||
return { | ||
@@ -479,10 +476,6 @@ name: state ? state.name : req.verb + " " + req.url, | ||
controllerAs: 'leonardo', | ||
controller: function () { | ||
this.activeTab = 'scenarios'; | ||
this.selectTab = function (name) { | ||
this.activeTab = name; | ||
}; | ||
}, | ||
controller: LeoActivator, | ||
bindToController: true, | ||
link: function(scope, elem) { | ||
var el = angular.element('<div ng-click="activate()" class="leonardo-activator"></div>'); | ||
var el = angular.element('<div ng-click="leonardo.activate()" class="leonardo-activator" ng-show="leonardo.isLeonardoVisible"></div>'); | ||
@@ -494,3 +487,3 @@ var win = angular.element([ | ||
'<ul>', | ||
'<li>LEONARDO</li>', | ||
'<li>LEONARDO</li>', | ||
'<li ng-class="{ \'leo-selected-tab\': leonardo.activeTab === \'scenarios\' }" ng-click="leonardo.selectTab(\'scenarios\')">Scenarios</li>', | ||
@@ -518,12 +511,2 @@ '<li ng-class="{ \'leo-selected-tab\': leonardo.activeTab === \'recorder\' }"ng-click="leonardo.selectTab(\'recorder\')">Recorder</li>', | ||
}, false ); | ||
scope.activate = function(){ | ||
if (!document.body.classList.contains('pull-top')) { | ||
document.body.classList.add('pull-top'); | ||
document.body.classList.remove('pull-top-closed'); | ||
} | ||
else { | ||
document.body.classList.remove('pull-top'); | ||
} | ||
}; | ||
} | ||
@@ -533,4 +516,29 @@ }; | ||
angular.module('leonardo').directive('leoWindowBody', | ||
['$http', 'leoConfiguration', '$timeout', function windowBodyDirective($http, leoConfiguration, $timeout) { | ||
LeoActivator.$inject = ['$scope', '$document']; | ||
function LeoActivator($scope, $document) { | ||
this.isLeonardoVisible = true; | ||
this.activeTab = 'scenarios'; | ||
this.selectTab = function (name) { | ||
this.activeTab = name; | ||
}; | ||
$document.on('keypress', function(e) { | ||
if(e.shiftKey && e.ctrlKey && e.keyCode === 12) { | ||
this.isLeonardoVisible = !this.isLeonardoVisible; | ||
$scope.$apply(); | ||
} | ||
}.bind(this)); | ||
this.activate = function() { | ||
if (!document.body.classList.contains('pull-top')) { | ||
document.body.classList.add('pull-top'); | ||
document.body.classList.remove('pull-top-closed'); | ||
} | ||
else { | ||
document.body.classList.remove('pull-top'); | ||
} | ||
}; | ||
} | ||
angular.module('leonardo').directive('leoWindowBody', ['$http', 'leoConfiguration', '$timeout', function windowBodyDirective($http, leoConfiguration, $timeout) { | ||
return { | ||
@@ -540,151 +548,159 @@ restrict: 'E', | ||
scope: true, | ||
replace: true, | ||
require: '^leoActivator', | ||
controller: ['$scope', function($scope) { | ||
$scope.detail = { | ||
option: 'success', | ||
delay: 0, | ||
status: 200 | ||
}; | ||
controller: LeoWindowBody, | ||
bindToController: true, | ||
controllerAs: 'leoWindowBody', | ||
require: ['^leoActivator', 'leoWindowBody'], | ||
link: function (scope, el, attr, controllers) { | ||
var leoActivator = controllers[0]; | ||
var leoWindowBody = controllers[1]; | ||
$scope.NothasUrl = function (option) { | ||
return !option.url; | ||
}; | ||
$scope.hasUrl = function (option) { | ||
return !!option.url; | ||
}; | ||
leoWindowBody.saveUnregisteredState = function () { | ||
var stateName = this.detail.state; | ||
$scope.deactivate = function () { | ||
$scope.states.forEach(function (state) { | ||
state.active = false; | ||
leoConfiguration.addSavedState({ | ||
name: stateName, | ||
verb: leoWindowBody.detail._unregisteredState.verb, | ||
url: leoWindowBody.detail._unregisteredState.url, | ||
options: [ | ||
{ | ||
name: leoWindowBody.detail.option, | ||
status: leoWindowBody.detail.status, | ||
data: leoWindowBody.detail.value, | ||
delay: leoWindowBody.detail.delay | ||
} | ||
] | ||
}); | ||
leoConfiguration.deactivateAllStates(); | ||
leoActivator.selectTab('scenarios'); | ||
}; | ||
$scope.updateState = function (state) { | ||
if (state.active) { | ||
console.log('activate state option:' + state.name + ': ' + state.activeOption.name); | ||
leoConfiguration.activateStateOption(state.name, state.activeOption.name); | ||
} else { | ||
console.log('deactivating state: ' + state.name); | ||
leoConfiguration.deactivateState(state.name); | ||
leoWindowBody.test = { | ||
url: '', | ||
value: undefined | ||
}; | ||
leoWindowBody.submit = function (url) { | ||
leoWindowBody.test.value = undefined; | ||
leoWindowBody.url = url; | ||
if (url) { | ||
$http.get(url).success(function (res) { | ||
leoWindowBody.test.value = res; | ||
}); | ||
} | ||
}; | ||
} | ||
}; | ||
}]); | ||
$scope.states = leoConfiguration.getStates(); | ||
LeoWindowBody.$inject = ['$scope', 'leoConfiguration', '$timeout']; | ||
function LeoWindowBody($scope, leoConfiguration, $timeout) { | ||
this.detail = { | ||
option: 'success', | ||
delay: 0, | ||
status: 200 | ||
}; | ||
$scope.scenarios = leoConfiguration.getScenarios(); | ||
this.states = leoConfiguration.getStates(); | ||
$scope.activateScenario = function (scenario) { | ||
$scope.activeScenario = scenario; | ||
leoConfiguration.setActiveScenario(scenario); | ||
$scope.states = leoConfiguration.getStates(); | ||
}; | ||
this.scenarios = leoConfiguration.getScenarios(); | ||
$scope.requests = leoConfiguration.getRequestsLog(); | ||
this.notHasUrl = function (option) { | ||
return !option.url; | ||
}; | ||
$scope.$watch('detail.value', function(value){ | ||
if (!value) { | ||
return; | ||
} | ||
try { | ||
$scope.detail.stringValue = value ? JSON.stringify(value, null, 4) : ''; | ||
$scope.detail.error = ''; | ||
} | ||
catch (e) { | ||
$scope.detail.error = e.message; | ||
} | ||
}); | ||
this.hasUrl = function (option) { | ||
return !!option.url; | ||
}; | ||
$scope.$watch('detail.stringValue', function(value){ | ||
try { | ||
$scope.detail.value = value ? JSON.parse(value) : {}; | ||
$scope.detail.error = ''; | ||
} | ||
catch(e) { | ||
$scope.detail.error = e.message; | ||
} | ||
}); | ||
this.deactivate = function () { | ||
this.states.forEach(function (state) { | ||
state.active = false; | ||
}); | ||
leoConfiguration.deactivateAllStates(); | ||
}; | ||
$scope.requestSelect = function (request) { | ||
$scope.requests.forEach(function (request) { | ||
request.active = false; | ||
}); | ||
this.updateState = function (state) { | ||
if (state.active) { | ||
console.log('leonardo: activate state option:' + state.name + ': ' + state.activeOption.name); | ||
leoConfiguration.activateStateOption(state.name, state.activeOption.name); | ||
} else { | ||
console.log('leonardo: deactivating state: ' + state.name); | ||
leoConfiguration.deactivateState(state.name); | ||
} | ||
}; | ||
request.active = true; | ||
if (request.state && request.state.name) { | ||
var optionName = request.state.name + ' option ' + request.state.options.length; | ||
} | ||
this.activateScenario = function (scenario) { | ||
this.activeScenario = scenario; | ||
leoConfiguration.setActiveScenario(scenario); | ||
this.states = leoConfiguration.getStates(); | ||
}.bind(this); | ||
angular.extend($scope.detail, { | ||
state : (request.state && request.state.name) || '', | ||
option: optionName || '', | ||
delay: 0, | ||
status: 200, | ||
stateActive: !!request.state, | ||
value: request.data || {} | ||
}); | ||
$scope.detail._unregisteredState = request; | ||
}; | ||
this.requests = leoConfiguration.getRequestsLog(); | ||
$scope.$on('leonardo:stateChanged', function(event, stateObj) { | ||
$scope.states = leoConfiguration.getStates(); | ||
$scope.$watch('leoWindowBody.detail.value', function (value) { | ||
if (!value) { | ||
return; | ||
} | ||
try { | ||
this.detail.stringValue = value ? JSON.stringify(value, null, 4) : ''; | ||
this.detail.error = ''; | ||
} | ||
catch (e) { | ||
this.detail.error = e.message; | ||
} | ||
}.bind(this)); | ||
var state = $scope.states.filter(function(state){ | ||
return state.name === stateObj.name; | ||
})[0]; | ||
$scope.$watch('leoWindowBody.detail.stringValue', function (value) { | ||
try { | ||
this.detail.value = value ? JSON.parse(value) : {}; | ||
this.detail.error = ''; | ||
} | ||
catch (e) { | ||
this.detail.error = e.message; | ||
} | ||
}.bind(this)); | ||
if (state) { | ||
state.highlight = true; | ||
$timeout(function(){ | ||
state.highlight = false; | ||
}, 3000); | ||
} | ||
}); | ||
$scope.getStatesForExport = function () { | ||
$scope.exportStates = leoConfiguration.getStates(); | ||
} | ||
}], | ||
link: function(scope, el, attr, leoActivator) { | ||
scope.saveUnregisteredState = function () { | ||
var stateName = scope.detail.state; | ||
this.requestSelect = function (request) { | ||
this.requests.forEach(function (request) { | ||
request.active = false; | ||
}); | ||
leoConfiguration.addSavedState({ | ||
name: stateName, | ||
verb: scope.detail._unregisteredState.verb, | ||
url: scope.detail._unregisteredState.url, | ||
options: [ | ||
{ | ||
name: scope.detail.option, | ||
status: scope.detail.status, | ||
data: scope.detail.value | ||
} | ||
] | ||
}); | ||
request.active = true; | ||
leoActivator.selectTab('scenarios'); | ||
}; | ||
if (request.state && request.state.name) { | ||
var optionName = request.state.name + ' option ' + request.state.options.length; | ||
} | ||
angular.extend(this.detail, { | ||
state: (request.state && request.state.name) || '', | ||
option: optionName || '', | ||
delay: 0, | ||
status: 200, | ||
stateActive: !!request.state, | ||
value: request.data || {} | ||
}); | ||
this.detail._unregisteredState = request; | ||
}.bind(this); | ||
scope.test = { | ||
url: '', | ||
value: undefined | ||
}; | ||
$scope.$on('leonardo:stateChanged', function (event, stateObj) { | ||
this.states = leoConfiguration.getStates(); | ||
scope.submit = function(url){ | ||
scope.test.value = undefined; | ||
scope.url = url; | ||
if (url) { | ||
$http.get(url).success(function (res) { | ||
scope.test.value = res; | ||
}); | ||
} | ||
}; | ||
var state = this.states.filter(function (state) { | ||
return state.name === stateObj.name; | ||
})[0]; | ||
if (state) { | ||
state.highlight = true; | ||
$timeout(function () { | ||
state.highlight = false; | ||
}, 3000); | ||
} | ||
}; | ||
}]); | ||
}.bind(this)); | ||
this.getStatesForExport = function () { | ||
this.exportStates = leoConfiguration.getStates(); | ||
} | ||
} | ||
angular.module('leonardo').directive('leoRequest', function () { | ||
@@ -698,10 +714,13 @@ return { | ||
}, | ||
controller: ['$scope', function ($scope) { | ||
$scope.select = function () { | ||
$scope.onSelect(); | ||
} | ||
}] | ||
} | ||
controllerAs: 'leoRequest', | ||
bindToController: true, | ||
controller: LeoRequest | ||
}; | ||
}); | ||
function LeoRequest() { | ||
this.select = function () { | ||
this.onSelect(); | ||
} | ||
} | ||
(function(module) { | ||
@@ -715,3 +734,3 @@ try { | ||
$templateCache.put('request.html', | ||
'<a href="#" class="leo-list-item" ng-click="select()" ng-class="{active:request.active}"><span class="leo-request-name">{{request.url}}</span> <span ng-if="!!request.state" class="leo-request leo-request-existing">{{request.state.name}}</span> <span ng-if="!request.state" class="leo-request leo-request-new">new</span> <span ng-if="!!request.state && request.state.active" class="leo-request leo-request-mocked">mocked</span></a>'); | ||
'<a href="#" class="leo-list-item" ng-click="leoRequest.select()" ng-class="{active: leoRequest.request.active}"><span class="leo-request-verb {{leoRequest.request.verb.toLowerCase()}}">{{leoRequest.request.verb}}</span> <span class="leo-request-name">{{leoRequest.request.url}}</span> <span ng-if="!!leoRequest.request.state" class="leo-request leo-request-existing">{{leoRequest.request.state.name}}</span> <span ng-if="!leoRequest.request.state" class="leo-request leo-request-new">new</span> <span ng-if="!!leoRequest.request.state && leoRequest.request.state.active" class="leo-request leo-request-mocked">mocked</span></a>'); | ||
}]); | ||
@@ -728,7 +747,7 @@ })(); | ||
$templateCache.put('window-body.html', | ||
'<div class="leonardo-window-body"><div ng-switch="leonardo.activeTab" class="leonardo-window-options"><div ng-switch-when="configure" class="leonardo-configure"><table><thead><tr><th>State</th><th>URL</th><th>Options</th></tr></thead><tbody><tr ng-repeat="state in states"><td>{{state.name}}</td><td>{{state.url}}</td><td><ul><li ng-repeat="option in state.options">Name: {{option.name}}<br>Status: {{option.status}}<br>Data: {{option.data}}<br></li></ul></td></tr></tbody></table></div><div ng-switch-when="recorder" class="leonardo-recorder"><div class="leo-list"><div class="list-group"><leo-request ng-repeat="request in requests" request="request" on-select="requestSelect(request)"></leo-request></div></div><div class="leo-detail"><div class="leo-detail-header"><div ng-if="!detail.stateActive"><span>Add new state:</span> <input class="leo-detail-state" ng-model="detail.state" placeholder="Enter state name"></div><div ng-if="detail.stateActive" class="leo-detail-state">Add mocked response for "{{detail.state}}"</div></div><div class="leo-detail-option"><div>Response name: <input ng-model="detail.option"></div><div>Status code: <input ng-model="detail.status"></div><div>Delay: <input ng-model="detail.delay"></div><div class="leo-detail-option-json">Response JSON:<div class="leo-error">{{detail.error}}</div><textarea ng-model="detail.stringValue"></textarea></div></div><div class="leo-action-row"><button ng-click="saveUnregisteredState()">{{ detail.stateActive ? \'Add Option\' : \'Add State\' }}</button></div></div></div><div ng-switch-when="export" class="leonardo-export" style="padding: 30px"><code contenteditable="" ng-init="getStatesForExport()">\n' + | ||
'<div class="leonardo-window-body"><div ng-switch="leonardo.activeTab" class="leonardo-window-options"><div ng-switch-when="configure" class="leonardo-configure"><table><thead><tr><th>State</th><th>URL</th><th>Options</th></tr></thead><tbody><tr ng-repeat="state in leoWindowBody.states"><td>{{state.name}}</td><td>{{state.url}}</td><td><ul><li ng-repeat="option in state.options">Name: {{option.name}}<br>Status: {{option.status}}<br>Data: {{option.data}}<br></li></ul></td></tr></tbody></table></div><div ng-switch-when="recorder" class="leonardo-recorder"><div class="leo-list"><div class="list-group"><leo-request ng-repeat="request in leoWindowBody.requests" request="request" on-select="leoWindowBody.requestSelect(request)"></leo-request></div></div><div class="leo-detail"><div class="leo-detail-header"><div ng-if="!leoWindowBody.detail.stateActive"><span>Add new state:</span> <input class="leo-detail-state" ng-model="leoWindowBody.detail.state" placeholder="Enter state name"></div><div ng-if="leoWindowBody.detail.stateActive" class="leo-detail-state">Add mocked response for "{{leoWindowBody.detail.state}}"</div></div><div class="leo-detail-option"><div>Response name: <input ng-model="leoWindowBody.detail.option"></div><div>Status code: <input ng-model="leoWindowBody.detail.status"></div><div>Delay: <input ng-model="leoWindowBody.detail.delay"></div><div class="leo-detail-option-json">Response JSON:<div class="leo-error">{{leoWindowBody.detail.error}}</div><textarea ng-model="leoWindowBody.detail.stringValue"></textarea></div></div><div class="leo-action-row"><button ng-click="leoWindowBody.saveUnregisteredState()">{{ leoWindowBody.detail.stateActive ? \'Add Option\' : \'Add State\' }}</button></div></div></div><div ng-switch-when="export" class="leonardo-export" style="padding: 30px"><code contenteditable="" ng-init="leoWindowBody.getStatesForExport()">\n' + | ||
'\n' + | ||
' <div>angular.module(\'leonardo\').run([\'leoConfiguration\', function(leoConfiguration) {</div>\n' + | ||
'\n' + | ||
' <div ng-repeat="state in exportStates">\n' + | ||
' <div ng-repeat="state in leoWindowBody.exportStates">\n' + | ||
' <div style="margin-left: 10px">leoConfiguration.addStates([</div>\n' + | ||
@@ -739,6 +758,6 @@ ' <pre style="margin-left: 20px">{{state | json}}</pre>\n' + | ||
'\n' + | ||
' <div>])</div>\n' + | ||
' <div>}])</div>\n' + | ||
'\n' + | ||
' </code></div><div ng-switch-when="scenarios" class="leonardo-activate"><div class="leonardo-menu"><div>SCENARIOS</div><ul><li ng-class="{ \'selected\': scenario === activeScenario }" ng-repeat="scenario in scenarios" ng-click="activateScenario(scenario)">{{scenario}}</li></ul></div><ul><li class="leo-non-ajax"><h3>Non Ajax States</h3></li><li ng-repeat="state in states | filter:NothasUrl"><div><div class="onoffswitch"><input ng-model="state.active" ng-click="updateState(state)" class="onoffswitch-checkbox" id="{{state.name}}" type="checkbox" name="{{state.name}}" value="{{state.name}}"> <label class="onoffswitch-label" for="{{state.name}}"><span class="onoffswitch-inner"></span> <span class="onoffswitch-switch"></span></label></div></div><div><h4>{{state.name}}</h4></div><div><select ng-disabled="!state.active" ng-model="state.activeOption" ng-options="option.name for option in state.options" ng-change="updateState(state)"></select></div></li><li><h3>Ajax States</h3></li><li ng-repeat="state in states | filter:hasUrl track by $index" ng-class="{ \'leo-highlight\': state.highlight }"><div><div class="onoffswitch"><input ng-model="state.active" ng-click="updateState(state)" class="onoffswitch-checkbox" id="{{state.name}}" type="checkbox" name="{{state.name}}" value="{{state.name}}"> <label class="onoffswitch-label" for="{{state.name}}"><span class="onoffswitch-inner"></span> <span class="onoffswitch-switch"></span></label></div></div><div><h4>{{state.name}}</h4> - {{state.url}}</div><div><select ng-disabled="!state.active" ng-model="state.activeOption" ng-options="option.name for option in state.options" ng-change="updateState(state)"></select></div></li></ul></div><div ng-switch-when="test" class="leonardo-test"><div><label for="url"></label>URL: <input id="url" type="text" ng-model="test.url"> <input type="button" ng-click="submit(test.url)" value="submit"></div><textarea>{{test.value | json}}</textarea></div></div></div>'); | ||
' </code></div><div ng-switch-when="scenarios" class="leonardo-activate"><div class="leonardo-menu"><div>SCENARIOS</div><ul><li ng-class="{ \'selected\': scenario === leoWindowBody.activeScenario }" ng-repeat="scenario in leoWindowBody.scenarios" ng-click="leoWindowBody.activateScenario(scenario)">{{scenario}}</li></ul></div><ul><li class="leo-non-ajax"><h3>Non Ajax States</h3></li><li ng-repeat="state in leoWindowBody.states | filter:leoWindowBody.notHasUrl track by $index"><div><div class="onoffswitch"><input ng-model="state.active" ng-click="leoWindowBody.updateState(state)" class="onoffswitch-checkbox" id="{{state.name}}" type="checkbox" name="{{state.name}}" value="{{state.name}}"> <label class="onoffswitch-label" for="{{state.name}}"><span class="onoffswitch-inner"></span> <span class="onoffswitch-switch"></span></label></div></div><div><h4>{{state.name}}</h4></div><div><select ng-disabled="!state.active" ng-model="state.activeOption" ng-options="option.name for option in state.options" ng-change="leoWindowBody.updateState(state)"></select></div></li><li><h3>Ajax States</h3></li><li ng-repeat="state in leoWindowBody.states | filter:leoWindowBody.hasUrl track by $index" ng-class="{ \'leo-highlight\': state.highlight }"><div><div class="onoffswitch"><input ng-model="state.active" ng-click="leoWindowBody.updateState(state)" class="onoffswitch-checkbox" id="{{state.name}}" type="checkbox" name="{{state.name}}" value="{{state.name}}"> <label class="onoffswitch-label" for="{{state.name}}"><span class="onoffswitch-inner"></span> <span class="onoffswitch-switch"></span></label></div></div><div><h4>{{state.name}}</h4> - {{state.url}}</div><div><select ng-disabled="!state.active" ng-model="state.activeOption" ng-options="option.name for option in state.options" ng-change="leoWindowBody.updateState(state)"></select></div></li></ul></div><div ng-switch-when="test" class="leonardo-test"><div><label for="url"></label>URL: <input id="url" type="text" ng-model="leoWindowBody.test.url"> <input type="button" ng-click="leoWindowBody.submit(test.url)" value="submit"></div><textarea>{{leoWindowBody.test.value | json}}</textarea></div></div></div>'); | ||
}]); | ||
})(); |
{ | ||
"name": "leonardojs", | ||
"version": "1.0.8", | ||
"version": "1.0.9", | ||
"description": "Leonardo ========", | ||
"main": "index.js", | ||
"main": "dist/leonardo.js", | ||
"scripts": { | ||
@@ -7,0 +7,0 @@ "test": "test", |
@@ -10,4 +10,6 @@ ## Leonardo | ||
[Demo](http://outbrain.github.io/Leonardo/) | ||
## Examples | ||
* [Simple Demo](http://outbrain.github.io/Leonardo/) | ||
* [Full Application Example](http://outbrain.github.io/Leonardo/examples/angularIL/) | ||
@@ -48,3 +50,3 @@ ## Install | ||
//..... | ||
<script src="[bower_componenets|node_modules|other]/leonardo/leonardo.js"></script> | ||
<script src="[bower_componenets|node_modules|other]/leonardo/dist/leonardo.js"></script> | ||
</body> | ||
@@ -61,3 +63,3 @@ </html> | ||
//..... | ||
<link rel="stylesheet" media="all" href="[bower_componenets|node_modules|other]/leonardo/leonardo.min.css" /> | ||
<link rel="stylesheet" media="all" href="[bower_componenets|node_modules|other]/leonardo/dist/leonardo.min.css" /> | ||
</head> | ||
@@ -145,2 +147,5 @@ </html> | ||
## Hide/Show Leonardo icon | ||
You can hide Leonardo activator icon by clicking `ctrl` + `shift` + `l`. | ||
## Documentation | ||
@@ -147,0 +152,0 @@ http://outbrain.github.io/Leonardo/docs/configuration.srv.html |
@@ -5,10 +5,6 @@ angular.module('leonardo').directive('leoActivator', ['$compile', function activatorDirective($compile) { | ||
controllerAs: 'leonardo', | ||
controller: function () { | ||
this.activeTab = 'scenarios'; | ||
this.selectTab = function (name) { | ||
this.activeTab = name; | ||
}; | ||
}, | ||
controller: LeoActivator, | ||
bindToController: true, | ||
link: function(scope, elem) { | ||
var el = angular.element('<div ng-click="activate()" class="leonardo-activator"></div>'); | ||
var el = angular.element('<div ng-click="leonardo.activate()" class="leonardo-activator" ng-show="leonardo.isLeonardoVisible"></div>'); | ||
@@ -20,3 +16,3 @@ var win = angular.element([ | ||
'<ul>', | ||
'<li>LEONARDO</li>', | ||
'<li>LEONARDO</li>', | ||
'<li ng-class="{ \'leo-selected-tab\': leonardo.activeTab === \'scenarios\' }" ng-click="leonardo.selectTab(\'scenarios\')">Scenarios</li>', | ||
@@ -44,14 +40,31 @@ '<li ng-class="{ \'leo-selected-tab\': leonardo.activeTab === \'recorder\' }"ng-click="leonardo.selectTab(\'recorder\')">Recorder</li>', | ||
}, false ); | ||
} | ||
}; | ||
}]); | ||
scope.activate = function(){ | ||
if (!document.body.classList.contains('pull-top')) { | ||
document.body.classList.add('pull-top'); | ||
document.body.classList.remove('pull-top-closed'); | ||
} | ||
else { | ||
document.body.classList.remove('pull-top'); | ||
} | ||
}; | ||
LeoActivator.$inject = ['$scope', '$document']; | ||
function LeoActivator($scope, $document) { | ||
this.isLeonardoVisible = true; | ||
this.activeTab = 'scenarios'; | ||
this.selectTab = function (name) { | ||
this.activeTab = name; | ||
}; | ||
$document.on('keypress', function(e) { | ||
if(e.shiftKey && e.ctrlKey && e.keyCode === 12) { | ||
this.isLeonardoVisible = !this.isLeonardoVisible; | ||
$scope.$apply(); | ||
} | ||
}.bind(this)); | ||
this.activate = function() { | ||
if (!document.body.classList.contains('pull-top')) { | ||
document.body.classList.add('pull-top'); | ||
document.body.classList.remove('pull-top-closed'); | ||
} | ||
else { | ||
document.body.classList.remove('pull-top'); | ||
} | ||
}; | ||
}]); | ||
} |
@@ -7,29 +7,29 @@ angular.module('leonardo').factory('leoConfiguration', | ||
_requestsLog = [], | ||
_savedStates = [], | ||
// Core API | ||
// ---------------- | ||
api = { | ||
// Add a new state which you wish to mock - there a two types of states - one with url and one without. | ||
addState: addState, | ||
addStates: addStates, | ||
getState: getState, | ||
getStates: fetchStates, | ||
deactivateState: deactivateState, | ||
deactivateAllStates: deactivateAll, | ||
activateStateOption: activateStateOption, | ||
addScenario: addScenario, | ||
addScenarios: addScenarios, | ||
getScenario: getScenario, | ||
getScenarios: getScenarios, | ||
setActiveScenario: setActiveScenario, | ||
getRecordedStates: getRecordedStates, | ||
getRequestsLog: getRequestsLog, | ||
loadSavedStates: loadSavedStates, | ||
addSavedState: addSavedState, | ||
//Private api for passing through unregistered urls to $htto | ||
_requestSubmitted: requestSubmitted, | ||
_logRequest: logRequest | ||
}; | ||
return api; | ||
_savedStates = []; | ||
// Core API | ||
// ---------------- | ||
return { | ||
// Add a new state which you wish to mock - there a two types of states - one with url and one without. | ||
addState: addState, | ||
addStates: addStates, | ||
getState: getState, | ||
getStates: fetchStates, | ||
deactivateState: deactivateState, | ||
deactivateAllStates: deactivateAll, | ||
activateStateOption: activateStateOption, | ||
addScenario: addScenario, | ||
addScenarios: addScenarios, | ||
getScenario: getScenario, | ||
getScenarios: getScenarios, | ||
setActiveScenario: setActiveScenario, | ||
getRecordedStates: getRecordedStates, | ||
getRequestsLog: getRequestsLog, | ||
loadSavedStates: loadSavedStates, | ||
addSavedState: addSavedState, | ||
//Private api for passing through unregistered urls to $http | ||
_requestSubmitted: requestSubmitted, | ||
_logRequest: logRequest | ||
}; | ||
function upsertOption(state, name, active) { | ||
@@ -47,6 +47,6 @@ var _states = leoStorage.getStates(); | ||
function fetchStatesByUrl(url){ | ||
return fetchStates().filter(function(state){ | ||
return state.url === url; | ||
}); | ||
function fetchStatesByUrl(url, method){ | ||
return fetchStates().filter(function(state){ | ||
return state.url && new RegExp(state.url).test(url) && state.verb.toLowerCase() === method.toLowerCase(); | ||
}); | ||
} | ||
@@ -86,4 +86,4 @@ | ||
function sync(){ | ||
fetchStates().forEach(function (state, i) { | ||
function sync() { | ||
fetchStates().forEach(function (state) { | ||
var option, responseHandler; | ||
@@ -95,3 +95,2 @@ if (state.url) { | ||
responseHandler.respond(function () { | ||
console.log(i); | ||
$httpBackend.setDelay(option.delay); | ||
@@ -151,3 +150,3 @@ return [option.status, angular.isFunction(option.data) ? option.data() : option.data]; | ||
} else { | ||
console.warn('addStates should get an array'); | ||
console.warn('leonardo: addStates should get an array'); | ||
} | ||
@@ -169,3 +168,3 @@ } | ||
if (!state) { | ||
console.log("cannot upsert - state is mandatory"); | ||
console.log("leonardo: cannot upsert - state is mandatory"); | ||
return; | ||
@@ -203,8 +202,2 @@ } | ||
function upsertMany(items){ | ||
items.forEach(function(item) { | ||
upsert(item); | ||
}); | ||
} | ||
function addScenario(scenario){ | ||
@@ -214,3 +207,3 @@ if (scenario && typeof scenario.name === 'string') { | ||
} else { | ||
throw 'addScnerio method expects a scenario object with name property'; | ||
throw 'addScenario method expects a scenario object with name property'; | ||
} | ||
@@ -228,7 +221,5 @@ } | ||
function getScenario(name){ | ||
console.log(name); | ||
if (!_scenarios[name]) { | ||
return; | ||
} | ||
console.log('return scenario', _scenarios[name].states); | ||
return _scenarios[name].states; | ||
@@ -238,4 +229,9 @@ } | ||
function setActiveScenario(name){ | ||
var scenario = getScenario(name); | ||
if (!scenario) { | ||
console.warn("leonardo: could not find scenario named " + name); | ||
return; | ||
} | ||
deactivateAll(); | ||
getScenario(name).forEach(function(state){ | ||
scenario.forEach(function(state){ | ||
upsertOption(state.name, state.option, true); | ||
@@ -254,6 +250,9 @@ }); | ||
function requestSubmitted(requestConfig){ | ||
var state = fetchStatesByUrl(requestConfig.url)[0]; | ||
var url = requestConfig.url; | ||
var method = requestConfig.method; | ||
var state = fetchStatesByUrl(url, method)[0]; | ||
var handler = getResponseHandler(state || { | ||
url: requestConfig.url, | ||
verb: requestConfig.method | ||
url: url, | ||
verb: method | ||
}); | ||
@@ -274,3 +273,3 @@ if (!state) { | ||
}; | ||
req.state = getStateByRequest(req); | ||
req.state = fetchStatesByUrl(req.url, req.verb)[0]; | ||
_requestsLog.push(req); | ||
@@ -280,9 +279,2 @@ } | ||
function getStateByRequest(req) { | ||
return fetchStates().filter(function(state) { | ||
if (!state.url) return false; | ||
return state.url === req.url && state.verb.toLowerCase() === req.verb.toLowerCase(); | ||
})[0]; | ||
} | ||
function getRequestsLog() { | ||
@@ -306,3 +298,3 @@ return _requestsLog; | ||
.map(function(req){ | ||
var state = getStateByRequest(req); | ||
var state = fetchStatesByUrl(req.url, req.verb)[0]; | ||
return { | ||
@@ -309,0 +301,0 @@ name: state ? state.name : req.verb + " " + req.url, |
@@ -77,1 +77,6 @@ angular.module('leonardo', ['leonardo.templates', 'ngMockE2E']) | ||
}]); | ||
// Common.js package manager support (e.g. ComponentJS, WebPack) | ||
if (typeof module !== "undefined" && typeof exports !== "undefined" && module.exports === exports) { | ||
module.exports = 'leonardo'; | ||
} |
@@ -9,8 +9,12 @@ angular.module('leonardo').directive('leoRequest', function () { | ||
}, | ||
controller: ['$scope', function ($scope) { | ||
$scope.select = function () { | ||
$scope.onSelect(); | ||
} | ||
}] | ||
controllerAs: 'leoRequest', | ||
bindToController: true, | ||
controller: LeoRequest | ||
}; | ||
}); | ||
function LeoRequest() { | ||
this.select = function () { | ||
this.onSelect(); | ||
} | ||
}); | ||
} |
@@ -1,3 +0,2 @@ | ||
angular.module('leonardo').directive('leoWindowBody', | ||
['$http', 'leoConfiguration', '$timeout', function windowBodyDirective($http, leoConfiguration, $timeout) { | ||
angular.module('leonardo').directive('leoWindowBody', ['$http', 'leoConfiguration', '$timeout', function windowBodyDirective($http, leoConfiguration, $timeout) { | ||
return { | ||
@@ -7,149 +6,157 @@ restrict: 'E', | ||
scope: true, | ||
replace: true, | ||
require: '^leoActivator', | ||
controller: ['$scope', function($scope) { | ||
$scope.detail = { | ||
option: 'success', | ||
delay: 0, | ||
status: 200 | ||
}; | ||
controller: LeoWindowBody, | ||
bindToController: true, | ||
controllerAs: 'leoWindowBody', | ||
require: ['^leoActivator', 'leoWindowBody'], | ||
link: function (scope, el, attr, controllers) { | ||
var leoActivator = controllers[0]; | ||
var leoWindowBody = controllers[1]; | ||
$scope.NothasUrl = function (option) { | ||
return !option.url; | ||
}; | ||
$scope.hasUrl = function (option) { | ||
return !!option.url; | ||
}; | ||
leoWindowBody.saveUnregisteredState = function () { | ||
var stateName = this.detail.state; | ||
$scope.deactivate = function () { | ||
$scope.states.forEach(function (state) { | ||
state.active = false; | ||
leoConfiguration.addSavedState({ | ||
name: stateName, | ||
verb: leoWindowBody.detail._unregisteredState.verb, | ||
url: leoWindowBody.detail._unregisteredState.url, | ||
options: [ | ||
{ | ||
name: leoWindowBody.detail.option, | ||
status: leoWindowBody.detail.status, | ||
data: leoWindowBody.detail.value, | ||
delay: leoWindowBody.detail.delay | ||
} | ||
] | ||
}); | ||
leoConfiguration.deactivateAllStates(); | ||
leoActivator.selectTab('scenarios'); | ||
}; | ||
$scope.updateState = function (state) { | ||
if (state.active) { | ||
console.log('activate state option:' + state.name + ': ' + state.activeOption.name); | ||
leoConfiguration.activateStateOption(state.name, state.activeOption.name); | ||
} else { | ||
console.log('deactivating state: ' + state.name); | ||
leoConfiguration.deactivateState(state.name); | ||
leoWindowBody.test = { | ||
url: '', | ||
value: undefined | ||
}; | ||
leoWindowBody.submit = function (url) { | ||
leoWindowBody.test.value = undefined; | ||
leoWindowBody.url = url; | ||
if (url) { | ||
$http.get(url).success(function (res) { | ||
leoWindowBody.test.value = res; | ||
}); | ||
} | ||
}; | ||
} | ||
}; | ||
}]); | ||
$scope.states = leoConfiguration.getStates(); | ||
LeoWindowBody.$inject = ['$scope', 'leoConfiguration', '$timeout']; | ||
function LeoWindowBody($scope, leoConfiguration, $timeout) { | ||
this.detail = { | ||
option: 'success', | ||
delay: 0, | ||
status: 200 | ||
}; | ||
$scope.scenarios = leoConfiguration.getScenarios(); | ||
this.states = leoConfiguration.getStates(); | ||
$scope.activateScenario = function (scenario) { | ||
$scope.activeScenario = scenario; | ||
leoConfiguration.setActiveScenario(scenario); | ||
$scope.states = leoConfiguration.getStates(); | ||
}; | ||
this.scenarios = leoConfiguration.getScenarios(); | ||
$scope.requests = leoConfiguration.getRequestsLog(); | ||
this.notHasUrl = function (option) { | ||
return !option.url; | ||
}; | ||
$scope.$watch('detail.value', function(value){ | ||
if (!value) { | ||
return; | ||
} | ||
try { | ||
$scope.detail.stringValue = value ? JSON.stringify(value, null, 4) : ''; | ||
$scope.detail.error = ''; | ||
} | ||
catch (e) { | ||
$scope.detail.error = e.message; | ||
} | ||
}); | ||
this.hasUrl = function (option) { | ||
return !!option.url; | ||
}; | ||
$scope.$watch('detail.stringValue', function(value){ | ||
try { | ||
$scope.detail.value = value ? JSON.parse(value) : {}; | ||
$scope.detail.error = ''; | ||
} | ||
catch(e) { | ||
$scope.detail.error = e.message; | ||
} | ||
}); | ||
this.deactivate = function () { | ||
this.states.forEach(function (state) { | ||
state.active = false; | ||
}); | ||
leoConfiguration.deactivateAllStates(); | ||
}; | ||
$scope.requestSelect = function (request) { | ||
$scope.requests.forEach(function (request) { | ||
request.active = false; | ||
}); | ||
this.updateState = function (state) { | ||
if (state.active) { | ||
console.log('leonardo: activate state option:' + state.name + ': ' + state.activeOption.name); | ||
leoConfiguration.activateStateOption(state.name, state.activeOption.name); | ||
} else { | ||
console.log('leonardo: deactivating state: ' + state.name); | ||
leoConfiguration.deactivateState(state.name); | ||
} | ||
}; | ||
request.active = true; | ||
if (request.state && request.state.name) { | ||
var optionName = request.state.name + ' option ' + request.state.options.length; | ||
} | ||
this.activateScenario = function (scenario) { | ||
this.activeScenario = scenario; | ||
leoConfiguration.setActiveScenario(scenario); | ||
this.states = leoConfiguration.getStates(); | ||
}.bind(this); | ||
angular.extend($scope.detail, { | ||
state : (request.state && request.state.name) || '', | ||
option: optionName || '', | ||
delay: 0, | ||
status: 200, | ||
stateActive: !!request.state, | ||
value: request.data || {} | ||
}); | ||
$scope.detail._unregisteredState = request; | ||
}; | ||
this.requests = leoConfiguration.getRequestsLog(); | ||
$scope.$on('leonardo:stateChanged', function(event, stateObj) { | ||
$scope.states = leoConfiguration.getStates(); | ||
$scope.$watch('leoWindowBody.detail.value', function (value) { | ||
if (!value) { | ||
return; | ||
} | ||
try { | ||
this.detail.stringValue = value ? JSON.stringify(value, null, 4) : ''; | ||
this.detail.error = ''; | ||
} | ||
catch (e) { | ||
this.detail.error = e.message; | ||
} | ||
}.bind(this)); | ||
var state = $scope.states.filter(function(state){ | ||
return state.name === stateObj.name; | ||
})[0]; | ||
$scope.$watch('leoWindowBody.detail.stringValue', function (value) { | ||
try { | ||
this.detail.value = value ? JSON.parse(value) : {}; | ||
this.detail.error = ''; | ||
} | ||
catch (e) { | ||
this.detail.error = e.message; | ||
} | ||
}.bind(this)); | ||
if (state) { | ||
state.highlight = true; | ||
$timeout(function(){ | ||
state.highlight = false; | ||
}, 3000); | ||
} | ||
}); | ||
$scope.getStatesForExport = function () { | ||
$scope.exportStates = leoConfiguration.getStates(); | ||
} | ||
}], | ||
link: function(scope, el, attr, leoActivator) { | ||
scope.saveUnregisteredState = function () { | ||
var stateName = scope.detail.state; | ||
this.requestSelect = function (request) { | ||
this.requests.forEach(function (request) { | ||
request.active = false; | ||
}); | ||
leoConfiguration.addSavedState({ | ||
name: stateName, | ||
verb: scope.detail._unregisteredState.verb, | ||
url: scope.detail._unregisteredState.url, | ||
options: [ | ||
{ | ||
name: scope.detail.option, | ||
status: scope.detail.status, | ||
data: scope.detail.value | ||
} | ||
] | ||
}); | ||
request.active = true; | ||
leoActivator.selectTab('scenarios'); | ||
}; | ||
if (request.state && request.state.name) { | ||
var optionName = request.state.name + ' option ' + request.state.options.length; | ||
} | ||
angular.extend(this.detail, { | ||
state: (request.state && request.state.name) || '', | ||
option: optionName || '', | ||
delay: 0, | ||
status: 200, | ||
stateActive: !!request.state, | ||
value: request.data || {} | ||
}); | ||
this.detail._unregisteredState = request; | ||
}.bind(this); | ||
scope.test = { | ||
url: '', | ||
value: undefined | ||
}; | ||
$scope.$on('leonardo:stateChanged', function (event, stateObj) { | ||
this.states = leoConfiguration.getStates(); | ||
scope.submit = function(url){ | ||
scope.test.value = undefined; | ||
scope.url = url; | ||
if (url) { | ||
$http.get(url).success(function (res) { | ||
scope.test.value = res; | ||
}); | ||
} | ||
}; | ||
var state = this.states.filter(function (state) { | ||
return state.name === stateObj.name; | ||
})[0]; | ||
if (state) { | ||
state.highlight = true; | ||
$timeout(function () { | ||
state.highlight = false; | ||
}, 3000); | ||
} | ||
}; | ||
}]); | ||
}.bind(this)); | ||
this.getStatesForExport = function () { | ||
this.exportStates = leoConfiguration.getStates(); | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
1489283
76
7857
196
1