Support import of E:D shipyard text exports

This commit is contained in:
Colin McLeod
2015-08-13 23:22:13 -07:00
parent 1edacf3eba
commit 0728af14dd
9 changed files with 304 additions and 81 deletions

View File

@@ -1,11 +1,25 @@
angular.module('app').controller('ImportController', ['lodash', '$rootScope', '$scope', '$stateParams', 'ShipsDB', 'Ship', 'Persist', 'Serializer', function(_, $rootScope, $scope, $stateParams, Ships, Ship, Persist, Serializer) {
$scope.jsonValid = false;
$scope.importJSON = null;
angular.module('app').controller('ImportController', ['lodash', '$rootScope', '$scope', '$stateParams', 'ShipsDB', 'Ship', 'Components', 'GroupMap', 'Persist', 'Serializer', function(_, $rootScope, $scope, $stateParams, Ships, Ship, Components, GroupMap, Persist, Serializer) {
$scope.importValid = false;
$scope.importString = null;
$scope.errorMsg = null;
$scope.canEdit = true;
$scope.builds = $stateParams.obj || null;
$scope.ships = Ships;
var textBuildRegex = new RegExp('^\\[([\\w \\-]+)\\]\n');
var lineRegex = new RegExp('^([\\dA-Z]{1,2}): (\\d)([A-I])[/]?([FGT])?([SD])? ([\\w\\- ]+)');
var mountMap = { 'H': 4, 'L': 3, 'M': 2, 'S': 1, 'U': 0 };
var commonMap = { 'RB': 0, 'TM': 1, 'FH': 2, 'EC': 3, 'PC': 4, 'SS': 5, 'FS': 6 };
var bhMap = { 'lightweight alloy': 0, 'reinforced alloy': 1, 'military grade composite': 2, 'mirrored surface composite': 3, 'reactive surface composite': 4 };
function isEmptySlot(slot) {
return slot.maxClass == this && slot.c === null;
}
function equalsIgnoreCase(str) {
return str.toLowerCase() == this.toLowerCase();
}
function validateBuild(shipId, code, name) {
var shipData = Ships[shipId];
@@ -83,40 +97,134 @@ angular.module('app').controller('ImportController', ['lodash', '$rootScope', '$
$scope.builds = builds;
}
$scope.validateJson = function() {
function importTextBuild(buildStr) {
var buildName = textBuildRegex.exec(buildStr)[1].trim();
var shipName = buildName.toLowerCase();
var shipId = null;
for (var sId in Ships) {
if (Ships[sId].properties.name.toLowerCase() == shipName) {
shipId = sId;
break;
}
}
if (!shipId) { throw 'No such ship found: "' + buildName + '"'; }
var lines = buildStr.split('\n');
var ship = new Ship(shipId, Ships[shipId].properties, Ships[shipId].slots);
ship.buildWith(null);
for (var i = 1; i < lines.length; i++) {
var line = lines[i].trim();
if (!line) { continue; }
if (line.substring(0, 3) == '---') { break; }
var parts = lineRegex.exec(line);
if (!parts) { throw 'Error parsing: "' + line + '"'; }
var typeSize = parts[1];
var cl = parts[2];
var rating = parts[3];
var mount = parts[4];
var missile = parts[5];
var name = parts[6].trim();
var slot, group;
if (isNaN(typeSize)) { // Common or Hardpoint
if (typeSize.length == 1) { // Hardpoint
var slotClass = mountMap[typeSize];
if (cl > slotClass) { throw cl + rating + ' ' + name + ' exceeds slot size: "' + line + '"'; }
slot = _.find(ship.hardpoints, isEmptySlot, slotClass);
if (!slot) { throw 'No hardpoint slot available for: "' + line + '"'; }
group = _.find(GroupMap, equalsIgnoreCase, name);
var hpid = Components.findHardpointId(group, cl, rating, group ? null : name, mount, missile);
if (!hpid) { throw 'Unknown component: "' + line + '"'; }
ship.use(slot, hpid, Components.hardpoints(hpid), true);
} else if (typeSize == 'BH') {
var bhId = bhMap[name.toLowerCase()];
if (bhId === undefined) { throw 'Unknown bulkhead: "' + line + '"'; }
ship.useBulkhead(bhId, true);
} else if (commonMap[typeSize] != undefined) {
var commonIndex = commonMap[typeSize];
if (ship.common[commonIndex].maxClass < cl) { throw name + ' exceeds max class for the ' + ship.name; }
ship.use(ship.common[commonIndex], cl + rating, Components.common(commonIndex, cl + rating), true);
} else {
throw 'Unknown component: "' + line + '"';
}
} else {
if (cl > typeSize) { throw cl + rating + ' ' + name + ' exceeds slot size: "' + line + '"'; }
slot = _.find(ship.internal, isEmptySlot, typeSize);
if (!slot) { throw 'No internal slot available for: "' + line + '"'; }
group = _.find(GroupMap, equalsIgnoreCase, name);
var intId = Components.findInternalId(group, cl, rating, group ? null : name);
if (!intId) { throw 'Unknown component: "' + line + '"'; }
ship.use(slot, intId, Components.internal(intId));
}
}
var builds = {};
builds[shipId] = {};
builds[shipId]['Imported ' + buildName] = Serializer.fromShip(ship);
$scope.builds = builds;
}
$scope.validateImport = function() {
var importData = null;
$scope.jsonValid = false;
var importString = $scope.importString.trim();
$scope.importValid = false;
$scope.errorMsg = null;
$scope.builds = $scope.discounts = $scope.comparisons = $scope.insurance = null;
if (!$scope.importJSON) { return; }
if (!importString) { return; }
try {
importData = angular.fromJson($scope.importJSON);
} catch (e) {
$scope.errorMsg = 'Cannot Parse JSON!';
return;
}
if (textBuildRegex.test(importString)) { // E:D Shipyard build text
importTextBuild(importString);
} else { // JSON Build data
importData = angular.fromJson($scope.importString);
if (!importData || typeof importData != 'object') {
$scope.errorMsg = 'Must be an object or array!';
return;
}
if (!importData || typeof importData != 'object') {
throw 'Must be an object or array!';
}
try {
if (importData instanceof Array) { // Must be detailed export json
importDetailedArray(importData);
} else if (importData.ship && importData.name) { // Using JSON from a single ship build export
importDetailedArray([importData]); // Convert to array with singleobject
} else { // Using Backup JSON
importBackup(importData);
if (importData instanceof Array) { // Must be detailed export json
importDetailedArray(importData);
} else if (importData.ship && importData.name) { // Using JSON from a single ship build export
importDetailedArray([importData]); // Convert to array with singleobject
} else { // Using Backup JSON
importBackup(importData);
}
}
} catch (e) {
$scope.errorMsg = e;
$scope.errorMsg = (typeof e == 'string') ? e : 'Cannot Parse the data!';
return;
}
$scope.jsonValid = true;
$scope.importValid = true;
};
$scope.hasBuild = function(shipId, name) {

View File

@@ -145,7 +145,14 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
*/
$scope.select = function(type, slot, e, id) {
e.stopPropagation();
id = id || angular.element(e.target).attr('cpid'); // Get component ID
if (!id) { // Find component id if not passed
var elem = e.target;
while (elem && elem !== e.currentTarget && !elem.getAttribute('cpid')) {
elem = elem.parentElement;
}
id = elem.getAttribute('cpid');
}
if (id) {
if (id == 'empty') {

View File

@@ -3,7 +3,7 @@ angular.module('app').directive('loader', function() {
restrict: 'A',
link: function(scope, element) {
element.addClass('loader');
element.html('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewbox="0 0 40 40" width="100%" height="100%"><!-- Outer Ring --><path d="m5,8l5,8l5,-8z" class="l1 d1" /><path d="m5,8l5,-8l5,8z" class="l1 d2" /><path d="m10,0l5,8l5,-8z" class="l1 d3" /><path d="m15,8l5,-8l5,8z" class="l1 d4" /><path d="m20,0l5,8l5,-8z" class="l1 d5" /><path d="m25,8l5,-8l5,8z" class="l1 d6" /><path d="m25,8l5,8l5,-8z" class="l1 d7" /><path d="m30,16l5,-8l5,8z" class="l1 d8" /><path d="m30,16l5,8l5,-8z" class="l1 d9" /><path d="m25,24l5,-8l5,8z" class="l1 d10" /><path d="m25,24l5,8l5,-8z" class="l1 d11" /><path d="m20,32l5,-8l5,8z" class="l1 d13" /><path d="m15,24l5,8l5,-8z" class="l1 d14" /><path d="m10,32l5,-8l5,8z" class="l1 d15" /><path d="m5,24l5,8l5,-8z" class="l1 d16" /><path d="m5,24l5,-8l5,8z" class="l1 d17" /><path d="m0,16l5,8l5,-8z" class="l1 d18" /><path d="m0,16l5,-8l5,8z" class="l1 d20" /><!-- Inner Ring --><path d="m10,16l5,-8l5,8z" class="l2 d0" /><path d="m15,8l5,8l5,-8z" class="l2 d3" /><path d="m20,16l5,-8l5,8z" class="l2 d6" /><path d="m20,16l5,8l5,-8z" class="l2 d9" /><path d="m15,24l5,-8l5,8z" class="l2 d12" /><path d="m10,16l5,8l5,-8z" class="l2 d15" /></svg>');
element.html('<svg viewbox="0 0 40 40" width="100%" height="100%"><path d="m5,8l5,8l5,-8z" class="l1 d1" /><path d="m5,8l5,-8l5,8z" class="l1 d2" /><path d="m10,0l5,8l5,-8z" class="l1 d3" /><path d="m15,8l5,-8l5,8z" class="l1 d4" /><path d="m20,0l5,8l5,-8z" class="l1 d5" /><path d="m25,8l5,-8l5,8z" class="l1 d6" /><path d="m25,8l5,8l5,-8z" class="l1 d7" /><path d="m30,16l5,-8l5,8z" class="l1 d8" /><path d="m30,16l5,8l5,-8z" class="l1 d9" /><path d="m25,24l5,-8l5,8z" class="l1 d10" /><path d="m25,24l5,8l5,-8z" class="l1 d11" /><path d="m20,32l5,-8l5,8z" class="l1 d13" /><path d="m15,24l5,8l5,-8z" class="l1 d14" /><path d="m10,32l5,-8l5,8z" class="l1 d15" /><path d="m5,24l5,8l5,-8z" class="l1 d16" /><path d="m5,24l5,-8l5,8z" class="l1 d17" /><path d="m0,16l5,8l5,-8z" class="l1 d18" /><path d="m0,16l5,-8l5,8z" class="l1 d20" /><path d="m10,16l5,-8l5,8z" class="l2 d0" /><path d="m15,8l5,8l5,-8z" class="l2 d3" /><path d="m20,16l5,-8l5,8z" class="l2 d6" /><path d="m20,16l5,8l5,-8z" class="l2 d9" /><path d="m15,24l5,-8l5,8z" class="l2 d12" /><path d="m10,16l5,8l5,-8z" class="l2 d15" /></svg>');
}
};
});

View File

@@ -95,7 +95,7 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
this.totalDps = 0;
this.bulkheads.c = null;
this.useBulkhead(comps.bulkheads || 0, true);
this.useBulkhead(comps && comps.bulkheads ? comps.bulkheads : 0, true);
this.cargoScoop.priority = priorities ? priorities[0] * 1 : 0;
this.cargoScoop.enabled = enabled ? enabled[0] * 1 : true;
@@ -116,7 +116,10 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
common[i].type = 'SYS';
common[i].c = common[i].id = null; // Resetting 'old' component if there was one
common[i].discountedCost = 0;
this.use(common[i], comps.common[i], Components.common(i, comps.common[i]), true);
if (comps) {
this.use(common[i], comps.common[i], Components.common(i, comps.common[i]), true);
}
}
common[1].type = 'ENG'; // Thrusters
@@ -131,7 +134,7 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
hps[i].c = hps[i].id = null; // Resetting 'old' component if there was one
hps[i].discountedCost = 0;
if (comps.hardpoints[i] !== 0) {
if (comps && comps.hardpoints[i] !== 0) {
this.use(hps[i], comps.hardpoints[i], Components.hardpoints(comps.hardpoints[i]), true);
}
}
@@ -146,15 +149,17 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
internal[i].id = internal[i].c = null; // Resetting 'old' component if there was one
internal[i].discountedCost = 0;
if (comps.internal[i] !== 0) {
if (comps && comps.internal[i] !== 0) {
this.use(internal[i], comps.internal[i], Components.internal(comps.internal[i]), true);
}
}
// Update aggragated stats
this.updatePower();
this.updateJumpStats();
this.updateShieldStrength();
if (comps) {
this.updatePower();
this.updateJumpStats();
this.updateShieldStrength();
}
};
Ship.prototype.useBulkhead = function(index, preventUpdate) {

View File

@@ -33,15 +33,25 @@ angular.module('shipyard').service('Components', ['lodash', 'ComponentsDB', 'Shi
};
this.findInternalId = function(groupName, clss, rating, name) {
var group = C.internal[groupName];
var groups = {};
if (!group) {
throw 'Invalid internal group: ' + groupName;
if (groupName) {
if (!C.internal[groupName]) {
throw 'Invalid internal group: ' + groupName;
}
groups[groupName] = C.internal[groupName];
} else if (name) {
groups = C.internal;
} else {
throw 'Invalid group or name not provided';
}
for (var i = 0, l = group.length; i < l; i++) {
if (group[i].class == clss && group[i].rating == rating && ((!name && !group[i].name) || group[i].name == name)) {
return group[i].id;
for (var g in groups) {
var group = groups[g];
for (var i = 0, l = group.length; i < l; i++) {
if (group[i].class == clss && group[i].rating == rating && ((!name && !group[i].name) || group[i].name == name)) {
return group[i].id;
}
}
}
@@ -49,18 +59,28 @@ angular.module('shipyard').service('Components', ['lodash', 'ComponentsDB', 'Shi
};
this.findHardpointId = function(groupName, clss, rating, name, mode, missile) {
var group = C.hardpoints[groupName];
var groups = {};
if (!group) {
throw 'Invalid hardpoint group: ' + groupName;
if (groupName) {
if (!C.hardpoints[groupName]) {
throw 'Invalid internal group: ' + groupName;
}
groups[groupName] = C.hardpoints[groupName];
} else if (name) {
groups = C.hardpoints;
} else {
throw 'Invalid group or name not provided';
}
for (var i = 0, l = group.length; i < l; i++) {
if (group[i].class == clss && group[i].rating == rating && group[i].mode == mode
&& ((!name && !group[i].name) || group[i].name == name)
&& ((!missile && !group[i].missile) || group[i].missile == missile)
) {
return group[i].id;
for (var g in groups) {
var group = groups[g];
for (var i = 0, l = group.length; i < l; i++) {
if (group[i].class == clss && group[i].rating == rating && group[i].mode == mode
&& ((!name && !group[i].name) || group[i].name == name)
&& ((!missile && !group[i].missile) || group[i].missile == missile)
) {
return group[i].id;
}
}
}

View File

@@ -1,7 +1,7 @@
<h2>Import</h2>
<div ng-show="!processed">
<textarea class="cb json" ng-model="importJSON" ng-change="validateJson()" placeholder="Paste JSON Here"></textarea>
<button class="l" ng-click="process()" ng-disabled="!jsonValid">Proceed</button>
<textarea class="cb json" ng-model="importString" ng-change="validateImport()" placeholder="Paste JSON or Build text Here"></textarea>
<button class="l" ng-click="process()" ng-disabled="!importValid">Proceed</button>
<div class="l warning" style="margin-left:3em;">{{errorMsg}}</div>
</div>
@@ -34,7 +34,7 @@
</table>
<button class="cl l" ng-click="import()"><svg class="icon"><use xlink:href="#download"></use></svg> Import</button>
<button class="l" style="margin-left: 2em;" ng-click="processed = false" ng-show="canEdit">Edit JSON</button>
<button class="l" style="margin-left: 2em;" ng-click="processed = false" ng-show="canEdit">Edit Data</button>
</div>
<button class="r dismiss" ng-click="dismiss()">Cancel</button>

View File

@@ -0,0 +1,22 @@
[
{
"buildText": "[Imaginary Ship]\nbla bla",
"errorMsg": "No such ship found: \"Imaginary Ship\""
},
{
"buildText": "[Viper]\nS: 1F/F Pulse Laser\nsome un-parseable nonsense\nS: 1F/F Pulse Laser\n",
"errorMsg": "Error parsing: \"some un-parseable nonsense\""
},
{
"buildText": "[Sidewinder]\nS: 2F/F Pulse Laser\nS: 1F/F Pulse Laser\n",
"errorMsg": "2F Pulse Laser exceeds slot size: \"S: 2F/F Pulse Laser\""
},
{
"buildText": "[Sidewinder]\nL: 2F/F Pulse Laser\nS: 1F/F Pulse Laser\n",
"errorMsg": "No hardpoint slot available for: \"L: 2F/F Pulse Laser\""
},
{
"buildText": "[Sidewinder]\nS: 1F/F Magic Thing\nS: 1F/F Pulse Laser\n",
"errorMsg": "Unknown component: \"S: 1F/F Magic Thing\""
}
]

View File

@@ -0,0 +1,26 @@
[
{
"shipId": "anaconda",
"buildName": "Imported Anaconda",
"buildCode": "08E7E6E5E8E8E5C------1717--------05044j-03--2h--00.Iw18ZlA=.Aw18ZlA=",
"buildText": "[Anaconda]\nS: 1F/F Pulse Laser\nS: 1F/F Pulse Laser\n\nBH: 1I Lightweight Alloy\nRB: 8E Power Plant\nTM: 7E Thrusters\nFH: 6E Frame Shift Drive\nEC: 5E Life Support\nPC: 8E Power Distributor\nSS: 8E Sensors\nFS: 5C Fuel Tank (Capacity: 32)\n\n7: 6E Cargo Rack (Capacity: 64)\n6: 5E Cargo Rack (Capacity: 32)\n6: 6E Shield Generator\n5: 4E Cargo Rack (Capacity: 16)\n4: 1E Basic Discovery Scanner\n2: 1E Cargo Rack (Capacity: 2)\n"
},
{
"shipId": "cobra_mk_iii",
"buildName": "Imported Cobra Mk III",
"buildCode": "04A4C4E3D2A3D4C1712222503040202490f242h.Iw1-kA==.Aw1-kA==",
"buildText": "[Cobra Mk III]\nM: 1F/F Pulse Laser\nM: 1G/G Burst Laser\nS: 1E/T Fragment Cannon\nS: 1G/T Multi-cannon\nU: 0I Point Defence\nU: 0A Shield Booster\n\nBH: 1I Lightweight Alloy\nRB: 4A Power Plant\nTM: 4C Thrusters\nFH: 4E Frame Shift Drive\nEC: 3D Life Support\nPC: 2A Power Distributor\nSS: 3D Sensors\nFS: 4C Fuel Tank (Capacity: 16)\n\n4: 3E Cargo Rack (Capacity: 8)\n4: 3E Cargo Rack (Capacity: 8)\n4: 4E Shield Generator\n2: 2C Auto Field-Maintenance Unit\n2: 1E Standard Docking Computer\n2: 1E Basic Discovery Scanner\n---\nShield: 112.29 MJ\nPower : 10.45 MW retracted (67%)\n 12.16 MW deployed (78%)\n 15.60 MW available\nCargo : 16 T\nFuel : 16 T\nMass : 235.5 T empty\n 267.5 T full\nRange : 10.69 LY unladen\n 10.05 LY laden\nPrice : 2,929,040 CR\nRe-Buy: 146,452 CR @ 95% insurance\n"
},
{
"shipId": "type_9_heavy",
"buildName": "Imported Type-9 Heavy",
"buildCode": "35A7D6A5A4D4D5C7e2k2f2h110001020306054j03022f01242i.Iw18eQ==.Aw18eQ==",
"buildText": "[Type-9 Heavy]\nM: 2D/G Fragment Cannon\nM: 2I/F Mine Launcher\nM: 2B/FD Missile Rack\nS: 1I/FS Torpedo Pylon\nS: 1F/F Burst Laser\nU: 0I Chaff Launcher\nU: 0F Electronic Countermeasure\nU: 0I Heat Sink Launcher\nU: 0I Point Defence\n\nBH: 1I Mirrored Surface Composite\nRB: 5A Power Plant\nTM: 7D Thrusters\nFH: 6A Frame Shift Drive\nEC: 5A Life Support\nPC: 4D Power Distributor\nSS: 4D Sensors\nFS: 5C Fuel Tank (Capacity: 32)\n\n8: 7E Cargo Rack (Capacity: 128)\n7: 6E Cargo Rack (Capacity: 64)\n6: 6E Shield Generator\n5: 4E Cargo Rack (Capacity: 16)\n4: 3E Cargo Rack (Capacity: 8)\n4: 1C Advanced Discovery Scanner\n3: 2E Cargo Rack (Capacity: 4)\n3: 1E Standard Docking Computer\n2: 1C Detailed Surface Scanner\n"
},
{
"shipId": "vulture",
"buildName": "Imported Vulture",
"buildCode": "44A5A4A3D5A4D3C1e1e0e0j04044a0n532jf1.Iw19kA==.Aw19kA==",
"buildText": "[Vulture]\nL: 3E/G Pulse Laser\nL: 3E/G Pulse Laser\nU: 0A Frame Shift Wake Scanner\nU: 0A Kill Warrant Scanner\nU: 0A Shield Booster\nU: 0A Shield Booster\n\nBH: 1I Reactive Surface Composite\nRB: 4A Power Plant\nTM: 5A Thrusters\nFH: 4A Frame Shift Drive\nEC: 3D Life Support\nPC: 5A Power Distributor\nSS: 4D Sensors\nFS: 3C Fuel Tank (Capacity: 8)\n\n5: 5A Shield Generator\n4: 4A Auto Field-Maintenance Unit\n2: 2A Shield Cell Bank\n1: 1A Fuel Scoop\n1: 1C Fuel Tank (Capacity: 2)"
}
]

View File

@@ -37,9 +37,9 @@ describe('Import Controller', function() {
it('imports a valid backup', function() {
var importData = __json__['fixtures/valid-backup'];
scope.importJSON = angular.toJson(importData);
scope.validateJson();
expect(scope.jsonValid).toBeTruthy();
scope.importString = angular.toJson(importData);
scope.validateImport();
expect(scope.importValid).toBeTruthy();
expect(scope.errorMsg).toEqual(null);
scope.process();
expect(scope.processed).toBeTruthy();
@@ -52,9 +52,9 @@ describe('Import Controller', function() {
it('imports an old valid backup', function() {
var importData = __json__['fixtures/old-valid-export'];
scope.importJSON = angular.toJson(importData);
scope.validateJson();
expect(scope.jsonValid).toBeTruthy();
scope.importString = angular.toJson(importData);
scope.validateImport();
expect(scope.importValid).toBeTruthy();
expect(scope.errorMsg).toEqual(null);
scope.process();
expect(scope.processed).toBeTruthy();
@@ -65,31 +65,31 @@ describe('Import Controller', function() {
it('catches an invalid backup', function() {
var importData = __json__['fixtures/valid-backup'];
scope.importJSON = 'null';
scope.validateJson();
expect(scope.jsonValid).toBeFalsy();
scope.importString = 'null';
scope.validateImport();
expect(scope.importValid).toBeFalsy();
expect(scope.errorMsg).toEqual('Must be an object or array!');
scope.importJSON = '{ "builds": "Should not be a string" }';
scope.validateJson();
expect(scope.jsonValid).toBeFalsy();
scope.importString = '{ "builds": "Should not be a string" }';
scope.validateImport();
expect(scope.importValid).toBeFalsy();
expect(scope.errorMsg).toEqual('builds must be an object!');
scope.importJSON = angular.toJson(importData).replace('anaconda', 'invalid_ship');
scope.validateJson();
expect(scope.jsonValid).toBeFalsy();
scope.importString = angular.toJson(importData).replace('anaconda', 'invalid_ship');
scope.validateImport();
expect(scope.importValid).toBeFalsy();
expect(scope.errorMsg).toEqual('"invalid_ship" is not a valid Ship Id!');
scope.importJSON = angular.toJson(importData).replace('Dream', '');
scope.validateJson();
expect(scope.jsonValid).toBeFalsy();
scope.importString = angular.toJson(importData).replace('Dream', '');
scope.validateImport();
expect(scope.importValid).toBeFalsy();
expect(scope.errorMsg).toEqual('Imperial Clipper build "" must be a string at least 3 characters long!');
invalidImportData = angular.copy(importData);
invalidImportData.builds.asp = null; // Remove Asp Miner build used in comparison
scope.importJSON = angular.toJson(invalidImportData);
scope.validateJson();
expect(scope.jsonValid).toBeFalsy();
scope.importString = angular.toJson(invalidImportData);
scope.validateImport();
expect(scope.importValid).toBeFalsy();
expect(scope.errorMsg).toEqual('asp build "Miner" data is missing!');
});
@@ -100,9 +100,9 @@ describe('Import Controller', function() {
it('imports a valid build', function() {
var importData = __json__['fixtures/anaconda-test-detailed-export'];
scope.importJSON = angular.toJson(importData);
scope.validateJson();
expect(scope.jsonValid).toBeTruthy();
scope.importString = angular.toJson(importData);
scope.validateImport();
expect(scope.importValid).toBeTruthy();
expect(scope.errorMsg).toEqual(null);
scope.process();
expect(scope.processed).toBeTruthy();
@@ -114,9 +114,9 @@ describe('Import Controller', function() {
it('catches an invalid build', function() {
var importData = __json__['fixtures/anaconda-test-detailed-export'];
scope.importJSON = angular.toJson(importData).replace('components', 'comps');
scope.validateJson();
expect(scope.jsonValid).toBeFalsy();
scope.importString = angular.toJson(importData).replace('components', 'comps');
scope.validateImport();
expect(scope.importValid).toBeFalsy();
expect(scope.errorMsg).toEqual('Anaconda Build "Test": Invalid data');
});
@@ -127,9 +127,9 @@ describe('Import Controller', function() {
it('imports all builds', function() {
var importData = __json__['fixtures/valid-detailed-export'];
var expectedBuilds = __json__['fixtures/expected-builds'];
scope.importJSON = angular.toJson(importData);
scope.validateJson();
expect(scope.jsonValid).toBeTruthy();
scope.importString = angular.toJson(importData);
scope.validateImport();
expect(scope.importValid).toBeTruthy();
expect(scope.errorMsg).toEqual(null);
scope.process();
expect(scope.processed).toBeTruthy();
@@ -144,4 +144,39 @@ describe('Import Controller', function() {
});
describe('Import E:D Shipyard Builds', function() {
it('imports a valid builds', function() {
var imports = __json__['fixtures/ed-shipyard-import-valid'];
for (var i = 0; i < imports.length; i++ ) {
scope.importString = imports[i].buildText;
scope.validateImport();
expect(scope.importValid).toBeTruthy();
expect(scope.errorMsg).toEqual(null, 'Build #' + i + ': ' + imports[i].buildName);
if (scope.importValid) { // No point in carrying out other assertions
scope.process();
expect(scope.processed).toBeTruthy();
scope.import();
var allBuilds = angular.fromJson(localStorage.getItem('builds'));
var shipBuilds = allBuilds ? allBuilds[imports[i].shipId] : null;
var build = shipBuilds ? shipBuilds[imports[i].buildName] : null;
expect(build).toEqual(imports[i].buildCode, 'Build #' + i + ': ' + imports[i].buildName);
}
}
});
it('catches invalid builds', function() {
var imports = __json__['fixtures/ed-shipyard-import-invalid'];
for (var i = 0; i < imports.length; i++ ) {
scope.importString = imports[i].buildText;
scope.validateImport();
expect(scope.importValid).toBeFalsy();
expect(scope.errorMsg).toEqual(imports[i].errorMsg);
}
});
});
});