@aiready/context-analyzer 0.19.17 → 0.19.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +10 -10
- package/.turbo/turbo-lint.log +2 -22
- package/.turbo/turbo-test.log +23 -23
- package/coverage/analyzer.ts.html +1369 -0
- package/coverage/ast-utils.ts.html +382 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/classifier.ts.html +1771 -0
- package/coverage/clover.xml +1245 -0
- package/coverage/cluster-detector.ts.html +385 -0
- package/coverage/coverage-final.json +15 -0
- package/coverage/defaults.ts.html +262 -0
- package/coverage/favicon.png +0 -0
- package/coverage/graph-builder.ts.html +859 -0
- package/coverage/index.html +311 -0
- package/coverage/index.ts.html +124 -0
- package/coverage/metrics.ts.html +748 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/provider.ts.html +283 -0
- package/coverage/remediation.ts.html +502 -0
- package/coverage/scoring.ts.html +619 -0
- package/coverage/semantic-analysis.ts.html +1201 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/coverage/summary.ts.html +625 -0
- package/coverage/types.ts.html +571 -0
- package/dist/chunk-736QSHJP.mjs +1807 -0
- package/dist/chunk-CCBNKQYB.mjs +1812 -0
- package/dist/chunk-JUHHOSHG.mjs +1808 -0
- package/dist/cli.js +393 -379
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +65 -6
- package/dist/index.d.ts +65 -6
- package/dist/index.js +396 -380
- package/dist/index.mjs +3 -1
- package/package.json +2 -2
- package/src/__tests__/cluster-detector.test.ts +138 -0
- package/src/__tests__/provider.test.ts +78 -0
- package/src/__tests__/remediation.test.ts +94 -0
- package/src/analyzer.ts +244 -1
- package/src/classifier.ts +100 -35
- package/src/index.ts +1 -242
- package/src/provider.ts +2 -1
|
@@ -0,0 +1,748 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for metrics.ts</title>
|
|
7
|
+
<meta charset="utf-8" />
|
|
8
|
+
<link rel="stylesheet" href="prettify.css" />
|
|
9
|
+
<link rel="stylesheet" href="base.css" />
|
|
10
|
+
<link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
|
|
11
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
12
|
+
<style type='text/css'>
|
|
13
|
+
.coverage-summary .sorter {
|
|
14
|
+
background-image: url(sort-arrow-sprite.png);
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<div class='wrapper'>
|
|
21
|
+
<div class='pad1'>
|
|
22
|
+
<h1><a href="index.html">All files</a> metrics.ts</h1>
|
|
23
|
+
<div class='clearfix'>
|
|
24
|
+
|
|
25
|
+
<div class='fl pad1y space-right2'>
|
|
26
|
+
<span class="strong">90.67% </span>
|
|
27
|
+
<span class="quiet">Statements</span>
|
|
28
|
+
<span class='fraction'>107/118</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">68.75% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>66/96</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">100% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>11/11</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<div class='fl pad1y space-right2'>
|
|
47
|
+
<span class="strong">96.8% </span>
|
|
48
|
+
<span class="quiet">Lines</span>
|
|
49
|
+
<span class='fraction'>91/94</span>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
<p class="quiet">
|
|
55
|
+
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
56
|
+
</p>
|
|
57
|
+
<template id="filterTemplate">
|
|
58
|
+
<div class="quiet">
|
|
59
|
+
Filter:
|
|
60
|
+
<input type="search" id="fileSearch">
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
</div>
|
|
64
|
+
<div class='status-line high'></div>
|
|
65
|
+
<pre><table class="coverage">
|
|
66
|
+
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
67
|
+
<a name='L2'></a><a href='#L2'>2</a>
|
|
68
|
+
<a name='L3'></a><a href='#L3'>3</a>
|
|
69
|
+
<a name='L4'></a><a href='#L4'>4</a>
|
|
70
|
+
<a name='L5'></a><a href='#L5'>5</a>
|
|
71
|
+
<a name='L6'></a><a href='#L6'>6</a>
|
|
72
|
+
<a name='L7'></a><a href='#L7'>7</a>
|
|
73
|
+
<a name='L8'></a><a href='#L8'>8</a>
|
|
74
|
+
<a name='L9'></a><a href='#L9'>9</a>
|
|
75
|
+
<a name='L10'></a><a href='#L10'>10</a>
|
|
76
|
+
<a name='L11'></a><a href='#L11'>11</a>
|
|
77
|
+
<a name='L12'></a><a href='#L12'>12</a>
|
|
78
|
+
<a name='L13'></a><a href='#L13'>13</a>
|
|
79
|
+
<a name='L14'></a><a href='#L14'>14</a>
|
|
80
|
+
<a name='L15'></a><a href='#L15'>15</a>
|
|
81
|
+
<a name='L16'></a><a href='#L16'>16</a>
|
|
82
|
+
<a name='L17'></a><a href='#L17'>17</a>
|
|
83
|
+
<a name='L18'></a><a href='#L18'>18</a>
|
|
84
|
+
<a name='L19'></a><a href='#L19'>19</a>
|
|
85
|
+
<a name='L20'></a><a href='#L20'>20</a>
|
|
86
|
+
<a name='L21'></a><a href='#L21'>21</a>
|
|
87
|
+
<a name='L22'></a><a href='#L22'>22</a>
|
|
88
|
+
<a name='L23'></a><a href='#L23'>23</a>
|
|
89
|
+
<a name='L24'></a><a href='#L24'>24</a>
|
|
90
|
+
<a name='L25'></a><a href='#L25'>25</a>
|
|
91
|
+
<a name='L26'></a><a href='#L26'>26</a>
|
|
92
|
+
<a name='L27'></a><a href='#L27'>27</a>
|
|
93
|
+
<a name='L28'></a><a href='#L28'>28</a>
|
|
94
|
+
<a name='L29'></a><a href='#L29'>29</a>
|
|
95
|
+
<a name='L30'></a><a href='#L30'>30</a>
|
|
96
|
+
<a name='L31'></a><a href='#L31'>31</a>
|
|
97
|
+
<a name='L32'></a><a href='#L32'>32</a>
|
|
98
|
+
<a name='L33'></a><a href='#L33'>33</a>
|
|
99
|
+
<a name='L34'></a><a href='#L34'>34</a>
|
|
100
|
+
<a name='L35'></a><a href='#L35'>35</a>
|
|
101
|
+
<a name='L36'></a><a href='#L36'>36</a>
|
|
102
|
+
<a name='L37'></a><a href='#L37'>37</a>
|
|
103
|
+
<a name='L38'></a><a href='#L38'>38</a>
|
|
104
|
+
<a name='L39'></a><a href='#L39'>39</a>
|
|
105
|
+
<a name='L40'></a><a href='#L40'>40</a>
|
|
106
|
+
<a name='L41'></a><a href='#L41'>41</a>
|
|
107
|
+
<a name='L42'></a><a href='#L42'>42</a>
|
|
108
|
+
<a name='L43'></a><a href='#L43'>43</a>
|
|
109
|
+
<a name='L44'></a><a href='#L44'>44</a>
|
|
110
|
+
<a name='L45'></a><a href='#L45'>45</a>
|
|
111
|
+
<a name='L46'></a><a href='#L46'>46</a>
|
|
112
|
+
<a name='L47'></a><a href='#L47'>47</a>
|
|
113
|
+
<a name='L48'></a><a href='#L48'>48</a>
|
|
114
|
+
<a name='L49'></a><a href='#L49'>49</a>
|
|
115
|
+
<a name='L50'></a><a href='#L50'>50</a>
|
|
116
|
+
<a name='L51'></a><a href='#L51'>51</a>
|
|
117
|
+
<a name='L52'></a><a href='#L52'>52</a>
|
|
118
|
+
<a name='L53'></a><a href='#L53'>53</a>
|
|
119
|
+
<a name='L54'></a><a href='#L54'>54</a>
|
|
120
|
+
<a name='L55'></a><a href='#L55'>55</a>
|
|
121
|
+
<a name='L56'></a><a href='#L56'>56</a>
|
|
122
|
+
<a name='L57'></a><a href='#L57'>57</a>
|
|
123
|
+
<a name='L58'></a><a href='#L58'>58</a>
|
|
124
|
+
<a name='L59'></a><a href='#L59'>59</a>
|
|
125
|
+
<a name='L60'></a><a href='#L60'>60</a>
|
|
126
|
+
<a name='L61'></a><a href='#L61'>61</a>
|
|
127
|
+
<a name='L62'></a><a href='#L62'>62</a>
|
|
128
|
+
<a name='L63'></a><a href='#L63'>63</a>
|
|
129
|
+
<a name='L64'></a><a href='#L64'>64</a>
|
|
130
|
+
<a name='L65'></a><a href='#L65'>65</a>
|
|
131
|
+
<a name='L66'></a><a href='#L66'>66</a>
|
|
132
|
+
<a name='L67'></a><a href='#L67'>67</a>
|
|
133
|
+
<a name='L68'></a><a href='#L68'>68</a>
|
|
134
|
+
<a name='L69'></a><a href='#L69'>69</a>
|
|
135
|
+
<a name='L70'></a><a href='#L70'>70</a>
|
|
136
|
+
<a name='L71'></a><a href='#L71'>71</a>
|
|
137
|
+
<a name='L72'></a><a href='#L72'>72</a>
|
|
138
|
+
<a name='L73'></a><a href='#L73'>73</a>
|
|
139
|
+
<a name='L74'></a><a href='#L74'>74</a>
|
|
140
|
+
<a name='L75'></a><a href='#L75'>75</a>
|
|
141
|
+
<a name='L76'></a><a href='#L76'>76</a>
|
|
142
|
+
<a name='L77'></a><a href='#L77'>77</a>
|
|
143
|
+
<a name='L78'></a><a href='#L78'>78</a>
|
|
144
|
+
<a name='L79'></a><a href='#L79'>79</a>
|
|
145
|
+
<a name='L80'></a><a href='#L80'>80</a>
|
|
146
|
+
<a name='L81'></a><a href='#L81'>81</a>
|
|
147
|
+
<a name='L82'></a><a href='#L82'>82</a>
|
|
148
|
+
<a name='L83'></a><a href='#L83'>83</a>
|
|
149
|
+
<a name='L84'></a><a href='#L84'>84</a>
|
|
150
|
+
<a name='L85'></a><a href='#L85'>85</a>
|
|
151
|
+
<a name='L86'></a><a href='#L86'>86</a>
|
|
152
|
+
<a name='L87'></a><a href='#L87'>87</a>
|
|
153
|
+
<a name='L88'></a><a href='#L88'>88</a>
|
|
154
|
+
<a name='L89'></a><a href='#L89'>89</a>
|
|
155
|
+
<a name='L90'></a><a href='#L90'>90</a>
|
|
156
|
+
<a name='L91'></a><a href='#L91'>91</a>
|
|
157
|
+
<a name='L92'></a><a href='#L92'>92</a>
|
|
158
|
+
<a name='L93'></a><a href='#L93'>93</a>
|
|
159
|
+
<a name='L94'></a><a href='#L94'>94</a>
|
|
160
|
+
<a name='L95'></a><a href='#L95'>95</a>
|
|
161
|
+
<a name='L96'></a><a href='#L96'>96</a>
|
|
162
|
+
<a name='L97'></a><a href='#L97'>97</a>
|
|
163
|
+
<a name='L98'></a><a href='#L98'>98</a>
|
|
164
|
+
<a name='L99'></a><a href='#L99'>99</a>
|
|
165
|
+
<a name='L100'></a><a href='#L100'>100</a>
|
|
166
|
+
<a name='L101'></a><a href='#L101'>101</a>
|
|
167
|
+
<a name='L102'></a><a href='#L102'>102</a>
|
|
168
|
+
<a name='L103'></a><a href='#L103'>103</a>
|
|
169
|
+
<a name='L104'></a><a href='#L104'>104</a>
|
|
170
|
+
<a name='L105'></a><a href='#L105'>105</a>
|
|
171
|
+
<a name='L106'></a><a href='#L106'>106</a>
|
|
172
|
+
<a name='L107'></a><a href='#L107'>107</a>
|
|
173
|
+
<a name='L108'></a><a href='#L108'>108</a>
|
|
174
|
+
<a name='L109'></a><a href='#L109'>109</a>
|
|
175
|
+
<a name='L110'></a><a href='#L110'>110</a>
|
|
176
|
+
<a name='L111'></a><a href='#L111'>111</a>
|
|
177
|
+
<a name='L112'></a><a href='#L112'>112</a>
|
|
178
|
+
<a name='L113'></a><a href='#L113'>113</a>
|
|
179
|
+
<a name='L114'></a><a href='#L114'>114</a>
|
|
180
|
+
<a name='L115'></a><a href='#L115'>115</a>
|
|
181
|
+
<a name='L116'></a><a href='#L116'>116</a>
|
|
182
|
+
<a name='L117'></a><a href='#L117'>117</a>
|
|
183
|
+
<a name='L118'></a><a href='#L118'>118</a>
|
|
184
|
+
<a name='L119'></a><a href='#L119'>119</a>
|
|
185
|
+
<a name='L120'></a><a href='#L120'>120</a>
|
|
186
|
+
<a name='L121'></a><a href='#L121'>121</a>
|
|
187
|
+
<a name='L122'></a><a href='#L122'>122</a>
|
|
188
|
+
<a name='L123'></a><a href='#L123'>123</a>
|
|
189
|
+
<a name='L124'></a><a href='#L124'>124</a>
|
|
190
|
+
<a name='L125'></a><a href='#L125'>125</a>
|
|
191
|
+
<a name='L126'></a><a href='#L126'>126</a>
|
|
192
|
+
<a name='L127'></a><a href='#L127'>127</a>
|
|
193
|
+
<a name='L128'></a><a href='#L128'>128</a>
|
|
194
|
+
<a name='L129'></a><a href='#L129'>129</a>
|
|
195
|
+
<a name='L130'></a><a href='#L130'>130</a>
|
|
196
|
+
<a name='L131'></a><a href='#L131'>131</a>
|
|
197
|
+
<a name='L132'></a><a href='#L132'>132</a>
|
|
198
|
+
<a name='L133'></a><a href='#L133'>133</a>
|
|
199
|
+
<a name='L134'></a><a href='#L134'>134</a>
|
|
200
|
+
<a name='L135'></a><a href='#L135'>135</a>
|
|
201
|
+
<a name='L136'></a><a href='#L136'>136</a>
|
|
202
|
+
<a name='L137'></a><a href='#L137'>137</a>
|
|
203
|
+
<a name='L138'></a><a href='#L138'>138</a>
|
|
204
|
+
<a name='L139'></a><a href='#L139'>139</a>
|
|
205
|
+
<a name='L140'></a><a href='#L140'>140</a>
|
|
206
|
+
<a name='L141'></a><a href='#L141'>141</a>
|
|
207
|
+
<a name='L142'></a><a href='#L142'>142</a>
|
|
208
|
+
<a name='L143'></a><a href='#L143'>143</a>
|
|
209
|
+
<a name='L144'></a><a href='#L144'>144</a>
|
|
210
|
+
<a name='L145'></a><a href='#L145'>145</a>
|
|
211
|
+
<a name='L146'></a><a href='#L146'>146</a>
|
|
212
|
+
<a name='L147'></a><a href='#L147'>147</a>
|
|
213
|
+
<a name='L148'></a><a href='#L148'>148</a>
|
|
214
|
+
<a name='L149'></a><a href='#L149'>149</a>
|
|
215
|
+
<a name='L150'></a><a href='#L150'>150</a>
|
|
216
|
+
<a name='L151'></a><a href='#L151'>151</a>
|
|
217
|
+
<a name='L152'></a><a href='#L152'>152</a>
|
|
218
|
+
<a name='L153'></a><a href='#L153'>153</a>
|
|
219
|
+
<a name='L154'></a><a href='#L154'>154</a>
|
|
220
|
+
<a name='L155'></a><a href='#L155'>155</a>
|
|
221
|
+
<a name='L156'></a><a href='#L156'>156</a>
|
|
222
|
+
<a name='L157'></a><a href='#L157'>157</a>
|
|
223
|
+
<a name='L158'></a><a href='#L158'>158</a>
|
|
224
|
+
<a name='L159'></a><a href='#L159'>159</a>
|
|
225
|
+
<a name='L160'></a><a href='#L160'>160</a>
|
|
226
|
+
<a name='L161'></a><a href='#L161'>161</a>
|
|
227
|
+
<a name='L162'></a><a href='#L162'>162</a>
|
|
228
|
+
<a name='L163'></a><a href='#L163'>163</a>
|
|
229
|
+
<a name='L164'></a><a href='#L164'>164</a>
|
|
230
|
+
<a name='L165'></a><a href='#L165'>165</a>
|
|
231
|
+
<a name='L166'></a><a href='#L166'>166</a>
|
|
232
|
+
<a name='L167'></a><a href='#L167'>167</a>
|
|
233
|
+
<a name='L168'></a><a href='#L168'>168</a>
|
|
234
|
+
<a name='L169'></a><a href='#L169'>169</a>
|
|
235
|
+
<a name='L170'></a><a href='#L170'>170</a>
|
|
236
|
+
<a name='L171'></a><a href='#L171'>171</a>
|
|
237
|
+
<a name='L172'></a><a href='#L172'>172</a>
|
|
238
|
+
<a name='L173'></a><a href='#L173'>173</a>
|
|
239
|
+
<a name='L174'></a><a href='#L174'>174</a>
|
|
240
|
+
<a name='L175'></a><a href='#L175'>175</a>
|
|
241
|
+
<a name='L176'></a><a href='#L176'>176</a>
|
|
242
|
+
<a name='L177'></a><a href='#L177'>177</a>
|
|
243
|
+
<a name='L178'></a><a href='#L178'>178</a>
|
|
244
|
+
<a name='L179'></a><a href='#L179'>179</a>
|
|
245
|
+
<a name='L180'></a><a href='#L180'>180</a>
|
|
246
|
+
<a name='L181'></a><a href='#L181'>181</a>
|
|
247
|
+
<a name='L182'></a><a href='#L182'>182</a>
|
|
248
|
+
<a name='L183'></a><a href='#L183'>183</a>
|
|
249
|
+
<a name='L184'></a><a href='#L184'>184</a>
|
|
250
|
+
<a name='L185'></a><a href='#L185'>185</a>
|
|
251
|
+
<a name='L186'></a><a href='#L186'>186</a>
|
|
252
|
+
<a name='L187'></a><a href='#L187'>187</a>
|
|
253
|
+
<a name='L188'></a><a href='#L188'>188</a>
|
|
254
|
+
<a name='L189'></a><a href='#L189'>189</a>
|
|
255
|
+
<a name='L190'></a><a href='#L190'>190</a>
|
|
256
|
+
<a name='L191'></a><a href='#L191'>191</a>
|
|
257
|
+
<a name='L192'></a><a href='#L192'>192</a>
|
|
258
|
+
<a name='L193'></a><a href='#L193'>193</a>
|
|
259
|
+
<a name='L194'></a><a href='#L194'>194</a>
|
|
260
|
+
<a name='L195'></a><a href='#L195'>195</a>
|
|
261
|
+
<a name='L196'></a><a href='#L196'>196</a>
|
|
262
|
+
<a name='L197'></a><a href='#L197'>197</a>
|
|
263
|
+
<a name='L198'></a><a href='#L198'>198</a>
|
|
264
|
+
<a name='L199'></a><a href='#L199'>199</a>
|
|
265
|
+
<a name='L200'></a><a href='#L200'>200</a>
|
|
266
|
+
<a name='L201'></a><a href='#L201'>201</a>
|
|
267
|
+
<a name='L202'></a><a href='#L202'>202</a>
|
|
268
|
+
<a name='L203'></a><a href='#L203'>203</a>
|
|
269
|
+
<a name='L204'></a><a href='#L204'>204</a>
|
|
270
|
+
<a name='L205'></a><a href='#L205'>205</a>
|
|
271
|
+
<a name='L206'></a><a href='#L206'>206</a>
|
|
272
|
+
<a name='L207'></a><a href='#L207'>207</a>
|
|
273
|
+
<a name='L208'></a><a href='#L208'>208</a>
|
|
274
|
+
<a name='L209'></a><a href='#L209'>209</a>
|
|
275
|
+
<a name='L210'></a><a href='#L210'>210</a>
|
|
276
|
+
<a name='L211'></a><a href='#L211'>211</a>
|
|
277
|
+
<a name='L212'></a><a href='#L212'>212</a>
|
|
278
|
+
<a name='L213'></a><a href='#L213'>213</a>
|
|
279
|
+
<a name='L214'></a><a href='#L214'>214</a>
|
|
280
|
+
<a name='L215'></a><a href='#L215'>215</a>
|
|
281
|
+
<a name='L216'></a><a href='#L216'>216</a>
|
|
282
|
+
<a name='L217'></a><a href='#L217'>217</a>
|
|
283
|
+
<a name='L218'></a><a href='#L218'>218</a>
|
|
284
|
+
<a name='L219'></a><a href='#L219'>219</a>
|
|
285
|
+
<a name='L220'></a><a href='#L220'>220</a>
|
|
286
|
+
<a name='L221'></a><a href='#L221'>221</a>
|
|
287
|
+
<a name='L222'></a><a href='#L222'>222</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
288
|
+
<span class="cline-any cline-neutral"> </span>
|
|
289
|
+
<span class="cline-any cline-neutral"> </span>
|
|
290
|
+
<span class="cline-any cline-neutral"> </span>
|
|
291
|
+
<span class="cline-any cline-neutral"> </span>
|
|
292
|
+
<span class="cline-any cline-neutral"> </span>
|
|
293
|
+
<span class="cline-any cline-neutral"> </span>
|
|
294
|
+
<span class="cline-any cline-neutral"> </span>
|
|
295
|
+
<span class="cline-any cline-neutral"> </span>
|
|
296
|
+
<span class="cline-any cline-neutral"> </span>
|
|
297
|
+
<span class="cline-any cline-neutral"> </span>
|
|
298
|
+
<span class="cline-any cline-neutral"> </span>
|
|
299
|
+
<span class="cline-any cline-neutral"> </span>
|
|
300
|
+
<span class="cline-any cline-neutral"> </span>
|
|
301
|
+
<span class="cline-any cline-neutral"> </span>
|
|
302
|
+
<span class="cline-any cline-neutral"> </span>
|
|
303
|
+
<span class="cline-any cline-neutral"> </span>
|
|
304
|
+
<span class="cline-any cline-neutral"> </span>
|
|
305
|
+
<span class="cline-any cline-neutral"> </span>
|
|
306
|
+
<span class="cline-any cline-yes">16x</span>
|
|
307
|
+
<span class="cline-any cline-neutral"> </span>
|
|
308
|
+
<span class="cline-any cline-neutral"> </span>
|
|
309
|
+
<span class="cline-any cline-yes">4x</span>
|
|
310
|
+
<span class="cline-any cline-neutral"> </span>
|
|
311
|
+
<span class="cline-any cline-neutral"> </span>
|
|
312
|
+
<span class="cline-any cline-yes">8x</span>
|
|
313
|
+
<span class="cline-any cline-yes">4x</span>
|
|
314
|
+
<span class="cline-any cline-yes">8x</span>
|
|
315
|
+
<span class="cline-any cline-neutral"> </span>
|
|
316
|
+
<span class="cline-any cline-neutral"> </span>
|
|
317
|
+
<span class="cline-any cline-yes">4x</span>
|
|
318
|
+
<span class="cline-any cline-no"> </span>
|
|
319
|
+
<span class="cline-any cline-neutral"> </span>
|
|
320
|
+
<span class="cline-any cline-neutral"> </span>
|
|
321
|
+
<span class="cline-any cline-yes">4x</span>
|
|
322
|
+
<span class="cline-any cline-yes">8x</span>
|
|
323
|
+
<span class="cline-any cline-neutral"> </span>
|
|
324
|
+
<span class="cline-any cline-yes">4x</span>
|
|
325
|
+
<span class="cline-any cline-yes">4x</span>
|
|
326
|
+
<span class="cline-any cline-yes">8x</span>
|
|
327
|
+
<span class="cline-any cline-neutral"> </span>
|
|
328
|
+
<span class="cline-any cline-neutral"> </span>
|
|
329
|
+
<span class="cline-any cline-yes">4x</span>
|
|
330
|
+
<span class="cline-any cline-yes">4x</span>
|
|
331
|
+
<span class="cline-any cline-neutral"> </span>
|
|
332
|
+
<span class="cline-any cline-neutral"> </span>
|
|
333
|
+
<span class="cline-any cline-yes">4x</span>
|
|
334
|
+
<span class="cline-any cline-yes">4x</span>
|
|
335
|
+
<span class="cline-any cline-yes">4x</span>
|
|
336
|
+
<span class="cline-any cline-neutral"> </span>
|
|
337
|
+
<span class="cline-any cline-yes">4x</span>
|
|
338
|
+
<span class="cline-any cline-yes">8x</span>
|
|
339
|
+
<span class="cline-any cline-yes">4x</span>
|
|
340
|
+
<span class="cline-any cline-yes">4x</span>
|
|
341
|
+
<span class="cline-any cline-neutral"> </span>
|
|
342
|
+
<span class="cline-any cline-yes">4x</span>
|
|
343
|
+
<span class="cline-any cline-yes">4x</span>
|
|
344
|
+
<span class="cline-any cline-yes">4x</span>
|
|
345
|
+
<span class="cline-any cline-neutral"> </span>
|
|
346
|
+
<span class="cline-any cline-neutral"> </span>
|
|
347
|
+
<span class="cline-any cline-neutral"> </span>
|
|
348
|
+
<span class="cline-any cline-yes">4x</span>
|
|
349
|
+
<span class="cline-any cline-yes">4x</span>
|
|
350
|
+
<span class="cline-any cline-neutral"> </span>
|
|
351
|
+
<span class="cline-any cline-neutral"> </span>
|
|
352
|
+
<span class="cline-any cline-neutral"> </span>
|
|
353
|
+
<span class="cline-any cline-neutral"> </span>
|
|
354
|
+
<span class="cline-any cline-neutral"> </span>
|
|
355
|
+
<span class="cline-any cline-yes">4x</span>
|
|
356
|
+
<span class="cline-any cline-neutral"> </span>
|
|
357
|
+
<span class="cline-any cline-neutral"> </span>
|
|
358
|
+
<span class="cline-any cline-yes">16x</span>
|
|
359
|
+
<span class="cline-any cline-neutral"> </span>
|
|
360
|
+
<span class="cline-any cline-neutral"> </span>
|
|
361
|
+
<span class="cline-any cline-neutral"> </span>
|
|
362
|
+
<span class="cline-any cline-yes">16x</span>
|
|
363
|
+
<span class="cline-any cline-yes">2x</span>
|
|
364
|
+
<span class="cline-any cline-neutral"> </span>
|
|
365
|
+
<span class="cline-any cline-neutral"> </span>
|
|
366
|
+
<span class="cline-any cline-neutral"> </span>
|
|
367
|
+
<span class="cline-any cline-yes">4x</span>
|
|
368
|
+
<span class="cline-any cline-yes">4x</span>
|
|
369
|
+
<span class="cline-any cline-yes">8x</span>
|
|
370
|
+
<span class="cline-any cline-no"> </span>
|
|
371
|
+
<span class="cline-any cline-neutral"> </span>
|
|
372
|
+
<span class="cline-any cline-neutral"> </span>
|
|
373
|
+
<span class="cline-any cline-yes">4x</span>
|
|
374
|
+
<span class="cline-any cline-no"> </span>
|
|
375
|
+
<span class="cline-any cline-neutral"> </span>
|
|
376
|
+
<span class="cline-any cline-neutral"> </span>
|
|
377
|
+
<span class="cline-any cline-neutral"> </span>
|
|
378
|
+
<span class="cline-any cline-yes">4x</span>
|
|
379
|
+
<span class="cline-any cline-neutral"> </span>
|
|
380
|
+
<span class="cline-any cline-yes">4x</span>
|
|
381
|
+
<span class="cline-any cline-neutral"> </span>
|
|
382
|
+
<span class="cline-any cline-neutral"> </span>
|
|
383
|
+
<span class="cline-any cline-neutral"> </span>
|
|
384
|
+
<span class="cline-any cline-neutral"> </span>
|
|
385
|
+
<span class="cline-any cline-neutral"> </span>
|
|
386
|
+
<span class="cline-any cline-neutral"> </span>
|
|
387
|
+
<span class="cline-any cline-neutral"> </span>
|
|
388
|
+
<span class="cline-any cline-neutral"> </span>
|
|
389
|
+
<span class="cline-any cline-neutral"> </span>
|
|
390
|
+
<span class="cline-any cline-yes">4x</span>
|
|
391
|
+
<span class="cline-any cline-neutral"> </span>
|
|
392
|
+
<span class="cline-any cline-yes">3x</span>
|
|
393
|
+
<span class="cline-any cline-yes">3x</span>
|
|
394
|
+
<span class="cline-any cline-neutral"> </span>
|
|
395
|
+
<span class="cline-any cline-yes">3x</span>
|
|
396
|
+
<span class="cline-any cline-yes">5x</span>
|
|
397
|
+
<span class="cline-any cline-yes">3x</span>
|
|
398
|
+
<span class="cline-any cline-neutral"> </span>
|
|
399
|
+
<span class="cline-any cline-yes">3x</span>
|
|
400
|
+
<span class="cline-any cline-yes">3x</span>
|
|
401
|
+
<span class="cline-any cline-yes">5x</span>
|
|
402
|
+
<span class="cline-any cline-neutral"> </span>
|
|
403
|
+
<span class="cline-any cline-neutral"> </span>
|
|
404
|
+
<span class="cline-any cline-yes">3x</span>
|
|
405
|
+
<span class="cline-any cline-neutral"> </span>
|
|
406
|
+
<span class="cline-any cline-yes">2x</span>
|
|
407
|
+
<span class="cline-any cline-yes">2x</span>
|
|
408
|
+
<span class="cline-any cline-yes">4x</span>
|
|
409
|
+
<span class="cline-any cline-neutral"> </span>
|
|
410
|
+
<span class="cline-any cline-neutral"> </span>
|
|
411
|
+
<span class="cline-any cline-yes">2x</span>
|
|
412
|
+
<span class="cline-any cline-yes">2x</span>
|
|
413
|
+
<span class="cline-any cline-neutral"> </span>
|
|
414
|
+
<span class="cline-any cline-neutral"> </span>
|
|
415
|
+
<span class="cline-any cline-neutral"> </span>
|
|
416
|
+
<span class="cline-any cline-neutral"> </span>
|
|
417
|
+
<span class="cline-any cline-neutral"> </span>
|
|
418
|
+
<span class="cline-any cline-neutral"> </span>
|
|
419
|
+
<span class="cline-any cline-neutral"> </span>
|
|
420
|
+
<span class="cline-any cline-neutral"> </span>
|
|
421
|
+
<span class="cline-any cline-neutral"> </span>
|
|
422
|
+
<span class="cline-any cline-neutral"> </span>
|
|
423
|
+
<span class="cline-any cline-neutral"> </span>
|
|
424
|
+
<span class="cline-any cline-neutral"> </span>
|
|
425
|
+
<span class="cline-any cline-neutral"> </span>
|
|
426
|
+
<span class="cline-any cline-neutral"> </span>
|
|
427
|
+
<span class="cline-any cline-neutral"> </span>
|
|
428
|
+
<span class="cline-any cline-yes">14x</span>
|
|
429
|
+
<span class="cline-any cline-neutral"> </span>
|
|
430
|
+
<span class="cline-any cline-yes">11x</span>
|
|
431
|
+
<span class="cline-any cline-yes">33x</span>
|
|
432
|
+
<span class="cline-any cline-neutral"> </span>
|
|
433
|
+
<span class="cline-any cline-yes">11x</span>
|
|
434
|
+
<span class="cline-any cline-neutral"> </span>
|
|
435
|
+
<span class="cline-any cline-yes">11x</span>
|
|
436
|
+
<span class="cline-any cline-neutral"> </span>
|
|
437
|
+
<span class="cline-any cline-neutral"> </span>
|
|
438
|
+
<span class="cline-any cline-neutral"> </span>
|
|
439
|
+
<span class="cline-any cline-neutral"> </span>
|
|
440
|
+
<span class="cline-any cline-neutral"> </span>
|
|
441
|
+
<span class="cline-any cline-neutral"> </span>
|
|
442
|
+
<span class="cline-any cline-neutral"> </span>
|
|
443
|
+
<span class="cline-any cline-neutral"> </span>
|
|
444
|
+
<span class="cline-any cline-yes">14x</span>
|
|
445
|
+
<span class="cline-any cline-yes">2x</span>
|
|
446
|
+
<span class="cline-any cline-yes">2x</span>
|
|
447
|
+
<span class="cline-any cline-neutral"> </span>
|
|
448
|
+
<span class="cline-any cline-neutral"> </span>
|
|
449
|
+
<span class="cline-any cline-yes">11x</span>
|
|
450
|
+
<span class="cline-any cline-neutral"> </span>
|
|
451
|
+
<span class="cline-any cline-neutral"> </span>
|
|
452
|
+
<span class="cline-any cline-neutral"> </span>
|
|
453
|
+
<span class="cline-any cline-neutral"> </span>
|
|
454
|
+
<span class="cline-any cline-neutral"> </span>
|
|
455
|
+
<span class="cline-any cline-neutral"> </span>
|
|
456
|
+
<span class="cline-any cline-yes">2x</span>
|
|
457
|
+
<span class="cline-any cline-neutral"> </span>
|
|
458
|
+
<span class="cline-any cline-yes">2x</span>
|
|
459
|
+
<span class="cline-any cline-yes">2x</span>
|
|
460
|
+
<span class="cline-any cline-yes">15x</span>
|
|
461
|
+
<span class="cline-any cline-yes">15x</span>
|
|
462
|
+
<span class="cline-any cline-neutral"> </span>
|
|
463
|
+
<span class="cline-any cline-neutral"> </span>
|
|
464
|
+
<span class="cline-any cline-yes">2x</span>
|
|
465
|
+
<span class="cline-any cline-yes">2x</span>
|
|
466
|
+
<span class="cline-any cline-neutral"> </span>
|
|
467
|
+
<span class="cline-any cline-yes">7x</span>
|
|
468
|
+
<span class="cline-any cline-yes">2x</span>
|
|
469
|
+
<span class="cline-any cline-yes">2x</span>
|
|
470
|
+
<span class="cline-any cline-yes">7x</span>
|
|
471
|
+
<span class="cline-any cline-yes">7x</span>
|
|
472
|
+
<span class="cline-any cline-neutral"> </span>
|
|
473
|
+
<span class="cline-any cline-neutral"> </span>
|
|
474
|
+
<span class="cline-any cline-yes">2x</span>
|
|
475
|
+
<span class="cline-any cline-yes">2x</span>
|
|
476
|
+
<span class="cline-any cline-neutral"> </span>
|
|
477
|
+
<span class="cline-any cline-neutral"> </span>
|
|
478
|
+
<span class="cline-any cline-neutral"> </span>
|
|
479
|
+
<span class="cline-any cline-neutral"> </span>
|
|
480
|
+
<span class="cline-any cline-neutral"> </span>
|
|
481
|
+
<span class="cline-any cline-neutral"> </span>
|
|
482
|
+
<span class="cline-any cline-yes">2x</span>
|
|
483
|
+
<span class="cline-any cline-neutral"> </span>
|
|
484
|
+
<span class="cline-any cline-yes">12x</span>
|
|
485
|
+
<span class="cline-any cline-yes">2x</span>
|
|
486
|
+
<span class="cline-any cline-yes">6x</span>
|
|
487
|
+
<span class="cline-any cline-yes">6x</span>
|
|
488
|
+
<span class="cline-any cline-yes">10x</span>
|
|
489
|
+
<span class="cline-any cline-yes">6x</span>
|
|
490
|
+
<span class="cline-any cline-neutral"> </span>
|
|
491
|
+
<span class="cline-any cline-neutral"> </span>
|
|
492
|
+
<span class="cline-any cline-yes">2x</span>
|
|
493
|
+
<span class="cline-any cline-yes">2x</span>
|
|
494
|
+
<span class="cline-any cline-neutral"> </span>
|
|
495
|
+
<span class="cline-any cline-yes">2x</span>
|
|
496
|
+
<span class="cline-any cline-yes">6x</span>
|
|
497
|
+
<span class="cline-any cline-yes">6x</span>
|
|
498
|
+
<span class="cline-any cline-yes">6x</span>
|
|
499
|
+
<span class="cline-any cline-yes">6x</span>
|
|
500
|
+
<span class="cline-any cline-yes">6x</span>
|
|
501
|
+
<span class="cline-any cline-yes">6x</span>
|
|
502
|
+
<span class="cline-any cline-yes">6x</span>
|
|
503
|
+
<span class="cline-any cline-neutral"> </span>
|
|
504
|
+
<span class="cline-any cline-neutral"> </span>
|
|
505
|
+
<span class="cline-any cline-neutral"> </span>
|
|
506
|
+
<span class="cline-any cline-yes">2x</span>
|
|
507
|
+
<span class="cline-any cline-neutral"> </span>
|
|
508
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import { calculateImportSimilarity } from '@aiready/core';
|
|
509
|
+
import type { ExportInfo } from './types';
|
|
510
|
+
import { isTestFile } from './ast-utils';
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Calculate cohesion score (how related are exports in a file)
|
|
514
|
+
*/
|
|
515
|
+
export function calculateEnhancedCohesion(
|
|
516
|
+
exports: ExportInfo[],
|
|
517
|
+
filePath?: string,
|
|
518
|
+
options?: {
|
|
519
|
+
coUsageMatrix?: Map<string, Map<string, number>>;
|
|
520
|
+
weights?: {
|
|
521
|
+
importBased?: number;
|
|
522
|
+
structural?: number;
|
|
523
|
+
domainBased?: number;
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
): number {
|
|
527
|
+
if (exports.length <= 1) return 1;
|
|
528
|
+
|
|
529
|
+
// Test files always have perfect cohesion by design
|
|
530
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (<span class="branch-1 cbranch-no" title="branch not covered" >filePath && isTestFile(filePath)) <span class="cstat-no" title="statement not covered" >r</span>eturn 1;</span>
|
|
531
|
+
|
|
532
|
+
// 1. Domain-based cohesion using entropy
|
|
533
|
+
const domains = exports.map((e) => e.inferredDomain || <span class="branch-1 cbranch-no" title="branch not covered" >'unknown')</span>;
|
|
534
|
+
const domainCounts = new Map<string, number>();
|
|
535
|
+
for (const d of domains) domainCounts.set(d, (domainCounts.get(d) || 0) + 1);
|
|
536
|
+
|
|
537
|
+
// IF ALL DOMAINS MATCH, RETURN 1.0 IMMEDIATELY (Legacy test compatibility)
|
|
538
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (domainCounts.size === 1 && <span class="branch-1 cbranch-no" title="branch not covered" >domains[0] !== 'unknown') {</span>
|
|
539
|
+
<span class="cstat-no" title="statement not covered" > if (!options?.weights) <span class="cstat-no" title="statement not covered" >return 1;</span></span>
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
const probs = Array.from(domainCounts.values()).map(
|
|
543
|
+
(c) => c / exports.length
|
|
544
|
+
);
|
|
545
|
+
let domainEntropy = 0;
|
|
546
|
+
for (const p of probs) {
|
|
547
|
+
<span class="missing-if-branch" title="else path not taken" >E</span>if (p > 0) domainEntropy -= p * Math.log2(p);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
const maxEntropy = Math.log2(Math.max(2, domainCounts.size));
|
|
551
|
+
const domainScore = 1 - domainEntropy / maxEntropy;
|
|
552
|
+
|
|
553
|
+
// 2. Import-based cohesion
|
|
554
|
+
let importScoreTotal = 0;
|
|
555
|
+
let pairsWithData = 0;
|
|
556
|
+
let anyImportData = false;
|
|
557
|
+
|
|
558
|
+
for (let i = 0; i < exports.length; i++) {
|
|
559
|
+
for (let j = i + 1; j < exports.length; j++) {
|
|
560
|
+
const exp1Imports = exports[i].imports;
|
|
561
|
+
const exp2Imports = exports[j].imports;
|
|
562
|
+
|
|
563
|
+
<span class="missing-if-branch" title="else path not taken" >E</span>if (exp1Imports || <span class="branch-1 cbranch-no" title="branch not covered" >exp2Imports) {</span>
|
|
564
|
+
anyImportData = true;
|
|
565
|
+
const sim = calculateImportSimilarity(
|
|
566
|
+
{ ...exports[i], imports: exp1Imports || <span class="branch-1 cbranch-no" title="branch not covered" >[] }</span> as any,
|
|
567
|
+
{ ...exports[j], imports: exp2Imports || [] } as any
|
|
568
|
+
);
|
|
569
|
+
importScoreTotal += sim;
|
|
570
|
+
pairsWithData++;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
const avgImportScore =
|
|
576
|
+
pairsWithData > 0 ? importScoreTotal / pairsWithData : <span class="branch-1 cbranch-no" title="branch not covered" >0;</span>
|
|
577
|
+
|
|
578
|
+
// Weighted average
|
|
579
|
+
let score = anyImportData
|
|
580
|
+
? domainScore * 0.4 + avgImportScore * 0.6
|
|
581
|
+
: <span class="branch-1 cbranch-no" title="branch not covered" >domainScore;</span>
|
|
582
|
+
|
|
583
|
+
if (anyImportData && score === 0 && domainScore === 0) {
|
|
584
|
+
score = 0.1;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
// Structural boost
|
|
588
|
+
let structuralScore = 0;
|
|
589
|
+
for (const exp of exports) {
|
|
590
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (exp.dependencies && <span class="branch-1 cbranch-no" title="branch not covered" >exp.dependencies.length > 0) {</span>
|
|
591
|
+
<span class="cstat-no" title="statement not covered" > structuralScore += 1;</span>
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (structuralScore > 0) {
|
|
595
|
+
<span class="cstat-no" title="statement not covered" > score = Math.min(1, score + 0.1);</span>
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// Legacy fallback if no imports and domain Score was 1.0
|
|
599
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (!options?.weights && !anyImportData && <span class="branch-2 cbranch-no" title="branch not covered" >domainCounts.size === 1) <span class="cstat-no" title="statement not covered" >r</span>eturn 1;</span>
|
|
600
|
+
|
|
601
|
+
return score;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Calculate structural cohesion for a file based on co-usage patterns.
|
|
606
|
+
*/
|
|
607
|
+
export function calculateStructuralCohesionFromCoUsage(
|
|
608
|
+
file: string,
|
|
609
|
+
coUsageMatrix?: Map<string, Map<string, number>>
|
|
610
|
+
): number {
|
|
611
|
+
if (!coUsageMatrix) return 1;
|
|
612
|
+
|
|
613
|
+
const coUsages = coUsageMatrix.get(file);
|
|
614
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (!coUsages || coUsages.size === 0) <span class="cstat-no" title="statement not covered" >return 1;</span>
|
|
615
|
+
|
|
616
|
+
let total = 0;
|
|
617
|
+
for (const count of coUsages.values()) total += count;
|
|
618
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (total === 0) <span class="cstat-no" title="statement not covered" >return 1;</span>
|
|
619
|
+
|
|
620
|
+
const probs: number[] = [];
|
|
621
|
+
for (const count of coUsages.values()) {
|
|
622
|
+
<span class="missing-if-branch" title="else path not taken" >E</span>if (count > 0) probs.push(count / total);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
if (probs.length <= 1) return 1;
|
|
626
|
+
|
|
627
|
+
let entropy = 0;
|
|
628
|
+
for (const prob of probs) {
|
|
629
|
+
entropy -= prob * Math.log2(prob);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
const maxEntropy = Math.log2(probs.length);
|
|
633
|
+
return maxEntropy > 0 ? 1 - entropy / maxEntropy : <span class="branch-1 cbranch-no" title="branch not covered" >1;</span>
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Calculate fragmentation score (how scattered is a domain)
|
|
638
|
+
*/
|
|
639
|
+
export function calculateFragmentation(
|
|
640
|
+
files: string[],
|
|
641
|
+
domain: string,
|
|
642
|
+
options?: {
|
|
643
|
+
useLogScale?: boolean;
|
|
644
|
+
logBase?: number;
|
|
645
|
+
sharedImportRatio?: number;
|
|
646
|
+
dependencyCount?: number;
|
|
647
|
+
}
|
|
648
|
+
): number {
|
|
649
|
+
if (files.length <= 1) return 0;
|
|
650
|
+
|
|
651
|
+
const directories = new Set(
|
|
652
|
+
files.map((f) => f.split('/').slice(0, -1).join('/'))
|
|
653
|
+
);
|
|
654
|
+
const uniqueDirs = directories.size;
|
|
655
|
+
|
|
656
|
+
let score = options?.useLogScale
|
|
657
|
+
? uniqueDirs <= 1
|
|
658
|
+
? <span class="branch-0 cbranch-no" title="branch not covered" >0</span>
|
|
659
|
+
: Math.log(uniqueDirs) /
|
|
660
|
+
Math.log(options.logBase || Math.E) /
|
|
661
|
+
(Math.log(files.length) / Math.log(options.logBase || Math.E))
|
|
662
|
+
: (uniqueDirs - 1) / (files.length - 1);
|
|
663
|
+
|
|
664
|
+
// Coupling Discount
|
|
665
|
+
if (options?.sharedImportRatio && options.sharedImportRatio > 0.5) {
|
|
666
|
+
const discount = (options.sharedImportRatio - 0.5) * 0.4;
|
|
667
|
+
score = score * (1 - discount);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
return score;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Calculate path entropy for a set of files
|
|
675
|
+
*/
|
|
676
|
+
export function calculatePathEntropy(files: string[]): number {
|
|
677
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (!files || files.length === 0) <span class="cstat-no" title="statement not covered" >return 0;</span>
|
|
678
|
+
|
|
679
|
+
const dirCounts = new Map<string, number>();
|
|
680
|
+
for (const f of files) {
|
|
681
|
+
const dir = f.split('/').slice(0, -1).join('/') || <span class="branch-1 cbranch-no" title="branch not covered" >'.';</span>
|
|
682
|
+
dirCounts.set(dir, (dirCounts.get(dir) || 0) + 1);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
const counts = Array.from(dirCounts.values());
|
|
686
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (counts.length <= 1) <span class="cstat-no" title="statement not covered" >return 0;</span>
|
|
687
|
+
|
|
688
|
+
const total = counts.reduce((s, v) => s + v, 0);
|
|
689
|
+
let entropy = 0;
|
|
690
|
+
for (const count of counts) {
|
|
691
|
+
const prob = count / total;
|
|
692
|
+
entropy -= prob * Math.log2(prob);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
const maxEntropy = Math.log2(counts.length);
|
|
696
|
+
return maxEntropy > 0 ? entropy / maxEntropy : <span class="branch-1 cbranch-no" title="branch not covered" >0;</span>
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Calculate directory-distance metric based on common ancestor depth
|
|
701
|
+
*/
|
|
702
|
+
export function calculateDirectoryDistance(files: string[]): number {
|
|
703
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (!files || files.length <= 1) <span class="cstat-no" title="statement not covered" >return 0;</span>
|
|
704
|
+
|
|
705
|
+
const pathSegments = (p: string) => p.split('/').filter(Boolean);
|
|
706
|
+
const commonAncestorDepth = (a: string[], b: string[]) => {
|
|
707
|
+
const minLen = Math.min(a.length, b.length);
|
|
708
|
+
let i = 0;
|
|
709
|
+
while (i < minLen && a[i] === b[i]) i++;
|
|
710
|
+
return i;
|
|
711
|
+
};
|
|
712
|
+
|
|
713
|
+
let totalNormalized = 0;
|
|
714
|
+
let comparisons = 0;
|
|
715
|
+
|
|
716
|
+
for (let i = 0; i < files.length; i++) {
|
|
717
|
+
for (let j = i + 1; j < files.length; j++) {
|
|
718
|
+
const segA = pathSegments(files[i]);
|
|
719
|
+
const segB = pathSegments(files[j]);
|
|
720
|
+
const shared = commonAncestorDepth(segA, segB);
|
|
721
|
+
const maxDepth = Math.max(segA.length, segB.length);
|
|
722
|
+
totalNormalized += 1 - (maxDepth > 0 ? shared / maxDepth : <span class="branch-1 cbranch-no" title="branch not covered" >0);</span>
|
|
723
|
+
comparisons++;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
return comparisons > 0 ? totalNormalized / comparisons : <span class="branch-1 cbranch-no" title="branch not covered" >0;</span>
|
|
728
|
+
}
|
|
729
|
+
</pre></td></tr></table></pre>
|
|
730
|
+
|
|
731
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
732
|
+
</div><!-- /wrapper -->
|
|
733
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
734
|
+
Code coverage generated by
|
|
735
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
736
|
+
at 2026-03-09T02:34:18.551Z
|
|
737
|
+
</div>
|
|
738
|
+
<script src="prettify.js"></script>
|
|
739
|
+
<script>
|
|
740
|
+
window.onload = function () {
|
|
741
|
+
prettyPrint();
|
|
742
|
+
};
|
|
743
|
+
</script>
|
|
744
|
+
<script src="sorter.js"></script>
|
|
745
|
+
<script src="block-navigation.js"></script>
|
|
746
|
+
</body>
|
|
747
|
+
</html>
|
|
748
|
+
|