From 2ac78cebd0aa5da5e0615f5b7c8dcc7e5abaddb5 Mon Sep 17 00:00:00 2001
From: Mikael Lindqvist
Date: Wed, 12 Mar 2014 17:23:01 +0100
Subject: [PATCH 1/9] added preprocessor option
---
lib/yuidoc.js | 34 +++++++++-
scripts/test.sh | 3 +-
tests/input/preprocessor/preprocessortest.js | 5 ++
tests/lib/testpreprocessor.js | 9 +++
tests/preprocessor.js | 67 ++++++++++++++++++++
5 files changed, 116 insertions(+), 2 deletions(-)
create mode 100644 tests/input/preprocessor/preprocessortest.js
create mode 100644 tests/lib/testpreprocessor.js
create mode 100644 tests/preprocessor.js
diff --git a/lib/yuidoc.js b/lib/yuidoc.js
index 3d354047..d28cd90e 100755
--- a/lib/yuidoc.js
+++ b/lib/yuidoc.js
@@ -43,7 +43,8 @@ YUI.add('yuidoc', function (Y) {
version: '0.1.0',
paths: [],
themedir: path.join(__dirname, 'themes', 'default'),
- syntaxtype: 'js'
+ syntaxtype: 'js',
+ preprocessor: undefined
};
/**
@@ -245,8 +246,37 @@ YUI.add('yuidoc', function (Y) {
}
},
+ /**
+ * Applies preprocessors to the data tree.
+ * @method applyPreprocessors
+ * @private
+ */
+ applyPreprocessors: function (data) {
+ if (this.options.preprocessor) {
+ var preprocessors = [].concat(this.options.preprocessor);
+
+ for (var p in preprocessors) {
+ var preprocessor=preprocessors[p];
+
+ // Check if path is absolute, from:
+ // http://stackoverflow.com/questions/21698906/how-to-check-if-a-path-is-absolute-or-relative
+ var preprocessorAbsFile;
+ if (path.resolve(preprocessor)===preprocessor)
+ preprocessorAbsFile=preprocessor;
+
+ else
+ preprocessorAbsFile=path.join(process.cwd(),preprocessor);
+
+ var preprocessorModule=require(preprocessorAbsFile);
+
+ preprocessorModule(data);
+ }
+ }
+ },
+
/**
* Writes the parser JSON data to disk.
+ * Applies preprocessors, if any.
* @method writeJSON
* @param {Object} parser The DocParser instance to use
* @private
@@ -260,6 +290,8 @@ YUI.add('yuidoc', function (Y) {
data = parser.data;
+ this.applyPreprocessors(data);
+
data.warnings = parser.warnings;
if (self.selleck && self.options.selleck && data.files && data.modules) {
diff --git a/scripts/test.sh b/scripts/test.sh
index 94ffe494..6839f92a 100755
--- a/scripts/test.sh
+++ b/scripts/test.sh
@@ -19,7 +19,8 @@ wait
./builder.js \
./options.js \
./utils.js \
- ./files.js
+ ./files.js \
+ ./preprocessor.js
exit $?
diff --git a/tests/input/preprocessor/preprocessortest.js b/tests/input/preprocessor/preprocessortest.js
new file mode 100644
index 00000000..2444b634
--- /dev/null
+++ b/tests/input/preprocessor/preprocessortest.js
@@ -0,0 +1,5 @@
+/**
+ * This class is for testing the preprocessor option.
+ * @class TestPreprocessor
+ * @customtag hello
+ */
\ No newline at end of file
diff --git a/tests/lib/testpreprocessor.js b/tests/lib/testpreprocessor.js
new file mode 100644
index 00000000..b30cd792
--- /dev/null
+++ b/tests/lib/testpreprocessor.js
@@ -0,0 +1,9 @@
+module.exports=function(data) {
+ global.testPreprocessorCallCount++;
+
+ for (className in data.classes) {
+ classData=data.classes[className];
+
+ classData.customtagPlusStar=classData.customtag+"*";
+ }
+}
\ No newline at end of file
diff --git a/tests/preprocessor.js b/tests/preprocessor.js
new file mode 100644
index 00000000..0823ddb3
--- /dev/null
+++ b/tests/preprocessor.js
@@ -0,0 +1,67 @@
+/*global Y:true */
+var YUITest = require('yuitest'),
+ Assert = YUITest.Assert,
+ path = require('path'),
+ Y = require(path.join(__dirname, '../', 'lib', 'index'));
+
+//Move to the test dir before running the tests.
+process.chdir(__dirname);
+
+var suite = new YUITest.TestSuite({
+ name: 'Preprocessor Test Suite',
+ setUp: function () {
+ process.chdir(__dirname);
+ }
+});
+
+suite.add(new YUITest.TestCase({
+ name: "Preprocessor",
+ 'test: single preprocessor': function () {
+ global.testPreprocessorCallCount=0;
+
+ var json = (new Y.YUIDoc({
+ quiet: true,
+ paths: ['input/preprocessor'],
+ outdir: './out',
+ preprocessor: 'lib/testpreprocessor.js'
+ })).run();
+
+ Assert.areSame(global.testPreprocessorCallCount,1,"the preprocessor was not called");
+ },
+ 'test: single preprocessor with absolute path': function () {
+ global.testPreprocessorCallCount=0;
+
+ var json = (new Y.YUIDoc({
+ quiet: true,
+ paths: ['input/preprocessor'],
+ outdir: './out',
+ preprocessor: path.join(process.cwd(),'lib/testpreprocessor.js')
+ })).run();
+
+ Assert.areSame(global.testPreprocessorCallCount,1,"the preprocessor was not called when an absolute path was used");
+ },
+ 'test: several preprocessors': function () {
+ global.testPreprocessorCallCount=0;
+
+ var json = (new Y.YUIDoc({
+ quiet: true,
+ paths: ['input/preprocessor'],
+ outdir: './out',
+ preprocessor: ['lib/testpreprocessor.js','./lib/testpreprocessor']
+ })).run();
+
+ Assert.areSame(global.testPreprocessorCallCount,2,"the preprocessor was not called twice");
+ },
+ 'test: the test preprocessor does its job': function () {
+ var json = (new Y.YUIDoc({
+ quiet: true,
+ paths: ['input/preprocessor'],
+ outdir: './out',
+ preprocessor: 'lib/testpreprocessor.js'
+ })).run();
+
+ Assert.areSame(json.classes.TestPreprocessor.customtagPlusStar,"hello*","the preprocessor did not modify the data");
+ }
+}));
+
+YUITest.TestRunner.add(suite);
From 83d19eabacccb451909d9572650c2da00918fcf8 Mon Sep 17 00:00:00 2001
From: Mikael Lindqvist
Date: Wed, 12 Mar 2014 17:25:09 +0100
Subject: [PATCH 2/9] added newlines at end of file
---
tests/input/preprocessor/preprocessortest.js | 3 ++-
tests/lib/testpreprocessor.js | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/tests/input/preprocessor/preprocessortest.js b/tests/input/preprocessor/preprocessortest.js
index 2444b634..f622cb19 100644
--- a/tests/input/preprocessor/preprocessortest.js
+++ b/tests/input/preprocessor/preprocessortest.js
@@ -2,4 +2,5 @@
* This class is for testing the preprocessor option.
* @class TestPreprocessor
* @customtag hello
- */
\ No newline at end of file
+ */
+
\ No newline at end of file
diff --git a/tests/lib/testpreprocessor.js b/tests/lib/testpreprocessor.js
index b30cd792..d3d350f5 100644
--- a/tests/lib/testpreprocessor.js
+++ b/tests/lib/testpreprocessor.js
@@ -6,4 +6,4 @@ module.exports=function(data) {
classData.customtagPlusStar=classData.customtag+"*";
}
-}
\ No newline at end of file
+}
From bb2f846a6b9402f5c24f233fb993cf94b93e787d Mon Sep 17 00:00:00 2001
From: Mikael Lindqvist
Date: Wed, 12 Mar 2014 17:26:03 +0100
Subject: [PATCH 3/9] newline at end of file, 2nd try
---
tests/input/preprocessor/preprocessortest.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/tests/input/preprocessor/preprocessortest.js b/tests/input/preprocessor/preprocessortest.js
index f622cb19..314fec3c 100644
--- a/tests/input/preprocessor/preprocessortest.js
+++ b/tests/input/preprocessor/preprocessortest.js
@@ -3,4 +3,3 @@
* @class TestPreprocessor
* @customtag hello
*/
-
\ No newline at end of file
From 805df220ccba1e1f36ae0a09517d9ffb2154bee4 Mon Sep 17 00:00:00 2001
From: Mikael Lindqvist
Date: Wed, 12 Mar 2014 18:52:03 +0100
Subject: [PATCH 4/9] keep jshint happy and enable preprocessor tests for "npm
test"
---
lib/yuidoc.js | 19 +++++++++++--------
package.json | 2 +-
tests/preprocessor.js | 6 +++++-
3 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/lib/yuidoc.js b/lib/yuidoc.js
index d28cd90e..c98432d9 100755
--- a/lib/yuidoc.js
+++ b/lib/yuidoc.js
@@ -252,23 +252,26 @@ YUI.add('yuidoc', function (Y) {
* @private
*/
applyPreprocessors: function (data) {
+ var preprocessors, preprocessor, p,
+ preprocessorAbsFile, preprocessorModule;
+
if (this.options.preprocessor) {
- var preprocessors = [].concat(this.options.preprocessor);
+ preprocessors = [].concat(this.options.preprocessor);
- for (var p in preprocessors) {
- var preprocessor=preprocessors[p];
+ for (p=0; p
Date: Sun, 30 Mar 2014 13:08:05 +0200
Subject: [PATCH 5/9] let the preprocessor(s) see warnings to potentially act
on them.
---
lib/yuidoc.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/yuidoc.js b/lib/yuidoc.js
index c98432d9..364ae51c 100755
--- a/lib/yuidoc.js
+++ b/lib/yuidoc.js
@@ -293,10 +293,10 @@ YUI.add('yuidoc', function (Y) {
data = parser.data;
- this.applyPreprocessors(data);
-
data.warnings = parser.warnings;
+ this.applyPreprocessors(data);
+
if (self.selleck && self.options.selleck && data.files && data.modules) {
Object.keys(self.selleck).forEach(function (file) {
Object.keys(data.files).forEach(function (f) {
From de5762d1fdbc19f5af48c7f4e19df40752c130cf Mon Sep 17 00:00:00 2001
From: Mikael Lindqvist
Date: Sun, 30 Mar 2014 13:25:16 +0200
Subject: [PATCH 6/9] don't define an undefined value
---
lib/yuidoc.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/yuidoc.js b/lib/yuidoc.js
index 364ae51c..e031f992 100755
--- a/lib/yuidoc.js
+++ b/lib/yuidoc.js
@@ -43,8 +43,7 @@ YUI.add('yuidoc', function (Y) {
version: '0.1.0',
paths: [],
themedir: path.join(__dirname, 'themes', 'default'),
- syntaxtype: 'js',
- preprocessor: undefined
+ syntaxtype: 'js'
};
/**
From 3d19af818b6cff5e03254a36a2c6807dab4bd668 Mon Sep 17 00:00:00 2001
From: Mikael Lindqvist
Date: Sun, 30 Mar 2014 13:45:04 +0200
Subject: [PATCH 7/9] code cleanup and comments added
---
lib/yuidoc.js | 27 ++++++++++-----------------
1 file changed, 10 insertions(+), 17 deletions(-)
diff --git a/lib/yuidoc.js b/lib/yuidoc.js
index e031f992..073c3de9 100755
--- a/lib/yuidoc.js
+++ b/lib/yuidoc.js
@@ -251,28 +251,21 @@ YUI.add('yuidoc', function (Y) {
* @private
*/
applyPreprocessors: function (data) {
- var preprocessors, preprocessor, p,
- preprocessorAbsFile, preprocessorModule;
+ var preprocessors,
+ preprocessorsRelativeTo;
+
+ // If the preprocessor paths are relative they will be searched for relative
+ // to the process working directory. This is consistent with how other paths
+ // are treated by yuidoc, such as the config options 'paths' and 'outdir'.
+ preprocessorsRelativeTo = process.cwd();
if (this.options.preprocessor) {
preprocessors = [].concat(this.options.preprocessor);
- for (p=0; p
Date: Fri, 18 Apr 2014 12:40:36 +0200
Subject: [PATCH 8/9] * load preprocessors as standard npm modules, in addition
to searching relative to config file. * return data when applying
preprocessors rather than mutate the data in place. * pass config options to
preprocessors.
---
lib/yuidoc.js | 39 +++++++++++++------
tests/lib/testpreprocessor.js | 9 ++++-
tests/lib/testpreprocessormodule/package.json | 3 ++
.../testpreprocessormodule.js | 3 ++
tests/preprocessor.js | 36 +++++++++++++++--
5 files changed, 73 insertions(+), 17 deletions(-)
create mode 100644 tests/lib/testpreprocessormodule/package.json
create mode 100644 tests/lib/testpreprocessormodule/testpreprocessormodule.js
diff --git a/lib/yuidoc.js b/lib/yuidoc.js
index 073c3de9..80519338 100755
--- a/lib/yuidoc.js
+++ b/lib/yuidoc.js
@@ -246,27 +246,42 @@ YUI.add('yuidoc', function (Y) {
},
/**
- * Applies preprocessors to the data tree.
- * @method applyPreprocessors
+ * Applies preprocessors to the data tree.
+ * This function first clones the data and operates on the clone.
+ * @method runPreprocessors
* @private
+ * @return {Object} The mutated data
*/
- applyPreprocessors: function (data) {
- var preprocessors,
+ runPreprocessors: function (data) {
+ var self = this,
+ preprocessors,
preprocessorsRelativeTo;
- // If the preprocessor paths are relative they will be searched for relative
- // to the process working directory. This is consistent with how other paths
- // are treated by yuidoc, such as the config options 'paths' and 'outdir'.
+ // We will try to load the preprocessors as npm modules, but we will also
+ // search for them relative to the process working directory.
+ // The latter is consistent with how other paths are treated by yuidoc,
+ // such as the config options 'paths' and 'outdir'.
preprocessorsRelativeTo = process.cwd();
- if (this.options.preprocessor) {
- preprocessors = [].concat(this.options.preprocessor);
+ if (self.options.preprocessor) {
+ data=JSON.parse(JSON.stringify(data));
+
+ preprocessors = [].concat(self.options.preprocessor);
preprocessors.forEach(function (preprocessor) {
- var preprocessorModule = require(path.resolve(preprocessorsRelativeTo, preprocessor));
- preprocessorModule(data);
+ var preprocessorModule;
+
+ try {
+ preprocessorModule = require(preprocessor);
+ } catch (e) {
+ preprocessorModule = require(path.resolve(preprocessorsRelativeTo, preprocessor));
+ }
+
+ preprocessorModule(data, self.options);
});
}
+
+ return data;
},
/**
@@ -287,7 +302,7 @@ YUI.add('yuidoc', function (Y) {
data.warnings = parser.warnings;
- this.applyPreprocessors(data);
+ data = this.runPreprocessors(data);
if (self.selleck && self.options.selleck && data.files && data.modules) {
Object.keys(self.selleck).forEach(function (file) {
diff --git a/tests/lib/testpreprocessor.js b/tests/lib/testpreprocessor.js
index d3d350f5..09bbf011 100644
--- a/tests/lib/testpreprocessor.js
+++ b/tests/lib/testpreprocessor.js
@@ -1,9 +1,14 @@
-module.exports=function(data) {
+module.exports=function(data, options) {
+ var star="*";
+
+ if (options.star)
+ star=options.star;
+
global.testPreprocessorCallCount++;
for (className in data.classes) {
classData=data.classes[className];
- classData.customtagPlusStar=classData.customtag+"*";
+ classData.customtagPlusStar=classData.customtag+star;
}
}
diff --git a/tests/lib/testpreprocessormodule/package.json b/tests/lib/testpreprocessormodule/package.json
new file mode 100644
index 00000000..8ea47800
--- /dev/null
+++ b/tests/lib/testpreprocessormodule/package.json
@@ -0,0 +1,3 @@
+{
+ "main": "./testpreprocessormodule.js"
+}
\ No newline at end of file
diff --git a/tests/lib/testpreprocessormodule/testpreprocessormodule.js b/tests/lib/testpreprocessormodule/testpreprocessormodule.js
new file mode 100644
index 00000000..a25528b9
--- /dev/null
+++ b/tests/lib/testpreprocessormodule/testpreprocessormodule.js
@@ -0,0 +1,3 @@
+module.exports=function(data) {
+ data.testModuleWasHere=true;
+}
\ No newline at end of file
diff --git a/tests/preprocessor.js b/tests/preprocessor.js
index 5cc415ba..ab78ea68 100644
--- a/tests/preprocessor.js
+++ b/tests/preprocessor.js
@@ -2,6 +2,7 @@
var YUITest = require('yuitest'),
Assert = YUITest.Assert,
path = require('path'),
+ fs = require('fs'),
Y = require(path.join(__dirname, '../', 'lib', 'index'));
//Move to the test dir before running the tests.
@@ -36,7 +37,7 @@ suite.add(new YUITest.TestCase({
quiet: true,
paths: ['input/preprocessor'],
outdir: './out',
- preprocessor: path.join(process.cwd(),'lib/testpreprocessor.js')
+ preprocessor: path.join(process.cwd(),'/lib/testpreprocessor.js')
})).run();
Assert.isObject(json);
@@ -60,11 +61,40 @@ suite.add(new YUITest.TestCase({
quiet: true,
paths: ['input/preprocessor'],
outdir: './out',
- preprocessor: 'lib/testpreprocessor.js'
+ preprocessor: 'lib/testpreprocessor.js',
+ star: "#"
})).run();
Assert.isObject(json);
- Assert.areSame(json.classes.TestPreprocessor.customtagPlusStar,"hello*","the preprocessor did not modify the data");
+ Assert.areSame(json.classes.TestPreprocessor.customtagPlusStar,"hello#","the preprocessor did not modify the data");
+ },
+ 'test: load preprocessor as a npm module': function () {
+ // We are testing if it works to load the preprocessor from node_modules,
+ // so first we need to copy it in place.
+ if (!fs.existsSync("../node_modules/testpreprocessormodule")) {
+ fs.mkdirSync("../node_modules/testpreprocessormodule");
+ }
+
+ fs.writeFileSync("../node_modules/testpreprocessormodule/package.json",
+ fs.readFileSync("lib/testpreprocessormodule/package.json"));
+
+ fs.writeFileSync("../node_modules/testpreprocessormodule/testpreprocessormodule.js",
+ fs.readFileSync("lib/testpreprocessormodule/testpreprocessormodule.js"));
+
+ var json = (new Y.YUIDoc({
+ quiet: true,
+ paths: ['input/preprocessor'],
+ outdir: './out',
+ preprocessor: 'testpreprocessormodule'
+ })).run();
+
+ Assert.isObject(json);
+ Assert.isTrue(json.testModuleWasHere,"the preprocesor module was not run");
+
+ // Clean up things when we are done.
+ fs.unlinkSync("../node_modules/testpreprocessormodule/package.json");
+ fs.unlinkSync("../node_modules/testpreprocessormodule/testpreprocessormodule.js");
+ fs.rmdirSync("../node_modules/testpreprocessormodule");
}
}));
From 64b2acc1b4382297c1f8e657a6f565755ddf8907 Mon Sep 17 00:00:00 2001
From: Mikael Lindqvist
Date: Fri, 18 Apr 2014 12:46:24 +0200
Subject: [PATCH 9/9] newlines at end of files
---
tests/lib/testpreprocessormodule/package.json | 2 +-
tests/lib/testpreprocessormodule/testpreprocessormodule.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/lib/testpreprocessormodule/package.json b/tests/lib/testpreprocessormodule/package.json
index 8ea47800..e00fa501 100644
--- a/tests/lib/testpreprocessormodule/package.json
+++ b/tests/lib/testpreprocessormodule/package.json
@@ -1,3 +1,3 @@
{
"main": "./testpreprocessormodule.js"
-}
\ No newline at end of file
+}
diff --git a/tests/lib/testpreprocessormodule/testpreprocessormodule.js b/tests/lib/testpreprocessormodule/testpreprocessormodule.js
index a25528b9..001e814c 100644
--- a/tests/lib/testpreprocessormodule/testpreprocessormodule.js
+++ b/tests/lib/testpreprocessormodule/testpreprocessormodule.js
@@ -1,3 +1,3 @@
module.exports=function(data) {
data.testModuleWasHere=true;
-}
\ No newline at end of file
+}