From 3081901cc98dae08921ce7de61979e6fb67f4d4e Mon Sep 17 00:00:00 2001 From: User Date: Fri, 31 Jan 2025 14:37:36 +0100 Subject: [PATCH 1/5] Test for view.prototype.render --- test/app.render.js | 94 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/test/app.render.js b/test/app.render.js index ca15e761d3..7647df2de8 100644 --- a/test/app.render.js +++ b/test/app.render.js @@ -4,6 +4,7 @@ var assert = require('node:assert') var express = require('..'); var path = require('node:path') var tmpl = require('./support/tmpl'); +const View = require('../lib/view.js'); describe('app', function(){ describe('.render(name, fn)', function(){ @@ -365,6 +366,99 @@ describe('app', function(){ }) }) +describe('View.prototype.render', function () { + it('should force callback to be async and pass correct arguments', function (done) { + var mockEngine = function (filePath, options, callback) { + callback(null, 'rendered content'); + }; + + var view = new View('test', { + root: path.join(__dirname, 'fixtures'), + engines: { '.tmpl': mockEngine }, + defaultEngine: '.tmpl' + }); + + var isAsync = false; + + var originalCallback = function (err, html) { + assert(isAsync, 'Callback should be async'); + assert.strictEqual(err, null, 'Error should be null'); + assert.strictEqual(html, 'rendered content', 'Rendered content should match'); + done(); + }; + + view.render({}, function (err, html) { + isAsync = true; + originalCallback(err, html); + }); + }); + + it('should handle errors correctly', function (done) { + var mockEngine = function (filePath, options, callback) { + callback(new Error('render error')); + }; + + var view = new View('test', { + root: path.join(__dirname, 'fixtures'), + engines: { '.tmpl': mockEngine }, + defaultEngine: '.tmpl' + }); + + view.render({}, function (err, html) { + assert(err instanceof Error, 'Error should be an instance of Error'); + assert.strictEqual(err.message, 'render error', 'Error message should match'); + assert.strictEqual(html, undefined, 'HTML should be undefined when there is an error'); + done(); + }); + }); + + it('should handle synchronous callbacks correctly', function (done) { + var mockEngine = function (filePath, options, callback) { + callback(null, 'sync rendered content'); + }; + + var view = new View('test', { + root: path.join(__dirname, 'fixtures'), + engines: { '.tmpl': mockEngine }, + defaultEngine: '.tmpl' + }); + + var isAsync = false; + + var originalCallback = function (err, html) { + assert(isAsync, 'Callback should be async'); + assert.strictEqual(err, null, 'Error should be null'); + assert.strictEqual(html, 'sync rendered content', 'Rendered content should match'); + done(); + }; + + view.render({}, function (err, html) { + isAsync = true; + originalCallback(err, html); + }); + }); + + it('should pass correct arguments to the engine', function (done) { + var mockEngine = function (filePath, options, callback) { + assert.strictEqual(filePath, view.path, 'File path should match'); + assert.deepStrictEqual(options, { key: 'value' }, 'Options should match'); + callback(null, 'rendered content'); + }; + + var view = new View('test', { + root: path.join(__dirname, 'fixtures'), + engines: { '.tmpl': mockEngine }, + defaultEngine: '.tmpl' + }); + + view.render({ key: 'value' }, function (err, html) { + assert.strictEqual(err, null, 'Error should be null'); + assert.strictEqual(html, 'rendered content', 'Rendered content should match'); + done(); + }); + }); +}); + function createApp() { var app = express(); From 4166f8d80ee0582519cb2c2fc466727d2596e5d5 Mon Sep 17 00:00:00 2001 From: User Date: Tue, 4 Feb 2025 19:06:17 +0100 Subject: [PATCH 2/5] added View.prototype.render in specific file view.js --- test/app.render.js | 96 +------------------------------------------- test/view.js | 99 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 95 deletions(-) create mode 100644 test/view.js diff --git a/test/app.render.js b/test/app.render.js index 7647df2de8..dccdc71729 100644 --- a/test/app.render.js +++ b/test/app.render.js @@ -4,7 +4,6 @@ var assert = require('node:assert') var express = require('..'); var path = require('node:path') var tmpl = require('./support/tmpl'); -const View = require('../lib/view.js'); describe('app', function(){ describe('.render(name, fn)', function(){ @@ -366,103 +365,10 @@ describe('app', function(){ }) }) -describe('View.prototype.render', function () { - it('should force callback to be async and pass correct arguments', function (done) { - var mockEngine = function (filePath, options, callback) { - callback(null, 'rendered content'); - }; - - var view = new View('test', { - root: path.join(__dirname, 'fixtures'), - engines: { '.tmpl': mockEngine }, - defaultEngine: '.tmpl' - }); - - var isAsync = false; - - var originalCallback = function (err, html) { - assert(isAsync, 'Callback should be async'); - assert.strictEqual(err, null, 'Error should be null'); - assert.strictEqual(html, 'rendered content', 'Rendered content should match'); - done(); - }; - - view.render({}, function (err, html) { - isAsync = true; - originalCallback(err, html); - }); - }); - - it('should handle errors correctly', function (done) { - var mockEngine = function (filePath, options, callback) { - callback(new Error('render error')); - }; - - var view = new View('test', { - root: path.join(__dirname, 'fixtures'), - engines: { '.tmpl': mockEngine }, - defaultEngine: '.tmpl' - }); - - view.render({}, function (err, html) { - assert(err instanceof Error, 'Error should be an instance of Error'); - assert.strictEqual(err.message, 'render error', 'Error message should match'); - assert.strictEqual(html, undefined, 'HTML should be undefined when there is an error'); - done(); - }); - }); - - it('should handle synchronous callbacks correctly', function (done) { - var mockEngine = function (filePath, options, callback) { - callback(null, 'sync rendered content'); - }; - - var view = new View('test', { - root: path.join(__dirname, 'fixtures'), - engines: { '.tmpl': mockEngine }, - defaultEngine: '.tmpl' - }); - - var isAsync = false; - - var originalCallback = function (err, html) { - assert(isAsync, 'Callback should be async'); - assert.strictEqual(err, null, 'Error should be null'); - assert.strictEqual(html, 'sync rendered content', 'Rendered content should match'); - done(); - }; - - view.render({}, function (err, html) { - isAsync = true; - originalCallback(err, html); - }); - }); - - it('should pass correct arguments to the engine', function (done) { - var mockEngine = function (filePath, options, callback) { - assert.strictEqual(filePath, view.path, 'File path should match'); - assert.deepStrictEqual(options, { key: 'value' }, 'Options should match'); - callback(null, 'rendered content'); - }; - - var view = new View('test', { - root: path.join(__dirname, 'fixtures'), - engines: { '.tmpl': mockEngine }, - defaultEngine: '.tmpl' - }); - - view.render({ key: 'value' }, function (err, html) { - assert.strictEqual(err, null, 'Error should be null'); - assert.strictEqual(html, 'rendered content', 'Rendered content should match'); - done(); - }); - }); -}); - function createApp() { var app = express(); app.engine('.tmpl', tmpl); return app; -} +} \ No newline at end of file diff --git a/test/view.js b/test/view.js new file mode 100644 index 0000000000..2fa423f858 --- /dev/null +++ b/test/view.js @@ -0,0 +1,99 @@ +'use strict' + +var path = require('node:path') +var assert = require('node:assert') +const View = require('../lib/view.js'); + + +describe('View.prototype.render', function () { + it('should force callback to be async and pass correct arguments', function (done) { + var mockEngine = function (filePath, options, callback) { + callback(null, 'rendered content'); + }; + + var view = new View('test', { + root: path.join(__dirname, 'fixtures'), + engines: { '.tmpl': mockEngine }, + defaultEngine: '.tmpl' + }); + + var isAsync = false; + + var originalCallback = function (err, html) { + assert(isAsync, 'Callback should be async'); + assert.strictEqual(err, null, 'Error should be null'); + assert.strictEqual(html, 'rendered content', 'Rendered content should match'); + done(); + }; + + view.render({}, function (err, html) { + isAsync = true; + originalCallback(err, html); + }); + }); + + it('should handle errors correctly', function (done) { + var mockEngine = function (filePath, options, callback) { + callback(new Error('render error')); + }; + + var view = new View('test', { + root: path.join(__dirname, 'fixtures'), + engines: { '.tmpl': mockEngine }, + defaultEngine: '.tmpl' + }); + + view.render({}, function (err, html) { + assert(err instanceof Error, 'Error should be an instance of Error'); + assert.strictEqual(err.message, 'render error', 'Error message should match'); + assert.strictEqual(html, undefined, 'HTML should be undefined when there is an error'); + done(); + }); + }); + + it('should handle synchronous callbacks correctly', function (done) { + var mockEngine = function (filePath, options, callback) { + callback(null, 'sync rendered content'); + }; + + var view = new View('test', { + root: path.join(__dirname, 'fixtures'), + engines: { '.tmpl': mockEngine }, + defaultEngine: '.tmpl' + }); + + var isAsync = false; + + var originalCallback = function (err, html) { + assert(isAsync, 'Callback should be async'); + assert.strictEqual(err, null, 'Error should be null'); + assert.strictEqual(html, 'sync rendered content', 'Rendered content should match'); + done(); + }; + + view.render({}, function (err, html) { + isAsync = true; + originalCallback(err, html); + }); + }); + + it('should pass correct arguments to the engine', function (done) { + var mockEngine = function (filePath, options, callback) { + assert.strictEqual(filePath, view.path, 'File path should match'); + assert.deepStrictEqual(options, { key: 'value' }, 'Options should match'); + callback(null, 'rendered content'); + }; + + var view = new View('test', { + root: path.join(__dirname, 'fixtures'), + engines: { '.tmpl': mockEngine }, + defaultEngine: '.tmpl' + }); + + view.render({ key: 'value' }, function (err, html) { + assert.strictEqual(err, null, 'Error should be null'); + assert.strictEqual(html, 'rendered content', 'Rendered content should match'); + done(); + }); + }); + }); \ No newline at end of file From b5628f4906a918f7816a39bbdbe6f34395bd04eb Mon Sep 17 00:00:00 2001 From: User Date: Tue, 11 Feb 2025 14:03:01 +0100 Subject: [PATCH 3/5] more accurate approach for test if callback was executed synchronously --- test/app.render.js | 2 +- test/view.js | 187 +++++++++++++++++++++++---------------------- 2 files changed, 97 insertions(+), 92 deletions(-) diff --git a/test/app.render.js b/test/app.render.js index dccdc71729..ca15e761d3 100644 --- a/test/app.render.js +++ b/test/app.render.js @@ -371,4 +371,4 @@ function createApp() { app.engine('.tmpl', tmpl); return app; -} \ No newline at end of file +} diff --git a/test/view.js b/test/view.js index 2fa423f858..2aa28e8a3e 100644 --- a/test/view.js +++ b/test/view.js @@ -1,99 +1,104 @@ -'use strict' +'use strict'; -var path = require('node:path') -var assert = require('node:assert') +const path = require('node:path'); +const assert = require('node:assert'); const View = require('../lib/view.js'); +describe('View.prototype.render', function() { + it('should ensure callback is always async', function(done) { + const mockEngine = function(filePath, options, callback) { + callback(null, 'rendered content'); + }; -describe('View.prototype.render', function () { - it('should force callback to be async and pass correct arguments', function (done) { - var mockEngine = function (filePath, options, callback) { - callback(null, 'rendered content'); - }; - - var view = new View('test', { - root: path.join(__dirname, 'fixtures'), - engines: { '.tmpl': mockEngine }, - defaultEngine: '.tmpl' - }); - - var isAsync = false; - - var originalCallback = function (err, html) { - assert(isAsync, 'Callback should be async'); - assert.strictEqual(err, null, 'Error should be null'); - assert.strictEqual(html, 'rendered content', 'Rendered content should match'); - done(); - }; - - view.render({}, function (err, html) { - isAsync = true; - originalCallback(err, html); - }); + const view = new View('test', { + root: path.join(__dirname, 'fixtures'), + engines: { '.tmpl': mockEngine }, + defaultEngine: '.tmpl' }); - - it('should handle errors correctly', function (done) { - var mockEngine = function (filePath, options, callback) { - callback(new Error('render error')); - }; - - var view = new View('test', { - root: path.join(__dirname, 'fixtures'), - engines: { '.tmpl': mockEngine }, - defaultEngine: '.tmpl' - }); - - view.render({}, function (err, html) { - assert(err instanceof Error, 'Error should be an instance of Error'); - assert.strictEqual(err.message, 'render error', 'Error message should match'); - assert.strictEqual(html, undefined, 'HTML should be undefined when there is an error'); - done(); - }); + + let isAsync = false; + + view.render({}, function(err, html) { + isAsync = true; + assert.strictEqual(err, null); + assert.strictEqual(html, 'rendered content'); + done(); + }); + + assert.strictEqual(isAsync, false, 'Callback was executed synchronously!'); + }); + + it('should handle errors correctly', function(done) { + const mockEngine = function(filePath, options, callback) { + callback(new Error('render error')); + }; + + const view = new View('test', { + root: path.join(__dirname, 'fixtures'), + engines: { '.tmpl': mockEngine }, + defaultEngine: '.tmpl' + }); + + let isAsync = false; + + view.render({}, function(err, html) { + isAsync = true; + assert(err instanceof Error); + assert.strictEqual(err.message, 'render error'); + assert.strictEqual(html, undefined); + done(); + }); + + assert.strictEqual(isAsync, false, 'Error callback was executed synchronously!'); + }); + + it('should handle synchronous engine callbacks correctly', function(done) { + const mockEngine = function(filePath, options, callback) { + return callback(null, 'sync rendered content'); + }; + + const view = new View('test', { + root: path.join(__dirname, 'fixtures'), + engines: { '.tmpl': mockEngine }, + defaultEngine: '.tmpl' }); - - it('should handle synchronous callbacks correctly', function (done) { - var mockEngine = function (filePath, options, callback) { - callback(null, 'sync rendered content'); - }; - - var view = new View('test', { - root: path.join(__dirname, 'fixtures'), - engines: { '.tmpl': mockEngine }, - defaultEngine: '.tmpl' - }); - - var isAsync = false; - - var originalCallback = function (err, html) { - assert(isAsync, 'Callback should be async'); - assert.strictEqual(err, null, 'Error should be null'); - assert.strictEqual(html, 'sync rendered content', 'Rendered content should match'); - done(); - }; - - view.render({}, function (err, html) { - isAsync = true; - originalCallback(err, html); - }); + + let isAsync = false; + + view.render({}, function(err, html) { + isAsync = true; + assert.strictEqual(err, null); + assert.strictEqual(html, 'sync rendered content'); + done(); }); - - it('should pass correct arguments to the engine', function (done) { - var mockEngine = function (filePath, options, callback) { - assert.strictEqual(filePath, view.path, 'File path should match'); - assert.deepStrictEqual(options, { key: 'value' }, 'Options should match'); - callback(null, 'rendered content'); - }; - - var view = new View('test', { - root: path.join(__dirname, 'fixtures'), - engines: { '.tmpl': mockEngine }, - defaultEngine: '.tmpl' - }); - - view.render({ key: 'value' }, function (err, html) { - assert.strictEqual(err, null, 'Error should be null'); - assert.strictEqual(html, 'rendered content', 'Rendered content should match'); - done(); - }); + + assert.strictEqual(isAsync, false, 'Callback from synchronous engine was not properly delayed!'); + }); + + it('should pass correct arguments to the engine', function(done) { + const expectedOptions = { key: 'value' }; + + const mockEngine = function(filePath, options, callback) { + assert.strictEqual(filePath, view.path); + assert.deepStrictEqual(options, expectedOptions); + callback(null, 'rendered content'); + }; + + const view = new View('test', { + root: path.join(__dirname, 'fixtures'), + engines: { '.tmpl': mockEngine }, + defaultEngine: '.tmpl' }); - }); \ No newline at end of file + + let isAsync = false; + + view.render(expectedOptions, function(err, html) { + isAsync = true; + assert.strictEqual(err, null); + assert.strictEqual(html, 'rendered content'); + done(); + }); + + assert.strictEqual(isAsync, false, 'Callback was executed synchronously!'); + }); +}); \ No newline at end of file From 853b442ae57ff108eff0977d6c94db3532f34f67 Mon Sep 17 00:00:00 2001 From: User Date: Tue, 11 Feb 2025 14:14:41 +0100 Subject: [PATCH 4/5] Renamed View to view --- test/view.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/view.js b/test/view.js index 2aa28e8a3e..eac8c7cdff 100644 --- a/test/view.js +++ b/test/view.js @@ -2,15 +2,15 @@ const path = require('node:path'); const assert = require('node:assert'); -const View = require('../lib/view.js'); +const view = require('../lib/view.js'); -describe('View.prototype.render', function() { +describe('view.prototype.render', function() { it('should ensure callback is always async', function(done) { const mockEngine = function(filePath, options, callback) { callback(null, 'rendered content'); }; - const view = new View('test', { + const viewInstance = new view('test', { root: path.join(__dirname, 'fixtures'), engines: { '.tmpl': mockEngine }, defaultEngine: '.tmpl' @@ -18,7 +18,7 @@ describe('View.prototype.render', function() { let isAsync = false; - view.render({}, function(err, html) { + viewInstance.render({}, function(err, html) { isAsync = true; assert.strictEqual(err, null); assert.strictEqual(html, 'rendered content'); @@ -33,7 +33,7 @@ describe('View.prototype.render', function() { callback(new Error('render error')); }; - const view = new View('test', { + const viewInstance = new view('test', { root: path.join(__dirname, 'fixtures'), engines: { '.tmpl': mockEngine }, defaultEngine: '.tmpl' @@ -41,7 +41,7 @@ describe('View.prototype.render', function() { let isAsync = false; - view.render({}, function(err, html) { + viewInstance.render({}, function(err, html) { isAsync = true; assert(err instanceof Error); assert.strictEqual(err.message, 'render error'); @@ -57,7 +57,7 @@ describe('View.prototype.render', function() { return callback(null, 'sync rendered content'); }; - const view = new View('test', { + const viewInstance = new view('test', { root: path.join(__dirname, 'fixtures'), engines: { '.tmpl': mockEngine }, defaultEngine: '.tmpl' @@ -65,7 +65,7 @@ describe('View.prototype.render', function() { let isAsync = false; - view.render({}, function(err, html) { + viewInstance.render({}, function(err, html) { isAsync = true; assert.strictEqual(err, null); assert.strictEqual(html, 'sync rendered content'); @@ -79,12 +79,12 @@ describe('View.prototype.render', function() { const expectedOptions = { key: 'value' }; const mockEngine = function(filePath, options, callback) { - assert.strictEqual(filePath, view.path); + assert.strictEqual(filePath, viewInstance.path); assert.deepStrictEqual(options, expectedOptions); callback(null, 'rendered content'); }; - const view = new View('test', { + const viewInstance = new view('test', { root: path.join(__dirname, 'fixtures'), engines: { '.tmpl': mockEngine }, defaultEngine: '.tmpl' @@ -92,7 +92,7 @@ describe('View.prototype.render', function() { let isAsync = false; - view.render(expectedOptions, function(err, html) { + viewInstance.render(expectedOptions, function(err, html) { isAsync = true; assert.strictEqual(err, null); assert.strictEqual(html, 'rendered content'); From e9c8a97ae84f62ee1ad1e755c23f6c75129aaff9 Mon Sep 17 00:00:00 2001 From: User Date: Tue, 11 Feb 2025 19:38:16 +0100 Subject: [PATCH 5/5] fixed should pass correct arguments to the engine --- test/view.js | 55 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/test/view.js b/test/view.js index eac8c7cdff..71b6bccccd 100644 --- a/test/view.js +++ b/test/view.js @@ -3,15 +3,18 @@ const path = require('node:path'); const assert = require('node:assert'); const view = require('../lib/view.js'); +const fs = require('node:fs') describe('view.prototype.render', function() { + const fixturesDir = path.join(__dirname, 'fixtures'); + it('should ensure callback is always async', function(done) { const mockEngine = function(filePath, options, callback) { callback(null, 'rendered content'); }; const viewInstance = new view('test', { - root: path.join(__dirname, 'fixtures'), + root: fixturesDir, engines: { '.tmpl': mockEngine }, defaultEngine: '.tmpl' }); @@ -34,7 +37,7 @@ describe('view.prototype.render', function() { }; const viewInstance = new view('test', { - root: path.join(__dirname, 'fixtures'), + root: fixturesDir, engines: { '.tmpl': mockEngine }, defaultEngine: '.tmpl' }); @@ -58,7 +61,7 @@ describe('view.prototype.render', function() { }; const viewInstance = new view('test', { - root: path.join(__dirname, 'fixtures'), + root: fixturesDir, engines: { '.tmpl': mockEngine }, defaultEngine: '.tmpl' }); @@ -75,30 +78,38 @@ describe('view.prototype.render', function() { assert.strictEqual(isAsync, false, 'Callback from synchronous engine was not properly delayed!'); }); - it('should pass correct arguments to the engine', function(done) { - const expectedOptions = { key: 'value' }; - - const mockEngine = function(filePath, options, callback) { - assert.strictEqual(filePath, viewInstance.path); - assert.deepStrictEqual(options, expectedOptions); - callback(null, 'rendered content'); + it('should pass correct arguments to the engine', function (done) { + const tempDir = fs.mkdtempSync(path.join(__dirname, 'test-')); + const expectedPath = path.join(tempDir, 'test.tmpl'); + + fs.writeFileSync(expectedPath, 'template content'); + + const mockEngine = (filePath, options, callback) => { + try { + assert.strictEqual(filePath, expectedPath, 'File path should match'); + assert.deepStrictEqual(options, { key: 'value' }, 'Options should match'); + callback(null, 'rendered content'); + } catch (err) { + callback(err); + } }; - + const viewInstance = new view('test', { - root: path.join(__dirname, 'fixtures'), + root: tempDir, engines: { '.tmpl': mockEngine }, defaultEngine: '.tmpl' }); - - let isAsync = false; - - viewInstance.render(expectedOptions, function(err, html) { - isAsync = true; - assert.strictEqual(err, null); - assert.strictEqual(html, 'rendered content'); - done(); + + viewInstance.render({ key: 'value' }, (err, html) => { + fs.rmSync(tempDir, { recursive: true, force: true }); + + if (err) return done(err); + try { + assert.strictEqual(html, 'rendered content', 'Rendered content should match'); + done(); + } catch (assertErr) { + done(assertErr); + } }); - - assert.strictEqual(isAsync, false, 'Callback was executed synchronously!'); }); }); \ No newline at end of file