test/app.render.js JAVASCRIPT 393 lines View on github.com → Search inside
1'use strict'23var assert = require('node:assert')4var express = require('..');5var path = require('node:path')6var tmpl = require('./support/tmpl');78describe('app', function(){9  describe('.render(name, fn)', function(){10    it('should support absolute paths', function(done){11      var app = createApp();1213      app.locals.user = { name: 'tobi' };1415      app.render(path.join(__dirname, 'fixtures', 'user.tmpl'), function (err, str) {16        if (err) return done(err);17        assert.strictEqual(str, '<p>tobi</p>')18        done();19      })20    })2122    it('should support absolute paths with "view engine"', function(done){23      var app = createApp();2425      app.set('view engine', 'tmpl');26      app.locals.user = { name: 'tobi' };2728      app.render(path.join(__dirname, 'fixtures', 'user'), function (err, str) {29        if (err) return done(err);30        assert.strictEqual(str, '<p>tobi</p>')31        done();32      })33    })3435    it('should expose app.locals', function(done){36      var app = createApp();3738      app.set('views', path.join(__dirname, 'fixtures'))39      app.locals.user = { name: 'tobi' };4041      app.render('user.tmpl', function (err, str) {42        if (err) return done(err);43        assert.strictEqual(str, '<p>tobi</p>')44        done();45      })46    })4748    it('should support index.<engine>', function(done){49      var app = createApp();5051      app.set('views', path.join(__dirname, 'fixtures'))52      app.set('view engine', 'tmpl');5354      app.render('blog/post', function (err, str) {55        if (err) return done(err);56        assert.strictEqual(str, '<h1>blog post</h1>')57        done();58      })59    })6061    it('should handle render error throws', function(done){62      var app = express();6364      function View(name, options){65        this.name = name;66        this.path = 'fale';67      }6869      View.prototype.render = function(options, fn){70        throw new Error('err!');71      };7273      app.set('view', View);7475      app.render('something', function(err, str){76        assert.ok(err)77        assert.strictEqual(err.message, 'err!')78        done();79      })80    })8182    describe('when the file does not exist', function(){83      it('should provide a helpful error', function(done){84        var app = createApp();8586        app.set('views', path.join(__dirname, 'fixtures'))87        app.render('rawr.tmpl', function (err) {88          assert.ok(err)89          assert.equal(err.message, 'Failed to lookup view "rawr.tmpl" in views directory "' + path.join(__dirname, 'fixtures') + '"')90          done();91        });92      })93    })9495    describe('when an error occurs', function(){96      it('should invoke the callback', function(done){97        var app = createApp();9899        app.set('views', path.join(__dirname, 'fixtures'))100101        app.render('user.tmpl', function (err) {102          assert.ok(err)103          assert.equal(err.name, 'RenderError')104          done()105        })106      })107    })108109    describe('when an extension is given', function(){110      it('should render the template', function(done){111        var app = createApp();112113        app.set('views', path.join(__dirname, 'fixtures'))114115        app.render('email.tmpl', function (err, str) {116          if (err) return done(err);117          assert.strictEqual(str, '<p>This is an email</p>')118          done();119        })120      })121    })122123    describe('when "view engine" is given', function(){124      it('should render the template', function(done){125        var app = createApp();126127        app.set('view engine', 'tmpl');128        app.set('views', path.join(__dirname, 'fixtures'))129130        app.render('email', function(err, str){131          if (err) return done(err);132          assert.strictEqual(str, '<p>This is an email</p>')133          done();134        })135      })136    })137138    describe('when "views" is given', function(){139      it('should lookup the file in the path', function(done){140        var app = createApp();141142        app.set('views',  path.join(__dirname, 'fixtures', 'default_layout'))143        app.locals.user = { name: 'tobi' };144145        app.render('user.tmpl', function (err, str) {146          if (err) return done(err);147          assert.strictEqual(str, '<p>tobi</p>')148          done();149        })150      })151152      describe('when array of paths', function(){153        it('should lookup the file in the path', function(done){154          var app = createApp();155          var views = [156            path.join(__dirname, 'fixtures', 'local_layout'),157            path.join(__dirname, 'fixtures', 'default_layout')158          ]159160          app.set('views', views);161          app.locals.user = { name: 'tobi' };162163          app.render('user.tmpl', function (err, str) {164            if (err) return done(err);165            assert.strictEqual(str, '<span>tobi</span>')166            done();167          })168        })169170        it('should lookup in later paths until found', function(done){171          var app = createApp();172          var views = [173            path.join(__dirname, 'fixtures', 'local_layout'),174            path.join(__dirname, 'fixtures', 'default_layout')175          ]176177          app.set('views', views);178          app.locals.name = 'tobi';179180          app.render('name.tmpl', function (err, str) {181            if (err) return done(err);182            assert.strictEqual(str, '<p>tobi</p>')183            done();184          })185        })186187        it('should error if file does not exist', function(done){188          var app = createApp();189          var views = [190            path.join(__dirname, 'fixtures', 'local_layout'),191            path.join(__dirname, 'fixtures', 'default_layout')192          ]193194          app.set('views', views);195          app.locals.name = 'tobi';196197          app.render('pet.tmpl', function (err, str) {198            assert.ok(err)199            assert.equal(err.message, 'Failed to lookup view "pet.tmpl" in views directories "' + views[0] + '" or "' + views[1] + '"')200            done();201          })202        })203      })204    })205206    describe('when a "view" constructor is given', function(){207      it('should create an instance of it', function(done){208        var app = express();209210        function View(name, options){211          this.name = name;212          this.path = 'path is required by application.js as a signal of success even though it is not used there.';213        }214215        View.prototype.render = function(options, fn){216          fn(null, 'abstract engine');217        };218219        app.set('view', View);220221        app.render('something', function(err, str){222          if (err) return done(err);223          assert.strictEqual(str, 'abstract engine')224          done();225        })226      })227    })228229    describe('caching', function(){230      it('should always lookup view without cache', function(done){231        var app = express();232        var count = 0;233234        function View(name, options){235          this.name = name;236          this.path = 'fake';237          count++;238        }239240        View.prototype.render = function(options, fn){241          fn(null, 'abstract engine');242        };243244        app.set('view cache', false);245        app.set('view', View);246247        app.render('something', function(err, str){248          if (err) return done(err);249          assert.strictEqual(count, 1)250          assert.strictEqual(str, 'abstract engine')251          app.render('something', function(err, str){252            if (err) return done(err);253            assert.strictEqual(count, 2)254            assert.strictEqual(str, 'abstract engine')255            done();256          })257        })258      })259260      it('should cache with "view cache" setting', function(done){261        var app = express();262        var count = 0;263264        function View(name, options){265          this.name = name;266          this.path = 'fake';267          count++;268        }269270        View.prototype.render = function(options, fn){271          fn(null, 'abstract engine');272        };273274        app.set('view cache', true);275        app.set('view', View);276277        app.render('something', function(err, str){278          if (err) return done(err);279          assert.strictEqual(count, 1)280          assert.strictEqual(str, 'abstract engine')281          app.render('something', function(err, str){282            if (err) return done(err);283            assert.strictEqual(count, 1)284            assert.strictEqual(str, 'abstract engine')285            done();286          })287        })288      })289    })290  })291292  describe('.render(name, options, fn)', function(){293    it('should render the template', function(done){294      var app = createApp();295296      app.set('views', path.join(__dirname, 'fixtures'))297298      var user = { name: 'tobi' };299300      app.render('user.tmpl', { user: user }, function (err, str) {301        if (err) return done(err);302        assert.strictEqual(str, '<p>tobi</p>')303        done();304      })305    })306307    it('should expose app.locals', function(done){308      var app = createApp();309310      app.set('views', path.join(__dirname, 'fixtures'))311      app.locals.user = { name: 'tobi' };312313      app.render('user.tmpl', {}, function (err, str) {314        if (err) return done(err);315        assert.strictEqual(str, '<p>tobi</p>')316        done();317      })318    })319320    it('should give precedence to app.render() locals', function(done){321      var app = createApp();322323      app.set('views', path.join(__dirname, 'fixtures'))324      app.locals.user = { name: 'tobi' };325      var jane = { name: 'jane' };326327      app.render('user.tmpl', { user: jane }, function (err, str) {328        if (err) return done(err);329        assert.strictEqual(str, '<p>jane</p>')330        done();331      })332    })333334    it('should accept null or undefined options', function (done) {335      var app = createApp()336337      app.set('views', path.join(__dirname, 'fixtures'))338      app.locals.user = { name: 'tobi' }339340      app.render('user.tmpl', null, function (err, str) {341        if (err) return done(err);342        assert.strictEqual(str, '<p>tobi</p>')343344        app.render('user.tmpl', undefined, function (err2, str2) {345          if (err2) return done(err2);346          assert.strictEqual(str2, '<p>tobi</p>')347          done()348        })349      })350    })351352    describe('caching', function(){353      it('should cache with cache option', function(done){354        var app = express();355        var count = 0;356357        function View(name, options){358          this.name = name;359          this.path = 'fake';360          count++;361        }362363        View.prototype.render = function(options, fn){364          fn(null, 'abstract engine');365        };366367        app.set('view cache', false);368        app.set('view', View);369370        app.render('something', {cache: true}, function(err, str){371          if (err) return done(err);372          assert.strictEqual(count, 1)373          assert.strictEqual(str, 'abstract engine')374          app.render('something', {cache: true}, function(err, str){375            if (err) return done(err);376            assert.strictEqual(count, 1)377            assert.strictEqual(str, 'abstract engine')378            done();379          })380        })381      })382    })383  })384})385386function createApp() {387  var app = express();388389  app.engine('.tmpl', tmpl);390391  return app;392}

Code quality findings 34

Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var assert = require('node:assert')
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var express = require('..');
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var path = require('node:path')
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var tmpl = require('./support/tmpl');
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var views = [
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var views = [
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var views = [
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var count = 0;
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var count = 0;
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var user = { name: 'tobi' };
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var jane = { name: 'jane' };
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createApp()
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var count = 0;
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express();

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.