More helper and tests

This commit is contained in:
Martin Aspeli
2013-09-03 23:31:11 +01:00
parent a95fc968ef
commit 0500a809b2
2 changed files with 216 additions and 16 deletions
+76 -13
View File
@@ -42,8 +42,8 @@ module.exports = (function() {
/**
*
*/
Workbook.prototype.substitute = function(sheet, substitions) {
Workbook.prototype.substitute = function(sheet, substitutions) {
// Get sheet and parse XML tree
// Loop over /worksheet/sheetData/row
@@ -61,22 +61,22 @@ module.exports = (function() {
// If string contains `${token}`, invoke substituion on this element
// using the using the following rules:
// - if `token` is not found in `substituions`, do nothing
// - if `token` is not found in `substitutions`, do nothing
// - if `substituions[token]` is a string, or if the shared string
// - if `substitutions[token]` is a string, or if the shared string
// contains other characters than the substituion reference,
// replace the characters in the shared string, but leave the
// shared string reference intact.
// - if `substituions[token]` is a number (`n`), boolean (`b`), or
// - if `substitutions[token]` is a number (`n`), boolean (`b`), or
// date (`d`; ISO8601 format) insert it into the column
// reference and change the cell type.
// - if `substituions[token]` is a list, clone and repeat the column
// - if `substitutions[token]` is a list, clone and repeat the column
// for each item in the list (converting strings and types)
// - if `token` starts with `table:`, assume it is in the format
// `${table:listName.varName}`. If `substituions[listName]` is a
// `${table:listName.varName}`. If `substitutions[listName]` is a
// list of objects, clone the row and repeat for each item in the
// list, substituting each `${table:listName.varName}` with the
// property `varName` of each value in the list `listName`.
@@ -108,22 +108,85 @@ module.exports = (function() {
});
};
// Write back the new shared strings list
Workbook.prototype.writeSharedStrings = function() {
// TODO
};
// Add a new shared string
Workbook.prototype.addSharedString = function(s) {
var self = this;
var idx = self.sharedStrings.length;
self.sharedStrings.push(s);
self.sharedStringsLookup[s] = idx;
return idx;
};
// Get the number of a shared string, adding a new one if necessary.
Workbook.prototype.stringIndex = function(s) {
var self = this;
var idx = self.sharedStringsLookup[s];
if(idx === undefined) {
idx = self.sharedStrings.length;
self.sharedStrings.push(s);
self.sharedStringsLookup[s] = idx;
idx = self.addSharedString(s);
}
return idx;
};
// Write back the new shared strings list
Workbook.prototype.writeSharedStrings = function() {
// TODO
// Replace a shared string with a new one at the same index. Return the
// index.
Workbook.prototype.replaceString = function(oldString, newString) {
var self = this;
var idx = self.sharedStringsLookup[oldString];
if(idx === undefined) {
idx = self.addSharedString(newString);
} else {
self.sharedStrings[idx] = newString;
delete self.sharedStringsLookup[oldString];
self.sharedStringsLookup[newString] = idx;
}
return idx;
};
// Return a list of tokens that may exist in the string.
// Keys are: `placeholder` (the full placeholder, including the `${}`
// delineators), `name` (the name part of the token), `key` (the object key
// for `table` tokens), `full` (boolean indicating whether this placeholder
// is the entirety of the string) and `type` (one of `table` or `cell`)
Workbook.prototype.extractPlaceholders = function(string) {
// Yes, that's right. It's a bunch of brackets and question marks and stuff.
var re = /\${(?:(.+?):)?(.+?)(?:\.(.+?))?}/g;
var match = null, matches = [];
while((match = re.exec(string)) !== null) {
matches.push({
placeholder: match[0],
type: match[1] || 'normal',
name: match[2],
key: match[3],
full: match[0].length === string.length
});
}
return matches;
};
// Split a reference into an object with keys `row` and `col`.
Workbook.prototype.splitRef = function(ref) {
var match = ref.match(/([A-Z]+)([0-9]+)/);
return {
col: match[1],
row: parseInt(match[2], 10)
};
};
// Join an object with keys `row` and `col` into a single reference string
Workbook.prototype.joinRef = function(ref) {
return ref.col.toUpperCase() + Number(ref.row).toString();
};
// Get the next column's cell reference given a reference like "B2".
+140 -3
View File
@@ -26,6 +26,146 @@ describe("Helpers", function() {
});
describe('replaceString', function() {
it("adds new string if old string not found", function() {
var t = new XlsxTemplate();
expect(t.replaceString("foo", "bar")).toEqual(0);
expect(t.sharedStrings).toEqual(["bar"]);
expect(t.sharedStringsLookup).toEqual({"bar": 0});
});
it("replaces strings if found", function() {
var t = new XlsxTemplate();
t.addSharedString("foo");
t.addSharedString("baz");
expect(t.replaceString("foo", "bar")).toEqual(0);
expect(t.sharedStrings).toEqual(["bar", "baz"]);
expect(t.sharedStringsLookup).toEqual({"bar": 0, "baz": 1});
});
});
describe('extractPlaceholders', function() {
it("can extract simple placeholders", function() {
var t = new XlsxTemplate();
expect(t.extractPlaceholders("${foo}")).toEqual([{
full: true,
key: undefined,
name: "foo",
placeholder: "${foo}",
type: "normal"
}]);
});
it("can extract simple placeholders inside strings", function() {
var t = new XlsxTemplate();
expect(t.extractPlaceholders("A string ${foo} bar")).toEqual([{
full: false,
key: undefined,
name: "foo",
placeholder: "${foo}",
type: "normal"
}]);
});
it("can extract multiple placeholders from one string", function() {
var t = new XlsxTemplate();
expect(t.extractPlaceholders("${foo} ${bar}")).toEqual([{
full: false,
key: undefined,
name: "foo",
placeholder: "${foo}",
type: "normal"
}, {
full: false,
key: undefined,
name: "bar",
placeholder: "${bar}",
type: "normal"
}]);
});
it("can extract placeholders with keys", function() {
var t = new XlsxTemplate();
expect(t.extractPlaceholders("${foo.bar}")).toEqual([{
full: true,
key: "bar",
name: "foo",
placeholder: "${foo.bar}",
type: "normal"
}]);
});
it("can extract placeholders with types", function() {
var t = new XlsxTemplate();
expect(t.extractPlaceholders("${table:foo}")).toEqual([{
full: true,
key: undefined,
name: "foo",
placeholder: "${table:foo}",
type: "table"
}]);
});
it("can extract placeholders with types and keys", function() {
var t = new XlsxTemplate();
expect(t.extractPlaceholders("${table:foo.bar}")).toEqual([{
full: true,
key: "bar",
name: "foo",
placeholder: "${table:foo.bar}",
type: "table"
}]);
});
it("can handle strings with no placeholders", function() {
var t = new XlsxTemplate();
expect(t.extractPlaceholders("A string")).toEqual([]);
});
});
describe('splitRef', function() {
it("splits single digit and letter values", function() {
var t = new XlsxTemplate();
expect(t.splitRef("A1")).toEqual({col: "A", row: 1});
});
it("splits multiple digit and letter values", function() {
var t = new XlsxTemplate();
expect(t.splitRef("AB12")).toEqual({col: "AB", row: 12});
});
});
describe('joinRef', function() {
it("joins single digit and letter values", function() {
var t = new XlsxTemplate();
expect(t.joinRef({col: "A", row: 1})).toEqual("A1");
});
it("joins multiple digit and letter values", function() {
var t = new XlsxTemplate();
expect(t.joinRef({col: "AB", row: 12})).toEqual("AB12");
});
});
describe('nexCol', function() {
it("increments single columns", function() {
@@ -33,7 +173,6 @@ describe("Helpers", function() {
expect(t.nextCol("A1")).toEqual("B1");
expect(t.nextCol("B1")).toEqual("C1");
});
it("maintains row index", function() {
@@ -41,7 +180,6 @@ describe("Helpers", function() {
expect(t.nextCol("A99")).toEqual("B99");
expect(t.nextCol("B11231")).toEqual("C11231");
});
it("captialises letters", function() {
@@ -80,7 +218,6 @@ describe("Helpers", function() {
expect(t.nextRow("A1")).toEqual("A2");
expect(t.nextRow("B1")).toEqual("B2");
expect(t.nextRow("AZ2")).toEqual("AZ3");
});
it("captialises letters", function() {