11import * as path from 'node:path' ;
2+ import * as fsp from 'node:fs/promises' ;
3+ import ansis from 'ansis' ;
24import { RulesAction , RulesDependencies , RulesInput } from '../../../src/lib/actions/RulesAction' ;
5+ import { RulesActionSummaryViewer } from '../../../src/lib/viewers/ActionSummaryViewer' ;
36import { StubDefaultConfigFactory } from '../../stubs/StubCodeAnalyzerConfigFactories' ;
47import * as StubEnginePluginFactories from '../../stubs/StubEnginePluginsFactories' ;
58import { SpyRuleViewer } from '../../stubs/SpyRuleViewer' ;
9+ import { DisplayEventType , SpyDisplay } from '../../stubs/SpyDisplay' ;
10+
11+ const PATH_TO_GOLDFILES = path . join ( __dirname , '..' , '..' , 'fixtures' , 'comparison-files' , 'lib' , 'actions' , 'RulesAction.test.ts' ) ;
612
713describe ( 'RulesAction tests' , ( ) => {
814 let viewer : SpyRuleViewer ;
@@ -12,11 +18,14 @@ describe('RulesAction tests', () => {
1218 } )
1319
1420 it ( 'Submitting the all-selector returns all rules' , async ( ) => {
21+ const spyDisplay : SpyDisplay = new SpyDisplay ( ) ;
22+ const actionSummaryViewer : RulesActionSummaryViewer = new RulesActionSummaryViewer ( spyDisplay ) ;
1523 const dependencies : RulesDependencies = {
1624 configFactory : new StubDefaultConfigFactory ( ) ,
1725 pluginsFactory : new StubEnginePluginFactories . StubEnginePluginsFactory_withFunctionalStubEngine ( ) ,
1826 logEventListeners : [ ] ,
1927 progressListeners : [ ] ,
28+ actionSummaryViewer,
2029 viewer
2130 } ;
2231 const action = RulesAction . createAction ( dependencies ) ;
@@ -41,11 +50,14 @@ describe('RulesAction tests', () => {
4150 } ) ;
4251
4352 it ( 'Submitting a filtering selector returns only matching rules' , async ( ) => {
53+ const spyDisplay : SpyDisplay = new SpyDisplay ( ) ;
54+ const actionSummaryViewer : RulesActionSummaryViewer = new RulesActionSummaryViewer ( spyDisplay ) ;
4455 const dependencies : RulesDependencies = {
4556 configFactory : new StubDefaultConfigFactory ( ) ,
4657 pluginsFactory : new StubEnginePluginFactories . StubEnginePluginsFactory_withFunctionalStubEngine ( ) ,
4758 logEventListeners : [ ] ,
4859 progressListeners : [ ] ,
60+ actionSummaryViewer,
4961 viewer
5062 } ;
5163 const action = RulesAction . createAction ( dependencies ) ;
@@ -64,12 +76,15 @@ describe('RulesAction tests', () => {
6476 } ) ;
6577
6678 it ( 'Engines with target-dependent rules return the right rules' , async ( ) => {
79+ const spyDisplay : SpyDisplay = new SpyDisplay ( ) ;
80+ const actionSummaryViewer : RulesActionSummaryViewer = new RulesActionSummaryViewer ( spyDisplay ) ;
6781 const dependencies : RulesDependencies = {
6882 configFactory : new StubDefaultConfigFactory ( ) ,
6983 // The engine we're using here will synthesize one rule per target.
7084 pluginsFactory : new StubEnginePluginFactories . StubEnginePluginsFactory_withTargetDependentStubEngine ( ) ,
7185 logEventListeners : [ ] ,
7286 progressListeners : [ ] ,
87+ actionSummaryViewer,
7388 viewer
7489 } ;
7590 const targetedFilesAndFolders = [ 'package.json' , 'src' , 'README.md' ] ;
@@ -98,11 +113,14 @@ describe('RulesAction tests', () => {
98113 * test will help us do that.
99114 */
100115 it ( 'When no engines are registered, empty results are displayed' , async ( ) => {
116+ const spyDisplay : SpyDisplay = new SpyDisplay ( ) ;
117+ const actionSummaryViewer : RulesActionSummaryViewer = new RulesActionSummaryViewer ( spyDisplay ) ;
101118 const dependencies : RulesDependencies = {
102119 configFactory : new StubDefaultConfigFactory ( ) ,
103120 pluginsFactory : new StubEnginePluginFactories . StubEnginePluginsFactory_withNoPlugins ( ) ,
104121 logEventListeners : [ ] ,
105122 progressListeners : [ ] ,
123+ actionSummaryViewer,
106124 viewer
107125 } ;
108126 const action = RulesAction . createAction ( dependencies ) ;
@@ -118,11 +136,14 @@ describe('RulesAction tests', () => {
118136 } ) ;
119137
120138 it ( 'Throws an error when an engine throws an error' , async ( ) => {
139+ const spyDisplay : SpyDisplay = new SpyDisplay ( ) ;
140+ const actionSummaryViewer : RulesActionSummaryViewer = new RulesActionSummaryViewer ( spyDisplay ) ;
121141 const dependencies : RulesDependencies = {
122142 configFactory : new StubDefaultConfigFactory ( ) ,
123143 pluginsFactory : new StubEnginePluginFactories . StubEnginePluginsFactory_withThrowingStubPlugin ( ) ,
124144 logEventListeners : [ ] ,
125145 progressListeners : [ ] ,
146+ actionSummaryViewer,
126147 viewer
127148 } ;
128149 const action = RulesAction . createAction ( dependencies ) ;
@@ -133,6 +154,40 @@ describe('RulesAction tests', () => {
133154
134155 await expect ( executionPromise ) . rejects . toThrow ( 'SomeErrorFromGetAvailableEngineNames' ) ;
135156 } ) ;
157+
158+ describe ( 'Summary generation' , ( ) => {
159+ it . each ( [
160+ { quantifier : 'no' , expectation : 'Summary indicates absence of rules' , selector : 'NonsensicalTag' , goldfile : 'no-rules.txt.goldfile' } ,
161+ { quantifier : 'some' , expectation : 'Summary provides breakdown by engine' , selector : 'Recommended' , goldfile : 'some-rules.txt.goldfile' }
162+ ] ) ( 'When $quantifier rules are returned, $expectation' , async ( { selector, goldfile} ) => {
163+ const goldfilePath : string = path . join ( PATH_TO_GOLDFILES , 'action-summaries' , goldfile ) ;
164+ const spyDisplay : SpyDisplay = new SpyDisplay ( ) ;
165+ const actionSummaryViewer : RulesActionSummaryViewer = new RulesActionSummaryViewer ( spyDisplay ) ;
166+ const dependencies : RulesDependencies = {
167+ configFactory : new StubDefaultConfigFactory ( ) ,
168+ pluginsFactory : new StubEnginePluginFactories . StubEnginePluginsFactory_withFunctionalStubEngine ( ) ,
169+ logEventListeners : [ ] ,
170+ progressListeners : [ ] ,
171+ actionSummaryViewer,
172+ viewer
173+ } ;
174+ const action = RulesAction . createAction ( dependencies ) ;
175+ const input : RulesInput = {
176+ 'rule-selector' : [ selector ]
177+ } ;
178+
179+ await action . execute ( input ) ;
180+
181+ const displayEvents = spyDisplay . getDisplayEvents ( ) ;
182+ const displayedLogEvents = ansis . strip ( displayEvents
183+ . filter ( e => e . type === DisplayEventType . LOG )
184+ . map ( e => e . data )
185+ . join ( '\n' ) ) ;
186+
187+ const goldfileContents : string = await fsp . readFile ( goldfilePath , 'utf-8' ) ;
188+ expect ( displayedLogEvents ) . toContain ( goldfileContents ) ;
189+ } ) ;
190+ } ) ;
136191} ) ;
137192
138193// TODO: Whenever we decide to document the custom_engine_plugin_modules flag in our configuration file, then we'll want
0 commit comments