• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

moosetechnology / MooseIDE / 30074028047

24 Jul 2026 07:00AM UTC coverage: 67.55% (-0.03%) from 67.579%
30074028047

push

github

web-flow
Merge pull request #1647 from moosetechnology/1646-ModelReport-should-open-before-computing-the-report

1646 model report should open before computing the report
fix #1646

25 of 43 new or added lines in 4 files covered. (58.14%)

23106 of 34206 relevant lines covered (67.55%)

1.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/MooseIDE-Core-Reporter/MiModelReportModel.class.st
1
"
2
The spec model for the `MiModelReport`
3

4
Responsible for actually generating the report
5
"
6
Class {
7
        #name : 'MiModelReportModel',
8
        #superclass : 'MiAbstractModel',
9
        #instVars : [
10
                'mooseModel',
11
                'settings',
12
                'report',
13
                'largeClassThreshold',
14
                'longClassThreshold',
15
                'dataClassThreshold',
16
                'longMethodThreshold',
17
                'complexMethodThreshold',
18
                'excessiveAPIThreshold'
19
        ],
20
        #category : 'MooseIDE-Core-Reporter',
21
        #package : 'MooseIDE-Core-Reporter'
22
}
23

24
{ #category : 'as yet unclassified' }
25
MiModelReportModel class >> defaultComplexMethodThreshold [
×
26

×
27
        ^ 50
×
28
]
×
29

30
{ #category : 'accessing' }
31
MiModelReportModel class >> defaultConfiguration [
×
32

×
33
        ^ MiModelReportSettingsConfiguration new
×
34
                  largeClassThreshold: self defaultLargeClassThreshold;
×
35
                  longClassThreshold: self defaultLongClassThreshold;
×
36
                  dataClassThreshold: self defaultDataClassThreshold;
×
37
                  longMethodThreshold: self defaultLongMethodThreshold;
×
38
                  complexMethodThreshold: self defaultComplexMethodThreshold;
×
39
                  excessiveAPIThreshold: self defaultExcessiveAPIThreshold;
×
40
                  yourself
×
41
]
×
42

43
{ #category : 'as yet unclassified' }
44
MiModelReportModel class >> defaultDataClassThreshold [
×
45

×
46
        ^ 10
×
47
]
×
48

49
{ #category : 'as yet unclassified' }
50
MiModelReportModel class >> defaultExcessiveAPIThreshold [
×
51

×
52
        ^ 5
×
53
]
×
54

55
{ #category : 'as yet unclassified' }
56
MiModelReportModel class >> defaultLargeClassThreshold [
×
57

×
58
        ^ 100
×
59
]
×
60

61
{ #category : 'as yet unclassified' }
62
MiModelReportModel class >> defaultLongClassThreshold [
×
63

×
64
        ^ 1000
×
65
]
×
66

67
{ #category : 'as yet unclassified' }
68
MiModelReportModel class >> defaultLongMethodThreshold [
×
69

×
70
        ^ 100
×
71
]
×
72

73
{ #category : 'microdown' }
74
MiModelReportModel >> bulletList: aCollection [
×
75

×
76
        aCollection do: [ :line |
×
77
                report
×
78
                        << '- ' ;
×
79
                        << line ;
×
80
                        cr
×
81
        ].
×
82
        report cr
×
83
]
×
84

85
{ #category : 'document' }
86
MiModelReportModel >> classMembersStats: columns [
×
87

×
88
        self stats: columns compute: [ :c | c numberOfAttributes ] description: 'FIELDS'.
×
89
        self stats: columns compute: [ :c | c numberOfMethods ]    description: 'METHODS'
×
90
]
×
91

92
{ #category : 'document' }
NEW
93
MiModelReportModel >> computingReportMessage [
×
NEW
94

×
NEW
95
        ^'Computing report on ''' ,
×
NEW
96
                mooseModel name ,
×
NEW
97
                ''' (' ,
×
NEW
98
                mooseModel size asString ,
×
NEW
99
                ' entities)...'
×
NEW
100
]
×
101

102
{ #category : 'settings management' }
103
MiModelReportModel >> currentConfiguration [
×
104

×
105
        ^ MiModelReportSettingsConfiguration new
×
106
                  largeClassThreshold: largeClassThreshold;
×
107
                  longClassThreshold: longClassThreshold;
×
108
                  dataClassThreshold: dataClassThreshold;
×
109
                  longMethodThreshold: longMethodThreshold;
×
110
                  complexMethodThreshold: complexMethodThreshold;
×
111
                  excessiveAPIThreshold: excessiveAPIThreshold;
×
112
                  yourself
×
113
]
×
114

115
{ #category : 'accessing' }
116
MiModelReportModel >> defaultConfiguration [
×
117

×
118
        ^ self class defaultConfiguration
×
119
]
×
120

121
{ #category : 'document' }
122
MiModelReportModel >> document [
×
123
                
×
124
        self title: ('Dashboard : '  , mooseModel name).
×
125

×
126
        self sectionPackages.
×
127
        self sectionClasses.
×
128
        self sectionMethods.
×
129

×
130
]
×
131

132
{ #category : 'accessing' }
133
MiModelReportModel >> entities [
×
134
        ^mooseModel
×
135
]
×
136

137
{ #category : 'api - export' }
138
MiModelReportModel >> exportReportToHTML: microdownText [
×
139

×
140
        | filename |
×
141
        filename := mooseModel name , '-report.html'.
×
142
        filename asFileReference writeStreamDo: [ :stream |
×
143
                stream nextPutAll: (MicHTMLVisitor asHTMLString: microdownText) ].
×
144
        browser inform:
×
145
                filename , ' generated' , String cr , '(in Pharo image directory)'
×
146
]
×
147

148
{ #category : 'api - export' }
149
MiModelReportModel >> exportReportToPDF: microdownText [
×
150

×
151
        browser inform: 'PDF export not implemented yet, sorry'
×
152
]
×
153

154
{ #category : 'private - formatting' }
155
MiModelReportModel >> floatAsString: aFloat [
×
156

×
157
        ^(aFloat asFloat round: 1) asString
×
158

×
159
]
×
160

161
{ #category : 'accessing' }
162
MiModelReportModel >> followEntity: aMooseEntity [
×
163

×
164
        mooseModel := (aMooseEntity isMooseModel ifTrue: [ aMooseEntity ] ifFalse: [ aMooseEntity mooseModel ]).
×
165
        self updateReport
×
166
]
×
167

168
{ #category : 'private - formatting' }
169
MiModelReportModel >> formatCollection: collection value: valueBlock [
×
170

×
171
        ^collection
×
172
                ifEmpty: [ 'n/a' ]
×
173
                ifNotEmpty: [ self floatAsString: (valueBlock value: collection) ]
×
174
]
×
175

176
{ #category : 'private - formatting' }
177
MiModelReportModel >> fullyQualifiedName: anEntity [
×
178

×
179
        ^anEntity mooseName copyReplaceAll: '::' with: '.' 
×
180

×
181
]
×
182

183
{ #category : 'testing' }
184
MiModelReportModel >> hasSettings [
×
185

×
186
        ^ true
×
187
]
×
188

189
{ #category : 'microdown' }
190
MiModelReportModel >> headerBlock: level header: aString [
×
191

×
192
        level timesRepeat: [ report << '#' ].
×
193
        report
×
194
                space ;
×
195
                << aString ;
×
196
                cr ; cr
×
197
]
×
198

199
{ #category : 'initialization' }
200
MiModelReportModel >> initializeSettings [
×
201

×
202
        largeClassThreshold := self class defaultLargeClassThreshold.
×
203
        longClassThreshold := self class defaultLongClassThreshold.
×
204
        dataClassThreshold := self class defaultDataClassThreshold.
×
205
        longMethodThreshold := self class defaultLongMethodThreshold.
×
206
        complexMethodThreshold := self class defaultComplexMethodThreshold.
×
207
        excessiveAPIThreshold := self class defaultExcessiveAPIThreshold
×
208
]
×
209

210
{ #category : 'microdown' }
211
MiModelReportModel >> line: aString [
×
212

×
213
        report
×
214
                << aString ;
×
215
                cr
×
216

×
217
]
×
218

219
{ #category : 'document' }
220
MiModelReportModel >> methodMembersStats: columns [
×
221

×
222
        self stats: columns compute: [ :m | m numberOfParameters ] description: 'PARAMETERS'.
×
223
        self stats: columns compute: [ :m | m numberOfLinesOfCode ]    description: 'LINES OF CODE'.
×
224
        self stats: columns compute: [ :m | m cyclomaticComplexity ]    description: 'CYCLOMATIC COMPLEXITY'
×
225
]
×
226

227
{ #category : 'accessing' }
228
MiModelReportModel >> miSelectedItem [
×
229

×
230
        ^#()
×
231
]
×
232

233
{ #category : 'private - formatting' }
234
MiModelReportModel >> numericValue: text value: number [
×
235

×
236
        ^text , ': ' , number asString
×
237
                
×
238
]
×
239

240
{ #category : 'accessing' }
241
MiModelReportModel >> reportDOM [
×
242

×
243
        ^ report
×
244
]
×
245

246
{ #category : 'api - export' }
247
MiModelReportModel >> saveRawReport: microdownText [
×
248

×
249
        | filename |
×
250
        filename := mooseModel name , '-report.md'.
×
251
        filename asFileReference writeStreamDo: [ :stream |
×
252
                stream nextPutAll: microdownText
×
253
        ].
×
254
        browser inform: filename , ' saved', String cr , '(in Pharo image directory)'
×
255
]
×
256

257
{ #category : 'document' }
258
MiModelReportModel >> sectionClasses [
×
259

×
260
        | allClasses largeClasses longClasses dataClasses |
×
261
        allClasses := OrderedCollection withAll: mooseModel allModelClasses.
×
262
        largeClasses := allClasses select: [ :c |
×
263
                                c numberOfMethods > largeClassThreshold ].
×
264
        longClasses := allClasses select: [ :c |
×
265
                               c numberOfLinesOfCode > longClassThreshold ].
×
266
        dataClasses := allClasses select: [ :c |
×
267
                               c numberOfAttributes > dataClassThreshold ].
×
268

×
269
        self subtitle: 'Classes'.
×
270

×
271
        "Stats table"
×
272
        self tableHeader: #( '' All Large Long Data ).
×
273
        self
×
274
                statLine: {
×
275
                                allClasses size asString.
×
276
                                largeClasses size asString.
×
277
                                longClasses size asString.
×
278
                                dataClasses size asString }
×
279
                description: 'number'.
×
280
        self classMembersStats: {
×
281
                        allClasses.
×
282
                        largeClasses.
×
283
                        longClasses.
×
284
                        dataClasses }.
×
285

×
286
        "Lists of entities"
×
287
        self
×
288
                subSectionSpecialList: largeClasses
×
289
                description:
×
290
                'Large classes (> ' , largeClassThreshold asString , ' methods)'.
×
291
        self
×
292
                subSectionSpecialList: longClasses
×
293
                description:
×
294
                'Long classes (> ' , longClassThreshold asString , ' LOC)'.
×
295
        self
×
296
                subSectionSpecialList: dataClasses
×
297
                description:
×
298
                'Data classes (> ' , dataClassThreshold asString , ' fields)'
×
299
]
×
300

301
{ #category : 'document' }
302
MiModelReportModel >> sectionMethods [
×
303

×
304
        | allMethods longMethods complexMethods excessiveAPIMethods |
×
305
        allMethods := OrderedCollection withAll: mooseModel allModelMethods.
×
306
        longMethods := allMethods select: [ :m |
×
307
                               m numberOfLinesOfCode > longMethodThreshold ].
×
308
        complexMethods := allMethods select: [ :m |
×
309
                                  m cyclomaticComplexity > complexMethodThreshold ].
×
310
        excessiveAPIMethods := allMethods select: [ :m |
×
311
                                       m numberOfParameters > excessiveAPIThreshold ].
×
312
        self subtitle: 'Methods'.
×
313

×
314
        "Stats table"
×
315
        self tableHeader: { ''. 'All'. 'Long'. 'Complex'. 'Excessive API' }.
×
316
        self
×
317
                statLine: {
×
318
                                allMethods size asString.
×
319
                                longMethods size asString.
×
320
                                complexMethods size asString.
×
321
                                excessiveAPIMethods size asString }
×
322
                description: 'number'.
×
323
        self methodMembersStats: {
×
324
                        allMethods.
×
325
                        longMethods.
×
326
                        complexMethods.
×
327
                        excessiveAPIMethods }.
×
328
        self line: ''.
×
329

×
330
        "Lists of entities"
×
331
        self
×
332
                subSectionSpecialList: longMethods
×
333
                description:
×
334
                'Long methods (> ' , longMethodThreshold asString , ' LOC)'.
×
335
        self
×
336
                subSectionSpecialList: complexMethods
×
337
                description: 'Complex methods (cyclomatic complexity > '
×
338
                        , complexMethodThreshold asString , ')'.
×
339
        self
×
340
                subSectionSpecialList: excessiveAPIMethods
×
341
                description:
×
342
                        'Excessive API methods (> ' , excessiveAPIThreshold asString
×
343
                        , ' parameters)'
×
344
]
×
345

346
{ #category : 'document' }
347
MiModelReportModel >> sectionMethodsStats: methods [
×
348

×
349
        self stats: (methods collect: [ :c | c numberOfParameters ]) description: 'parameters'.
×
350
        self stats: (methods collect: [ :c | c numberOfLinesOfCode ]) description: 'lines of code'.
×
351
        self stats: (methods collect: [ :c | c cyclomaticComplexity ]) description: 'cyclomatic complexity'
×
352

×
353
]
×
354

355
{ #category : 'document' }
356
MiModelReportModel >> sectionPackages [
×
357
        | number allClasses |
×
358

×
359
        self subtitle: 'Packages'.
×
360

×
361
        number := mooseModel allModelPackages size.
×
362
        allClasses := mooseModel allModelClasses asOrderedCollection.
×
363

×
364
        self line:
×
365
                (self numericValue: 'Number of Packages' value: number).
×
366
        self line:
×
367
                (self numericValue: 'Mean number of classes' value: (self floatAsString: (allClasses size / number))).
×
368
        self line:
×
369
                (self numericValue: 'Total number of classes' value: allClasses size).
×
370
        self line:
×
371
                (self numericValue: 'Total number of lines of code' value: (allClasses sum: #numberOfLinesOfCode)).
×
372
        self line: ''
×
373

×
374
]
×
375

376
{ #category : 'settings' }
377
MiModelReportModel >> settingsChanged: aBoolean [
×
378

×
379
        aBoolean ifTrue: [ self updateReport ].
×
380
]
×
381

382
{ #category : 'settings management' }
383
MiModelReportModel >> settingsPresenterExtent [
×
384

×
385
        ^ 425 @ 350
×
386
]
×
387

388
{ #category : 'microdown' }
389
MiModelReportModel >> statLine: columns        description: aString [
×
390

×
391
        self tableLine: { aString } , columns
×
392
]
×
393

394
{ #category : 'microdown' }
395
MiModelReportModel >> stats: columns compute: valueBlock description: aString [
×
396
        "columns is a collection of collections of entities (eg. {allClasses, largeClasses, longClasses})
×
397
         valueBlock takes one entity of these collections and compute a number form it (eg. numberOfAttributes)
×
398
         From this, we display 3 lines: mean value, median value, max value for each column"
×
399

×
400
        | valuesCollection |
×
401
        valuesCollection := columns collect: [ :collection | collection collect: valueBlock ].
×
402

×
403
        self tableLine: { aString }.
×
404
        self
×
405
                statLine: (valuesCollection collect: [ :column | self formatCollection: column value: #average])
×
406
                description: '. mean'.
×
407
        self
×
408
                statLine: (valuesCollection collect: [ :column | self formatCollection: column value: #median])
×
409
                description: '. median'.
×
410
        self
×
411
                statLine: (valuesCollection collect: [ :column | self formatCollection: column value: #max])
×
412
                description: '. max'
×
413

×
414
]
×
415

416
{ #category : 'document' }
417
MiModelReportModel >> subSectionSpecialList: collection description: aString [
×
418

×
419
        self subsubtitle: aString.
×
420

×
421
        self line: (self numericValue: 'Number' value: collection size).
×
422

×
423
        self bulletList: ((collection collect: [:c | self fullyQualifiedName: c ])
×
424
                sorted: [:a :b | a mooseName < b mooseName]).
×
425

×
426
]
×
427

428
{ #category : 'document' }
429
MiModelReportModel >> subSectionSpecialMethods: selectionBlock description: aString [
×
430

×
431
        | methods |
×
432
        self subsubtitle: aString.
×
433

×
434
        methods := (mooseModel allModelMethods select: selectionBlock)
×
435
                sorted: [:a :b | a mooseName < b mooseName].
×
436

×
437
        self line: (self numericValue: 'Number' value: methods size).
×
438
        self bulletList: (methods collect: [:c | self fullyQualifiedName: c ] ).
×
439

×
440
        self sectionMethodsStats: methods 
×
441

×
442
]
×
443

444
{ #category : 'microdown' }
445
MiModelReportModel >> subsubtitle: aString [
×
446

×
447
        ^self headerBlock: 3 header: aString.
×
448

×
449
]
×
450

451
{ #category : 'microdown' }
452
MiModelReportModel >> subtitle: aString [
×
453

×
454
        ^self headerBlock: 2 header: aString.
×
455

×
456
]
×
457

458
{ #category : 'microdown' }
459
MiModelReportModel >> tableHeader: aCollection [
×
460

×
461
        self tableLine: aCollection.
×
462
        report
×
463
                << '|---|' ;
×
464
                cr
×
465
]
×
466

467
{ #category : 'microdown' }
468
MiModelReportModel >> tableLine: aCollection [
×
469

×
470
        aCollection do: [ :item |
×
471
                report
×
472
                        << '| ' ;
×
473
                        << item ;
×
474
                        space
×
475
        ].
×
476
        report
×
477
                << '|' ;
×
478
                cr
×
479
]
×
480

481
{ #category : 'microdown' }
482
MiModelReportModel >> title: aString [
×
483

×
484
        ^self headerBlock: 1 header: aString.
×
485

×
486
]
×
487

488
{ #category : 'settings management' }
489
MiModelReportModel >> updateFromConfiguration: aConfiguration [
×
490

×
491
        largeClassThreshold := aConfiguration largeClassThreshold.
×
492
        longClassThreshold := aConfiguration longClassThreshold.
×
493
        dataClassThreshold := aConfiguration dataClassThreshold.
×
494

×
495
        longMethodThreshold := aConfiguration longMethodThreshold.
×
496
        complexMethodThreshold := aConfiguration complexMethodThreshold.
×
497
        excessiveAPIThreshold := aConfiguration excessiveAPIThreshold.
×
498

×
499
        mooseModel ifNil: [ ^ self ].
×
500
        self updateReport
×
501
]
×
502

503
{ #category : 'running' }
504
MiModelReportModel >> updateReport [
×
505

×
NEW
506
        browser generatedReport: self computingReportMessage.
×
NEW
507

×
508
        report := String new writeStream .
×
509
        self document.
×
510
        report close.
×
NEW
511

×
512
        browser generatedReport: report contents
×
513
]
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc