Skip to content

Commit

Permalink
Merge pull request #114 from Kashoo/issue-113-escape-backticks
Browse files Browse the repository at this point in the history
Issue 113: Escape backticks in generated sync functions
  • Loading branch information
dkichler authored Apr 26, 2017
2 parents e6fded2 + 88865ab commit 23166e1
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 11 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- [#97](https://github.com/Kashoo/synctos/issues/97): Support dynamic document constraints
- [#100](https://github.com/Kashoo/synctos/issues/100): Option to initialize test helper module with document definition file

### Fixed
- [#113](https://github.com/Kashoo/synctos/issues/113): Backticks in document definitions cause syntax errors

## [1.8.0] - 2017-03-21
### Added
- [#90](https://github.com/Kashoo/synctos/issues/90): Document-wide constraints on file attachments
Expand Down
6 changes: 4 additions & 2 deletions etc/sync-function-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ exports.load = function(docDefinitionFilename, baseDir) {
syncDocDefn = syncDocDefn.replace(/importDocumentDefinitionFragment\s*\(\s*"((?:\\"|[^"])+)"\s*\)/g, readDocDefinitionFragment)
.replace(/importDocumentDefinitionFragment\s*\(\s*'((?:\\'|[^'])+)'\s*\)/g, readDocDefinitionFragment);

// Load the document definitions into the sync function template
var syncFunc = syncFuncTemplate.replace('%SYNC_DOCUMENT_DEFINITIONS%', function() { return syncDocDefn; });
// Load the document definitions into the sync function template and then escape any occurrence of the backtick character so the sync
// function can be used in a Sync Gateway configuration file multiline string
var syncFunc = syncFuncTemplate.replace('%SYNC_DOCUMENT_DEFINITIONS%', function() { return syncDocDefn; })
.replace(/`/g, function() { return '\\`'; });

// Normalize code block indentation, normalize line endings and replace blank lines with empty lines
syncFunc = indent.indentJS(syncFunc, ' ')
Expand Down
16 changes: 14 additions & 2 deletions etc/test-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,17 +257,21 @@ var defaultWriteChannel = 'write';

function initSyncFunction(filePath) {
// Load the contents of the sync function file into a global variable called syncFunction
var rawSyncFunction = fs.readFileSync(filePath).toString();

/*jslint evil: true */
eval('syncFunction = ' + fs.readFileSync(filePath).toString());
eval('syncFunction = ' + unescapeBackticks(rawSyncFunction));
/*jslint evil: false */

init();
}

function initDocumentDefinitions(filePath) {
// Generate a sync function from the document definitions and load its contents into a global variable called syncFunction
var rawDocDefinitions = syncFunctionLoader.load(filePath);

/*jslint evil: true */
eval('syncFunction = ' + syncFunctionLoader.load(filePath));
eval('syncFunction = ' + unescapeBackticks(rawDocDefinitions));
/*jslint evil: false */

init();
Expand Down Expand Up @@ -654,3 +658,11 @@ function verifyUnknownDocumentType(doc, oldDoc) {
expect(requireAccess.callCount).to.be(0);
expect(channel.callCount).to.be(0);
}

// Sync Gateway configuration files use the backtick character to denote the beginning and end of a multiline string. The sync function
// generator script automatically escapes backtick characters with the sequence "\`" so that it produces a valid multiline string.
// However, when loaded by the test helper, a sync function is not inserted into a Sync Gateway configuration file so we must "unescape"
// backtick characters to preserve the original intention.
function unescapeBackticks(originalString) {
return originalString.replace(/\\`/g, function() { return '`'; });
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"devDependencies": {
"expect.js": "^0.3.1",
"jshint": "^2.9.4",
"mocha": "^3.2.0",
"mocha": "^3.3.0",
"simple-mock": "^0.7.3"
},
"scripts": {
Expand Down
4 changes: 2 additions & 2 deletions test/hashtable-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ describe('Hashtable validation type', function() {
var doc = {
_id: 'hashtableDoc',
staticKeyRegexPatternValidationProp: {
'Foobar': 'baz',
'Foo`bar': 'baz',
'Baz': 'qux'
}
};
Expand All @@ -165,7 +165,7 @@ describe('Hashtable validation type', function() {
testHelper.verifyDocumentNotCreated(
doc,
'hashtableDoc',
errorFormatter.regexPatternHashtableKeyViolation('staticKeyRegexPatternValidationProp[123]', /^[a-zA-Z]+$/));
errorFormatter.regexPatternHashtableKeyViolation('staticKeyRegexPatternValidationProp[123]', /^[a-zA-Z]+(`[a-zA-Z]+)?$/));
});
});

Expand Down
2 changes: 1 addition & 1 deletion test/resources/hashtable-doc-definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function() {
staticKeyRegexPatternValidationProp: {
type: 'hashtable',
hashtableKeysValidator: {
regexPattern: /^[a-zA-Z]+$/
regexPattern: /^[a-zA-Z]+(`[a-zA-Z]+)?$/
}
},
dynamicKeyRegex: {
Expand Down
2 changes: 1 addition & 1 deletion test/resources/string-doc-definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function() {
},
staticRegexPatternValidationProp: {
type: 'string',
regexPattern: /^\d+$/
regexPattern: /^\d+`[a-z]+$/
},
dynamicRegex: {
type: 'string'
Expand Down
7 changes: 5 additions & 2 deletions test/string-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ describe('String validation type', function() {
it('allows a doc with a string that matches the expected pattern', function() {
var doc = {
_id: 'stringDoc',
staticRegexPatternValidationProp: '0472'
staticRegexPatternValidationProp: '0472`foo'
};

testHelper.verifyDocumentCreated(doc);
Expand All @@ -136,7 +136,10 @@ describe('String validation type', function() {
staticRegexPatternValidationProp: 'foobar'
};

testHelper.verifyDocumentNotCreated(doc, 'stringDoc', errorFormatter.regexPatternItemViolation('staticRegexPatternValidationProp', /^\d+$/));
testHelper.verifyDocumentNotCreated(
doc,
'stringDoc',
errorFormatter.regexPatternItemViolation('staticRegexPatternValidationProp', /^\d+`[a-z]+$/));
});
});

Expand Down

0 comments on commit 23166e1

Please sign in to comment.