@@ -13,6 +13,7 @@ const { writeFileSync, readFileSync } = require('node:fs');
1313const { join } = require ( 'node:path' ) ;
1414
1515const gjsGtsParser = require . resolve ( 'ember-eslint-parser' ) ;
16+ const hbsParser = require . resolve ( 'ember-eslint-parser/hbs' ) ;
1617
1718/**
1819 * Helper function which creates ESLint instance with enabled/disabled autofix feature.
@@ -1020,3 +1021,124 @@ describe('supports template-lint-disable directive', () => {
10201021 expect ( resultErrors ) . toHaveLength ( 0 ) ;
10211022 } ) ;
10221023} ) ;
1024+
1025+ describe ( 'supports template-lint-disable directive in hbs files' , ( ) => {
1026+ function initHbsESLint ( ) {
1027+ return new ESLint ( {
1028+ ignore : false ,
1029+ useEslintrc : false ,
1030+ plugins : { ember : plugin } ,
1031+ overrideConfig : {
1032+ root : true ,
1033+ parserOptions : {
1034+ ecmaVersion : 2022 ,
1035+ sourceType : 'module' ,
1036+ } ,
1037+ plugins : [ 'ember' ] ,
1038+ overrides : [
1039+ {
1040+ files : [ '**/*.hbs' ] ,
1041+ parser : hbsParser ,
1042+ processor : 'ember/noop' ,
1043+ rules : {
1044+ 'ember/template-no-bare-strings' : 'error' ,
1045+ } ,
1046+ } ,
1047+ ] ,
1048+ } ,
1049+ } ) ;
1050+ }
1051+
1052+ it ( 'disables all rules on the next line with mustache comment' , async ( ) => {
1053+ const eslint = initHbsESLint ( ) ;
1054+ const code = `<div>
1055+ {{! template-lint-disable }}
1056+ Hello world
1057+ </div>` ;
1058+ const results = await eslint . lintText ( code , { filePath : 'my-template.hbs' } ) ;
1059+ const resultErrors = results . flatMap ( ( result ) => result . messages ) ;
1060+ expect ( resultErrors ) . toHaveLength ( 0 ) ;
1061+ } ) ;
1062+
1063+ it ( 'disables all rules on the next line with mustache block comment' , async ( ) => {
1064+ const eslint = initHbsESLint ( ) ;
1065+ const code = `<div>
1066+ {{!-- template-lint-disable --}}
1067+ Hello world
1068+ </div>` ;
1069+ const results = await eslint . lintText ( code , { filePath : 'my-template.hbs' } ) ;
1070+ const resultErrors = results . flatMap ( ( result ) => result . messages ) ;
1071+ expect ( resultErrors ) . toHaveLength ( 0 ) ;
1072+ } ) ;
1073+
1074+ it ( 'only disables the next line, not subsequent lines' , async ( ) => {
1075+ const eslint = initHbsESLint ( ) ;
1076+ const code = `{{! template-lint-disable }}
1077+ <div>Hello world</div>
1078+ <div>Bare string here too</div>` ;
1079+ const results = await eslint . lintText ( code , { filePath : 'my-template.hbs' } ) ;
1080+ const resultErrors = results . flatMap ( ( result ) => result . messages ) ;
1081+ // Line 2 "Hello world" suppressed, but line 3 "Bare string here too" should still error
1082+ expect ( resultErrors ) . toHaveLength ( 1 ) ;
1083+ expect ( resultErrors [ 0 ] . line ) . toBe ( 3 ) ;
1084+ } ) ;
1085+
1086+ it ( 'disables a specific rule by name' , async ( ) => {
1087+ const eslint = initHbsESLint ( ) ;
1088+ const code = `<div>
1089+ {{! template-lint-disable ember/template-no-bare-strings }}
1090+ Hello world
1091+ </div>` ;
1092+ const results = await eslint . lintText ( code , { filePath : 'my-template.hbs' } ) ;
1093+ const resultErrors = results . flatMap ( ( result ) => result . messages ) ;
1094+ expect ( resultErrors ) . toHaveLength ( 0 ) ;
1095+ } ) ;
1096+
1097+ it ( 'supports template-lint rule name format (maps to ember/ prefix)' , async ( ) => {
1098+ const eslint = initHbsESLint ( ) ;
1099+ const code = `<div>
1100+ {{! template-lint-disable no-bare-strings }}
1101+ Hello world
1102+ </div>` ;
1103+ const results = await eslint . lintText ( code , { filePath : 'my-template.hbs' } ) ;
1104+ const resultErrors = results . flatMap ( ( result ) => result . messages ) ;
1105+ expect ( resultErrors ) . toHaveLength ( 0 ) ;
1106+ } ) ;
1107+
1108+ it ( 'does not suppress unrelated rules when a specific rule is named' , async ( ) => {
1109+ const eslint = initHbsESLint ( ) ;
1110+ const code = `<div>
1111+ {{! template-lint-disable ember/template-no-html-comments }}
1112+ Hello world
1113+ </div>` ;
1114+ const results = await eslint . lintText ( code , { filePath : 'my-template.hbs' } ) ;
1115+ const resultErrors = results . flatMap ( ( result ) => result . messages ) ;
1116+ // no-bare-strings should still fire since we only disabled no-html-comments
1117+ expect ( resultErrors ) . toHaveLength ( 1 ) ;
1118+ expect ( resultErrors [ 0 ] . ruleId ) . toBe ( 'ember/template-no-bare-strings' ) ;
1119+ } ) ;
1120+
1121+ it ( 'works with multiple disable comments in the same file' , async ( ) => {
1122+ const eslint = initHbsESLint ( ) ;
1123+ const code = `<div>
1124+ {{! template-lint-disable }}
1125+ Hello world
1126+ {{! template-lint-disable }}
1127+ Another bare string
1128+ </div>` ;
1129+ const results = await eslint . lintText ( code , { filePath : 'my-template.hbs' } ) ;
1130+ const resultErrors = results . flatMap ( ( result ) => result . messages ) ;
1131+ expect ( resultErrors ) . toHaveLength ( 0 ) ;
1132+ } ) ;
1133+
1134+ it ( 'bare strings without disable comment still trigger errors' , async ( ) => {
1135+ const eslint = initHbsESLint ( ) ;
1136+ const code = `<div>
1137+ Hello world
1138+ </div>` ;
1139+ const results = await eslint . lintText ( code , { filePath : 'my-template.hbs' } ) ;
1140+ const resultErrors = results . flatMap ( ( result ) => result . messages ) ;
1141+ expect ( resultErrors ) . toHaveLength ( 1 ) ;
1142+ expect ( resultErrors [ 0 ] . ruleId ) . toBe ( 'ember/template-no-bare-strings' ) ;
1143+ } ) ;
1144+ } ) ;
0 commit comments