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