@lexho111/plainblog 0.6.0 → 0.6.2

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.
Files changed (36) hide show
  1. package/Blog.js +1 -6
  2. package/blog_test_empty.db +0 -0
  3. package/blog_test_load.db +0 -0
  4. package/coverage/clover.xml +638 -630
  5. package/coverage/coverage-final.json +14 -14
  6. package/coverage/lcov-report/index.html +36 -36
  7. package/coverage/lcov-report/package/Article.js.html +20 -20
  8. package/coverage/lcov-report/package/Blog.js.html +378 -339
  9. package/coverage/lcov-report/package/Formatter.js.html +2 -2
  10. package/coverage/lcov-report/package/build-scripts.js.html +1 -1
  11. package/coverage/lcov-report/package/build-styles.js.html +1 -1
  12. package/coverage/lcov-report/package/index.html +19 -19
  13. package/coverage/lcov-report/package/model/APIModel.js.html +8 -8
  14. package/coverage/lcov-report/package/model/DataModel.js.html +34 -16
  15. package/coverage/lcov-report/package/model/DatabaseModel.js.html +14 -11
  16. package/coverage/lcov-report/package/model/FileAdapter.js.html +26 -23
  17. package/coverage/lcov-report/package/model/FileModel.js.html +20 -17
  18. package/coverage/lcov-report/package/model/SequelizeAdapter.js.html +36 -36
  19. package/coverage/lcov-report/package/model/SqliteAdapter.js.html +11 -11
  20. package/coverage/lcov-report/package/model/datastructures/ArrayList.js.html +2 -2
  21. package/coverage/lcov-report/package/model/datastructures/ArrayListHashMap.js.html +1 -1
  22. package/coverage/lcov-report/package/model/datastructures/BinarySearchTree.js.html +71 -68
  23. package/coverage/lcov-report/package/model/datastructures/BinarySearchTreeHashMap.js.html +28 -19
  24. package/coverage/lcov-report/package/model/datastructures/FileList.js.html +1 -1
  25. package/coverage/lcov-report/package/model/datastructures/index.html +21 -21
  26. package/coverage/lcov-report/package/model/index.html +26 -26
  27. package/coverage/lcov-report/package/utilities.js.html +19 -19
  28. package/coverage/lcov.info +1193 -1178
  29. package/model/DataModel.js +1 -1
  30. package/model/DatabaseModel.js +1 -1
  31. package/model/FileAdapter.js +1 -1
  32. package/model/FileModel.js +1 -1
  33. package/model/datastructures/BinarySearchTree.js +1 -1
  34. package/model/datastructures/BinarySearchTreeHashMap.js +1 -1
  35. package/package.json +2 -4
  36. package/public/scripts.min.js +2 -2
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">73.24% </span>
26
+ <span class="strong">74.1% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>282/385</span>
28
+ <span class='fraction'>289/390</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">57.86% </span>
33
+ <span class="strong">58.56% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>103/178</span>
35
+ <span class='fraction'>106/181</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">86% </span>
40
+ <span class="strong">88% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>43/50</span>
42
+ <span class='fraction'>44/50</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">73.97% </span>
47
+ <span class="strong">74.86% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>270/365</span>
49
+ <span class='fraction'>277/370</span>
50
50
  </div>
51
51
 
52
52
 
@@ -913,7 +913,20 @@
913
913
  <a name='L848'></a><a href='#L848'>848</a>
914
914
  <a name='L849'></a><a href='#L849'>849</a>
915
915
  <a name='L850'></a><a href='#L850'>850</a>
916
- <a name='L851'></a><a href='#L851'>851</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
916
+ <a name='L851'></a><a href='#L851'>851</a>
917
+ <a name='L852'></a><a href='#L852'>852</a>
918
+ <a name='L853'></a><a href='#L853'>853</a>
919
+ <a name='L854'></a><a href='#L854'>854</a>
920
+ <a name='L855'></a><a href='#L855'>855</a>
921
+ <a name='L856'></a><a href='#L856'>856</a>
922
+ <a name='L857'></a><a href='#L857'>857</a>
923
+ <a name='L858'></a><a href='#L858'>858</a>
924
+ <a name='L859'></a><a href='#L859'>859</a>
925
+ <a name='L860'></a><a href='#L860'>860</a>
926
+ <a name='L861'></a><a href='#L861'>861</a>
927
+ <a name='L862'></a><a href='#L862'>862</a>
928
+ <a name='L863'></a><a href='#L863'>863</a>
929
+ <a name='L864'></a><a href='#L864'>864</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
917
930
  <span class="cline-any cline-neutral">&nbsp;</span>
918
931
  <span class="cline-any cline-neutral">&nbsp;</span>
919
932
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -938,11 +951,12 @@
938
951
  <span class="cline-any cline-neutral">&nbsp;</span>
939
952
  <span class="cline-any cline-neutral">&nbsp;</span>
940
953
  <span class="cline-any cline-neutral">&nbsp;</span>
941
- <span class="cline-any cline-yes">4x</span>
954
+ <span class="cline-any cline-neutral">&nbsp;</span>
955
+ <span class="cline-any cline-yes">5x</span>
942
956
  <span class="cline-any cline-neutral">&nbsp;</span>
943
957
  <span class="cline-any cline-neutral">&nbsp;</span>
944
958
  <span class="cline-any cline-neutral">&nbsp;</span>
945
- <span class="cline-any cline-yes">27x</span>
959
+ <span class="cline-any cline-yes">31x</span>
946
960
  <span class="cline-any cline-neutral">&nbsp;</span>
947
961
  <span class="cline-any cline-neutral">&nbsp;</span>
948
962
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -950,26 +964,26 @@
950
964
  <span class="cline-any cline-neutral">&nbsp;</span>
951
965
  <span class="cline-any cline-neutral">&nbsp;</span>
952
966
  <span class="cline-any cline-neutral">&nbsp;</span>
953
- <span class="cline-any cline-yes">27x</span>
967
+ <span class="cline-any cline-yes">31x</span>
954
968
  <span class="cline-any cline-neutral">&nbsp;</span>
955
969
  <span class="cline-any cline-neutral">&nbsp;</span>
956
970
  <span class="cline-any cline-neutral">&nbsp;</span>
957
971
  <span class="cline-any cline-neutral">&nbsp;</span>
958
972
  <span class="cline-any cline-neutral">&nbsp;</span>
959
973
  <span class="cline-any cline-neutral">&nbsp;</span>
960
- <span class="cline-any cline-yes">27x</span>
961
- <span class="cline-any cline-yes">27x</span>
962
- <span class="cline-any cline-yes">27x</span>
963
- <span class="cline-any cline-yes">27x</span>
964
- <span class="cline-any cline-yes">27x</span>
974
+ <span class="cline-any cline-yes">31x</span>
975
+ <span class="cline-any cline-yes">31x</span>
976
+ <span class="cline-any cline-yes">31x</span>
977
+ <span class="cline-any cline-yes">31x</span>
978
+ <span class="cline-any cline-yes">31x</span>
965
979
  <span class="cline-any cline-neutral">&nbsp;</span>
966
- <span class="cline-any cline-yes">27x</span>
980
+ <span class="cline-any cline-yes">31x</span>
967
981
  <span class="cline-any cline-neutral">&nbsp;</span>
968
- <span class="cline-any cline-yes">27x</span>
969
- <span class="cline-any cline-yes">27x</span>
982
+ <span class="cline-any cline-yes">31x</span>
983
+ <span class="cline-any cline-yes">31x</span>
970
984
  <span class="cline-any cline-neutral">&nbsp;</span>
971
- <span class="cline-any cline-yes">27x</span>
972
- <span class="cline-any cline-yes">27x</span>
985
+ <span class="cline-any cline-yes">31x</span>
986
+ <span class="cline-any cline-yes">31x</span>
973
987
  <span class="cline-any cline-neutral">&nbsp;</span>
974
988
  <span class="cline-any cline-neutral">&nbsp;</span>
975
989
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -998,20 +1012,20 @@
998
1012
  <span class="cline-any cline-neutral">&nbsp;</span>
999
1013
  <span class="cline-any cline-neutral">&nbsp;</span>
1000
1014
  <span class="cline-any cline-neutral">&nbsp;</span>
1001
- <span class="cline-any cline-yes">27x</span>
1002
- <span class="cline-any cline-yes">27x</span>
1003
- <span class="cline-any cline-yes">27x</span>
1015
+ <span class="cline-any cline-yes">31x</span>
1016
+ <span class="cline-any cline-yes">31x</span>
1017
+ <span class="cline-any cline-yes">31x</span>
1004
1018
  <span class="cline-any cline-neutral">&nbsp;</span>
1005
- <span class="cline-any cline-yes">27x</span>
1006
- <span class="cline-any cline-yes">27x</span>
1007
- <span class="cline-any cline-yes">27x</span>
1008
- <span class="cline-any cline-yes">27x</span>
1009
- <span class="cline-any cline-yes">27x</span>
1010
- <span class="cline-any cline-yes">27x</span>
1011
- <span class="cline-any cline-yes">27x</span>
1012
- <span class="cline-any cline-yes">27x</span>
1013
- <span class="cline-any cline-yes">27x</span>
1014
- <span class="cline-any cline-yes">27x</span>
1019
+ <span class="cline-any cline-yes">31x</span>
1020
+ <span class="cline-any cline-yes">31x</span>
1021
+ <span class="cline-any cline-yes">31x</span>
1022
+ <span class="cline-any cline-yes">31x</span>
1023
+ <span class="cline-any cline-yes">31x</span>
1024
+ <span class="cline-any cline-yes">31x</span>
1025
+ <span class="cline-any cline-yes">31x</span>
1026
+ <span class="cline-any cline-yes">31x</span>
1027
+ <span class="cline-any cline-yes">31x</span>
1028
+ <span class="cline-any cline-yes">31x</span>
1015
1029
  <span class="cline-any cline-neutral">&nbsp;</span>
1016
1030
  <span class="cline-any cline-neutral">&nbsp;</span>
1017
1031
  <span class="cline-any cline-yes">6x</span>
@@ -1026,20 +1040,20 @@
1026
1040
  <span class="cline-any cline-neutral">&nbsp;</span>
1027
1041
  <span class="cline-any cline-neutral">&nbsp;</span>
1028
1042
  <span class="cline-any cline-neutral">&nbsp;</span>
1029
- <span class="cline-any cline-yes">4x</span>
1030
- <span class="cline-any cline-yes">4x</span>
1043
+ <span class="cline-any cline-yes">5x</span>
1044
+ <span class="cline-any cline-yes">5x</span>
1031
1045
  <span class="cline-any cline-neutral">&nbsp;</span>
1032
1046
  <span class="cline-any cline-neutral">&nbsp;</span>
1033
1047
  <span class="cline-any cline-neutral">&nbsp;</span>
1034
- <span class="cline-any cline-yes">4x</span>
1048
+ <span class="cline-any cline-yes">5x</span>
1035
1049
  <span class="cline-any cline-neutral">&nbsp;</span>
1036
1050
  <span class="cline-any cline-neutral">&nbsp;</span>
1037
1051
  <span class="cline-any cline-neutral">&nbsp;</span>
1038
- <span class="cline-any cline-yes">18x</span>
1052
+ <span class="cline-any cline-yes">22x</span>
1039
1053
  <span class="cline-any cline-neutral">&nbsp;</span>
1040
1054
  <span class="cline-any cline-neutral">&nbsp;</span>
1041
1055
  <span class="cline-any cline-neutral">&nbsp;</span>
1042
- <span class="cline-any cline-yes">2x</span>
1056
+ <span class="cline-any cline-yes">3x</span>
1043
1057
  <span class="cline-any cline-neutral">&nbsp;</span>
1044
1058
  <span class="cline-any cline-neutral">&nbsp;</span>
1045
1059
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1047,13 +1061,13 @@
1047
1061
  <span class="cline-any cline-neutral">&nbsp;</span>
1048
1062
  <span class="cline-any cline-neutral">&nbsp;</span>
1049
1063
  <span class="cline-any cline-neutral">&nbsp;</span>
1050
- <span class="cline-any cline-yes">2x</span>
1051
- <span class="cline-any cline-yes">2x</span>
1052
- <span class="cline-any cline-yes">2x</span>
1053
- <span class="cline-any cline-yes">2x</span>
1064
+ <span class="cline-any cline-yes">4x</span>
1065
+ <span class="cline-any cline-yes">4x</span>
1066
+ <span class="cline-any cline-yes">4x</span>
1067
+ <span class="cline-any cline-yes">4x</span>
1054
1068
  <span class="cline-any cline-neutral">&nbsp;</span>
1055
1069
  <span class="cline-any cline-neutral">&nbsp;</span>
1056
- <span class="cline-any cline-yes">2x</span>
1070
+ <span class="cline-any cline-yes">4x</span>
1057
1071
  <span class="cline-any cline-neutral">&nbsp;</span>
1058
1072
  <span class="cline-any cline-neutral">&nbsp;</span>
1059
1073
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1061,8 +1075,8 @@
1061
1075
  <span class="cline-any cline-neutral">&nbsp;</span>
1062
1076
  <span class="cline-any cline-neutral">&nbsp;</span>
1063
1077
  <span class="cline-any cline-neutral">&nbsp;</span>
1064
- <span class="cline-any cline-no">&nbsp;</span>
1065
- <span class="cline-any cline-no">&nbsp;</span>
1078
+ <span class="cline-any cline-yes">1x</span>
1079
+ <span class="cline-any cline-yes">1x</span>
1066
1080
  <span class="cline-any cline-neutral">&nbsp;</span>
1067
1081
  <span class="cline-any cline-neutral">&nbsp;</span>
1068
1082
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1076,7 +1090,7 @@
1076
1090
  <span class="cline-any cline-neutral">&nbsp;</span>
1077
1091
  <span class="cline-any cline-neutral">&nbsp;</span>
1078
1092
  <span class="cline-any cline-neutral">&nbsp;</span>
1079
- <span class="cline-any cline-yes">155464x</span>
1093
+ <span class="cline-any cline-yes">164663x</span>
1080
1094
  <span class="cline-any cline-neutral">&nbsp;</span>
1081
1095
  <span class="cline-any cline-neutral">&nbsp;</span>
1082
1096
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1134,60 +1148,60 @@
1134
1148
  <span class="cline-any cline-neutral">&nbsp;</span>
1135
1149
  <span class="cline-any cline-neutral">&nbsp;</span>
1136
1150
  <span class="cline-any cline-neutral">&nbsp;</span>
1137
- <span class="cline-any cline-yes">23x</span>
1138
- <span class="cline-any cline-yes">21x</span>
1151
+ <span class="cline-any cline-yes">31x</span>
1152
+ <span class="cline-any cline-yes">25x</span>
1139
1153
  <span class="cline-any cline-neutral">&nbsp;</span>
1140
1154
  <span class="cline-any cline-neutral">&nbsp;</span>
1141
1155
  <span class="cline-any cline-neutral">&nbsp;</span>
1142
- <span class="cline-any cline-yes">21x</span>
1156
+ <span class="cline-any cline-yes">25x</span>
1143
1157
  <span class="cline-any cline-neutral">&nbsp;</span>
1144
- <span class="cline-any cline-yes">7x</span>
1158
+ <span class="cline-any cline-yes">9x</span>
1145
1159
  <span class="cline-any cline-neutral">&nbsp;</span>
1146
- <span class="cline-any cline-yes">21x</span>
1160
+ <span class="cline-any cline-yes">25x</span>
1147
1161
  <span class="cline-any cline-neutral">&nbsp;</span>
1148
1162
  <span class="cline-any cline-neutral">&nbsp;</span>
1149
1163
  <span class="cline-any cline-neutral">&nbsp;</span>
1150
1164
  <span class="cline-any cline-neutral">&nbsp;</span>
1151
1165
  <span class="cline-any cline-neutral">&nbsp;</span>
1152
- <span class="cline-any cline-yes">18x</span>
1153
- <span class="cline-any cline-yes">18x</span>
1154
- <span class="cline-any cline-yes">18x</span>
1155
- <span class="cline-any cline-yes">18x</span>
1166
+ <span class="cline-any cline-yes">22x</span>
1167
+ <span class="cline-any cline-yes">22x</span>
1168
+ <span class="cline-any cline-yes">22x</span>
1169
+ <span class="cline-any cline-yes">22x</span>
1156
1170
  <span class="cline-any cline-neutral">&nbsp;</span>
1157
1171
  <span class="cline-any cline-neutral">&nbsp;</span>
1158
1172
  <span class="cline-any cline-neutral">&nbsp;</span>
1159
1173
  <span class="cline-any cline-neutral">&nbsp;</span>
1160
1174
  <span class="cline-any cline-neutral">&nbsp;</span>
1161
- <span class="cline-any cline-yes">18x</span>
1162
- <span class="cline-any cline-yes">18x</span>
1175
+ <span class="cline-any cline-yes">22x</span>
1176
+ <span class="cline-any cline-yes">22x</span>
1163
1177
  <span class="cline-any cline-neutral">&nbsp;</span>
1164
- <span class="cline-any cline-yes">18x</span>
1178
+ <span class="cline-any cline-yes">22x</span>
1165
1179
  <span class="cline-any cline-neutral">&nbsp;</span>
1166
1180
  <span class="cline-any cline-neutral">&nbsp;</span>
1167
1181
  <span class="cline-any cline-neutral">&nbsp;</span>
1168
- <span class="cline-any cline-yes">15x</span>
1182
+ <span class="cline-any cline-yes">18x</span>
1169
1183
  <span class="cline-any cline-neutral">&nbsp;</span>
1170
1184
  <span class="cline-any cline-neutral">&nbsp;</span>
1171
- <span class="cline-any cline-yes">15x</span>
1185
+ <span class="cline-any cline-yes">18x</span>
1172
1186
  <span class="cline-any cline-neutral">&nbsp;</span>
1173
- <span class="cline-any cline-yes">3x</span>
1187
+ <span class="cline-any cline-yes">4x</span>
1174
1188
  <span class="cline-any cline-neutral">&nbsp;</span>
1175
1189
  <span class="cline-any cline-neutral">&nbsp;</span>
1176
1190
  <span class="cline-any cline-neutral">&nbsp;</span>
1177
- <span class="cline-any cline-yes">18x</span>
1191
+ <span class="cline-any cline-yes">22x</span>
1178
1192
  <span class="cline-any cline-neutral">&nbsp;</span>
1179
1193
  <span class="cline-any cline-neutral">&nbsp;</span>
1180
1194
  <span class="cline-any cline-no">&nbsp;</span>
1181
1195
  <span class="cline-any cline-neutral">&nbsp;</span>
1182
1196
  <span class="cline-any cline-neutral">&nbsp;</span>
1183
1197
  <span class="cline-any cline-neutral">&nbsp;</span>
1184
- <span class="cline-any cline-yes">18x</span>
1185
- <span class="cline-any cline-yes">18x</span>
1198
+ <span class="cline-any cline-yes">22x</span>
1199
+ <span class="cline-any cline-yes">22x</span>
1186
1200
  <span class="cline-any cline-neutral">&nbsp;</span>
1187
1201
  <span class="cline-any cline-neutral">&nbsp;</span>
1188
1202
  <span class="cline-any cline-neutral">&nbsp;</span>
1189
1203
  <span class="cline-any cline-neutral">&nbsp;</span>
1190
- <span class="cline-any cline-yes">18x</span>
1204
+ <span class="cline-any cline-yes">22x</span>
1191
1205
  <span class="cline-any cline-yes">4x</span>
1192
1206
  <span class="cline-any cline-yes">4x</span>
1193
1207
  <span class="cline-any cline-yes">4x</span>
@@ -1205,40 +1219,40 @@
1205
1219
  <span class="cline-any cline-neutral">&nbsp;</span>
1206
1220
  <span class="cline-any cline-neutral">&nbsp;</span>
1207
1221
  <span class="cline-any cline-neutral">&nbsp;</span>
1208
- <span class="cline-any cline-yes">21x</span>
1209
- <span class="cline-any cline-yes">21x</span>
1210
- <span class="cline-any cline-yes">21x</span>
1211
- <span class="cline-any cline-yes">21x</span>
1222
+ <span class="cline-any cline-yes">25x</span>
1223
+ <span class="cline-any cline-yes">25x</span>
1224
+ <span class="cline-any cline-yes">25x</span>
1225
+ <span class="cline-any cline-yes">25x</span>
1212
1226
  <span class="cline-any cline-neutral">&nbsp;</span>
1213
- <span class="cline-any cline-yes">21x</span>
1214
- <span class="cline-any cline-yes">1x</span>
1215
- <span class="cline-any cline-yes">1x</span>
1227
+ <span class="cline-any cline-yes">25x</span>
1228
+ <span class="cline-any cline-yes">2x</span>
1229
+ <span class="cline-any cline-yes">2x</span>
1216
1230
  <span class="cline-any cline-neutral">&nbsp;</span>
1217
- <span class="cline-any cline-yes">20x</span>
1218
- <span class="cline-any cline-yes">20x</span>
1219
- <span class="cline-any cline-yes">18x</span>
1220
- <span class="cline-any cline-yes">18x</span>
1221
- <span class="cline-any cline-yes">18x</span>
1231
+ <span class="cline-any cline-yes">23x</span>
1232
+ <span class="cline-any cline-yes">23x</span>
1233
+ <span class="cline-any cline-yes">19x</span>
1234
+ <span class="cline-any cline-yes">19x</span>
1235
+ <span class="cline-any cline-yes">19x</span>
1222
1236
  <span class="cline-any cline-neutral">&nbsp;</span>
1223
1237
  <span class="cline-any cline-neutral">&nbsp;</span>
1224
- <span class="cline-any cline-yes">20x</span>
1225
- <span class="cline-any cline-yes">20x</span>
1226
- <span class="cline-any cline-yes">20x</span>
1227
- <span class="cline-any cline-yes">20x</span>
1238
+ <span class="cline-any cline-yes">23x</span>
1239
+ <span class="cline-any cline-yes">23x</span>
1240
+ <span class="cline-any cline-yes">23x</span>
1241
+ <span class="cline-any cline-yes">23x</span>
1228
1242
  <span class="cline-any cline-neutral">&nbsp;</span>
1229
1243
  <span class="cline-any cline-neutral">&nbsp;</span>
1230
1244
  <span class="cline-any cline-neutral">&nbsp;</span>
1231
1245
  <span class="cline-any cline-neutral">&nbsp;</span>
1232
- <span class="cline-any cline-yes">20x</span>
1246
+ <span class="cline-any cline-yes">23x</span>
1233
1247
  <span class="cline-any cline-neutral">&nbsp;</span>
1234
1248
  <span class="cline-any cline-neutral">&nbsp;</span>
1235
- <span class="cline-any cline-yes">20x</span>
1249
+ <span class="cline-any cline-yes">23x</span>
1236
1250
  <span class="cline-any cline-neutral">&nbsp;</span>
1237
1251
  <span class="cline-any cline-neutral">&nbsp;</span>
1238
1252
  <span class="cline-any cline-neutral">&nbsp;</span>
1239
1253
  <span class="cline-any cline-neutral">&nbsp;</span>
1240
- <span class="cline-any cline-yes">20x</span>
1241
- <span class="cline-any cline-yes">2x</span>
1254
+ <span class="cline-any cline-yes">23x</span>
1255
+ <span class="cline-any cline-yes">4x</span>
1242
1256
  <span class="cline-any cline-neutral">&nbsp;</span>
1243
1257
  <span class="cline-any cline-neutral">&nbsp;</span>
1244
1258
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1246,7 +1260,7 @@
1246
1260
  <span class="cline-any cline-neutral">&nbsp;</span>
1247
1261
  <span class="cline-any cline-neutral">&nbsp;</span>
1248
1262
  <span class="cline-any cline-neutral">&nbsp;</span>
1249
- <span class="cline-any cline-yes">2x</span>
1263
+ <span class="cline-any cline-yes">4x</span>
1250
1264
  <span class="cline-any cline-neutral">&nbsp;</span>
1251
1265
  <span class="cline-any cline-neutral">&nbsp;</span>
1252
1266
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1255,17 +1269,17 @@
1255
1269
  <span class="cline-any cline-neutral">&nbsp;</span>
1256
1270
  <span class="cline-any cline-neutral">&nbsp;</span>
1257
1271
  <span class="cline-any cline-neutral">&nbsp;</span>
1258
- <span class="cline-any cline-yes">20x</span>
1272
+ <span class="cline-any cline-yes">23x</span>
1259
1273
  <span class="cline-any cline-no">&nbsp;</span>
1260
- <span class="cline-any cline-yes">20x</span>
1261
- <span class="cline-any cline-yes">20x</span>
1262
- <span class="cline-any cline-yes">9x</span>
1263
- <span class="cline-any cline-yes">11x</span>
1264
- <span class="cline-any cline-yes">20x</span>
1265
- <span class="cline-any cline-yes">20x</span>
1274
+ <span class="cline-any cline-yes">23x</span>
1275
+ <span class="cline-any cline-yes">23x</span>
1276
+ <span class="cline-any cline-yes">10x</span>
1277
+ <span class="cline-any cline-yes">13x</span>
1278
+ <span class="cline-any cline-yes">23x</span>
1279
+ <span class="cline-any cline-yes">23x</span>
1266
1280
  <span class="cline-any cline-neutral">&nbsp;</span>
1267
1281
  <span class="cline-any cline-neutral">&nbsp;</span>
1268
- <span class="cline-any cline-yes">21x</span>
1282
+ <span class="cline-any cline-yes">25x</span>
1269
1283
  <span class="cline-any cline-neutral">&nbsp;</span>
1270
1284
  <span class="cline-any cline-neutral">&nbsp;</span>
1271
1285
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1309,14 +1323,14 @@
1309
1323
  <span class="cline-any cline-neutral">&nbsp;</span>
1310
1324
  <span class="cline-any cline-neutral">&nbsp;</span>
1311
1325
  <span class="cline-any cline-neutral">&nbsp;</span>
1312
- <span class="cline-any cline-yes">4x</span>
1326
+ <span class="cline-any cline-yes">8x</span>
1313
1327
  <span class="cline-any cline-neutral">&nbsp;</span>
1314
- <span class="cline-any cline-yes">4x</span>
1328
+ <span class="cline-any cline-yes">8x</span>
1315
1329
  <span class="cline-any cline-neutral">&nbsp;</span>
1316
1330
  <span class="cline-any cline-neutral">&nbsp;</span>
1331
+ <span class="cline-any cline-yes">11x</span>
1332
+ <span class="cline-any cline-yes">8x</span>
1317
1333
  <span class="cline-any cline-yes">8x</span>
1318
- <span class="cline-any cline-yes">5x</span>
1319
- <span class="cline-any cline-yes">5x</span>
1320
1334
  <span class="cline-any cline-neutral">&nbsp;</span>
1321
1335
  <span class="cline-any cline-neutral">&nbsp;</span>
1322
1336
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1426,28 +1440,28 @@
1426
1440
  <span class="cline-any cline-neutral">&nbsp;</span>
1427
1441
  <span class="cline-any cline-neutral">&nbsp;</span>
1428
1442
  <span class="cline-any cline-neutral">&nbsp;</span>
1429
- <span class="cline-any cline-yes">4x</span>
1443
+ <span class="cline-any cline-yes">8x</span>
1430
1444
  <span class="cline-any cline-neutral">&nbsp;</span>
1431
- <span class="cline-any cline-yes">4x</span>
1432
- <span class="cline-any cline-yes">4x</span>
1433
- <span class="cline-any cline-yes">4x</span>
1434
- <span class="cline-any cline-yes">4x</span>
1445
+ <span class="cline-any cline-yes">8x</span>
1446
+ <span class="cline-any cline-yes">8x</span>
1447
+ <span class="cline-any cline-yes">8x</span>
1448
+ <span class="cline-any cline-yes">8x</span>
1435
1449
  <span class="cline-any cline-neutral">&nbsp;</span>
1436
- <span class="cline-any cline-yes">4x</span>
1437
- <span class="cline-any cline-yes">4x</span>
1438
- <span class="cline-any cline-yes">4x</span>
1450
+ <span class="cline-any cline-yes">8x</span>
1451
+ <span class="cline-any cline-yes">8x</span>
1452
+ <span class="cline-any cline-yes">8x</span>
1439
1453
  <span class="cline-any cline-neutral">&nbsp;</span>
1440
1454
  <span class="cline-any cline-neutral">&nbsp;</span>
1441
1455
  <span class="cline-any cline-neutral">&nbsp;</span>
1442
1456
  <span class="cline-any cline-neutral">&nbsp;</span>
1443
1457
  <span class="cline-any cline-neutral">&nbsp;</span>
1444
- <span class="cline-any cline-yes">7x</span>
1445
- <span class="cline-any cline-yes">7x</span>
1458
+ <span class="cline-any cline-yes">11x</span>
1459
+ <span class="cline-any cline-yes">11x</span>
1446
1460
  <span class="cline-any cline-neutral">&nbsp;</span>
1447
- <span class="cline-any cline-yes">4x</span>
1448
- <span class="cline-any cline-yes">4x</span>
1449
- <span class="cline-any cline-yes">4x</span>
1450
- <span class="cline-any cline-yes">4x</span>
1461
+ <span class="cline-any cline-yes">8x</span>
1462
+ <span class="cline-any cline-yes">8x</span>
1463
+ <span class="cline-any cline-yes">8x</span>
1464
+ <span class="cline-any cline-yes">8x</span>
1451
1465
  <span class="cline-any cline-neutral">&nbsp;</span>
1452
1466
  <span class="cline-any cline-neutral">&nbsp;</span>
1453
1467
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1458,56 +1472,69 @@
1458
1472
  <span class="cline-any cline-neutral">&nbsp;</span>
1459
1473
  <span class="cline-any cline-neutral">&nbsp;</span>
1460
1474
  <span class="cline-any cline-neutral">&nbsp;</span>
1461
- <span class="cline-any cline-yes">21x</span>
1462
- <span class="cline-any cline-yes">21x</span>
1463
- <span class="cline-any cline-yes">21x</span>
1475
+ <span class="cline-any cline-yes">25x</span>
1476
+ <span class="cline-any cline-yes">25x</span>
1477
+ <span class="cline-any cline-yes">25x</span>
1464
1478
  <span class="cline-any cline-neutral">&nbsp;</span>
1465
1479
  <span class="cline-any cline-neutral">&nbsp;</span>
1466
1480
  <span class="cline-any cline-neutral">&nbsp;</span>
1467
- <span class="cline-any cline-yes">21x</span>
1481
+ <span class="cline-any cline-yes">25x</span>
1468
1482
  <span class="cline-any cline-neutral">&nbsp;</span>
1469
- <span class="cline-any cline-yes">21x</span>
1470
- <span class="cline-any cline-yes">21x</span>
1471
- <span class="cline-any cline-yes">310923x</span>
1472
- <span class="cline-any cline-yes">155451x</span>
1473
- <span class="cline-any cline-yes">155451x</span>
1474
- <span class="cline-any cline-yes">155451x</span>
1483
+ <span class="cline-any cline-yes">25x</span>
1484
+ <span class="cline-any cline-yes">25x</span>
1485
+ <span class="cline-any cline-yes">24x</span>
1486
+ <span class="cline-any cline-yes">24x</span>
1487
+ <span class="cline-any cline-yes">311088x</span>
1488
+ <span class="cline-any cline-yes">155532x</span>
1489
+ <span class="cline-any cline-yes">155532x</span>
1490
+ <span class="cline-any cline-yes">155532x</span>
1475
1491
  <span class="cline-any cline-neutral">&nbsp;</span>
1476
1492
  <span class="cline-any cline-neutral">&nbsp;</span>
1477
1493
  <span class="cline-any cline-neutral">&nbsp;</span>
1478
1494
  <span class="cline-any cline-neutral">&nbsp;</span>
1479
1495
  <span class="cline-any cline-neutral">&nbsp;</span>
1480
- <span class="cline-any cline-yes">155451x</span>
1481
- <span class="cline-any cline-yes">155451x</span>
1482
- <span class="cline-any cline-yes">155451x</span>
1496
+ <span class="cline-any cline-yes">155532x</span>
1497
+ <span class="cline-any cline-yes">155532x</span>
1498
+ <span class="cline-any cline-yes">155532x</span>
1483
1499
  <span class="cline-any cline-neutral">&nbsp;</span>
1484
- <span class="cline-any cline-yes">21x</span>
1500
+ <span class="cline-any cline-yes">24x</span>
1485
1501
  <span class="cline-any cline-neutral">&nbsp;</span>
1502
+ <span class="cline-any cline-yes">1x</span>
1503
+ <span class="cline-any cline-yes">9118x</span>
1486
1504
  <span class="cline-any cline-neutral">&nbsp;</span>
1487
1505
  <span class="cline-any cline-neutral">&nbsp;</span>
1488
1506
  <span class="cline-any cline-neutral">&nbsp;</span>
1489
- <span class="cline-any cline-yes">1x</span>
1490
- <span class="cline-any cline-yes">1x</span>
1491
- <span class="cline-any cline-yes">1x</span>
1492
1507
  <span class="cline-any cline-neutral">&nbsp;</span>
1493
1508
  <span class="cline-any cline-neutral">&nbsp;</span>
1509
+ <span class="cline-any cline-yes">9118x</span>
1494
1510
  <span class="cline-any cline-neutral">&nbsp;</span>
1495
1511
  <span class="cline-any cline-neutral">&nbsp;</span>
1496
1512
  <span class="cline-any cline-neutral">&nbsp;</span>
1497
1513
  <span class="cline-any cline-neutral">&nbsp;</span>
1498
- <span class="cline-any cline-yes">5x</span>
1499
- <span class="cline-any cline-yes">5x</span>
1500
1514
  <span class="cline-any cline-neutral">&nbsp;</span>
1501
- <span class="cline-any cline-yes">5x</span>
1502
- <span class="cline-any cline-yes">3x</span>
1515
+ <span class="cline-any cline-neutral">&nbsp;</span>
1516
+ <span class="cline-any cline-yes">2x</span>
1503
1517
  <span class="cline-any cline-yes">2x</span>
1504
1518
  <span class="cline-any cline-yes">2x</span>
1505
1519
  <span class="cline-any cline-neutral">&nbsp;</span>
1506
1520
  <span class="cline-any cline-neutral">&nbsp;</span>
1507
- <span class="cline-any cline-yes">2x</span>
1508
1521
  <span class="cline-any cline-neutral">&nbsp;</span>
1509
1522
  <span class="cline-any cline-neutral">&nbsp;</span>
1510
- <span class="cline-any cline-yes">3x</span>
1523
+ <span class="cline-any cline-neutral">&nbsp;</span>
1524
+ <span class="cline-any cline-neutral">&nbsp;</span>
1525
+ <span class="cline-any cline-yes">8x</span>
1526
+ <span class="cline-any cline-yes">8x</span>
1527
+ <span class="cline-any cline-neutral">&nbsp;</span>
1528
+ <span class="cline-any cline-yes">8x</span>
1529
+ <span class="cline-any cline-yes">6x</span>
1530
+ <span class="cline-any cline-yes">5x</span>
1531
+ <span class="cline-any cline-yes">5x</span>
1532
+ <span class="cline-any cline-neutral">&nbsp;</span>
1533
+ <span class="cline-any cline-neutral">&nbsp;</span>
1534
+ <span class="cline-any cline-yes">5x</span>
1535
+ <span class="cline-any cline-neutral">&nbsp;</span>
1536
+ <span class="cline-any cline-neutral">&nbsp;</span>
1537
+ <span class="cline-any cline-yes">6x</span>
1511
1538
  <span class="cline-any cline-no">&nbsp;</span>
1512
1539
  <span class="cline-any cline-no">&nbsp;</span>
1513
1540
  <span class="cline-any cline-no">&nbsp;</span>
@@ -1515,7 +1542,7 @@
1515
1542
  <span class="cline-any cline-no">&nbsp;</span>
1516
1543
  <span class="cline-any cline-neutral">&nbsp;</span>
1517
1544
  <span class="cline-any cline-neutral">&nbsp;</span>
1518
- <span class="cline-any cline-yes">3x</span>
1545
+ <span class="cline-any cline-yes">6x</span>
1519
1546
  <span class="cline-any cline-neutral">&nbsp;</span>
1520
1547
  <span class="cline-any cline-yes">1x</span>
1521
1548
  <span class="cline-any cline-yes">1x</span>
@@ -1596,8 +1623,8 @@
1596
1623
  <span class="cline-any cline-neutral">&nbsp;</span>
1597
1624
  <span class="cline-any cline-neutral">&nbsp;</span>
1598
1625
  <span class="cline-any cline-neutral">&nbsp;</span>
1599
- <span class="cline-any cline-yes">1x</span>
1600
- <span class="cline-any cline-yes">1x</span>
1626
+ <span class="cline-any cline-yes">2x</span>
1627
+ <span class="cline-any cline-yes">2x</span>
1601
1628
  <span class="cline-any cline-neutral">&nbsp;</span>
1602
1629
  <span class="cline-any cline-neutral">&nbsp;</span>
1603
1630
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1642,22 +1669,22 @@
1642
1669
  <span class="cline-any cline-neutral">&nbsp;</span>
1643
1670
  <span class="cline-any cline-neutral">&nbsp;</span>
1644
1671
  <span class="cline-any cline-neutral">&nbsp;</span>
1645
- <span class="cline-any cline-yes">7x</span>
1672
+ <span class="cline-any cline-yes">9x</span>
1646
1673
  <span class="cline-any cline-neutral">&nbsp;</span>
1647
1674
  <span class="cline-any cline-neutral">&nbsp;</span>
1648
1675
  <span class="cline-any cline-neutral">&nbsp;</span>
1649
1676
  <span class="cline-any cline-neutral">&nbsp;</span>
1650
- <span class="cline-any cline-yes">7x</span>
1651
- <span class="cline-any cline-yes">7x</span>
1677
+ <span class="cline-any cline-yes">9x</span>
1678
+ <span class="cline-any cline-yes">9x</span>
1652
1679
  <span class="cline-any cline-neutral">&nbsp;</span>
1653
- <span class="cline-any cline-yes">6x</span>
1680
+ <span class="cline-any cline-yes">8x</span>
1654
1681
  <span class="cline-any cline-neutral">&nbsp;</span>
1655
1682
  <span class="cline-any cline-neutral">&nbsp;</span>
1656
1683
  <span class="cline-any cline-neutral">&nbsp;</span>
1657
1684
  <span class="cline-any cline-neutral">&nbsp;</span>
1658
1685
  <span class="cline-any cline-neutral">&nbsp;</span>
1659
1686
  <span class="cline-any cline-neutral">&nbsp;</span>
1660
- <span class="cline-any cline-yes">7x</span>
1687
+ <span class="cline-any cline-yes">9x</span>
1661
1688
  <span class="cline-any cline-neutral">&nbsp;</span>
1662
1689
  <span class="cline-any cline-yes">2x</span>
1663
1690
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1707,47 +1734,47 @@
1707
1734
  <span class="cline-any cline-neutral">&nbsp;</span>
1708
1735
  <span class="cline-any cline-neutral">&nbsp;</span>
1709
1736
  <span class="cline-any cline-neutral">&nbsp;</span>
1710
- <span class="cline-any cline-yes">21x</span>
1711
- <span class="cline-any cline-yes">21x</span>
1737
+ <span class="cline-any cline-yes">25x</span>
1738
+ <span class="cline-any cline-yes">25x</span>
1712
1739
  <span class="cline-any cline-neutral">&nbsp;</span>
1713
- <span class="cline-any cline-yes">21x</span>
1740
+ <span class="cline-any cline-yes">25x</span>
1714
1741
  <span class="cline-any cline-neutral">&nbsp;</span>
1715
1742
  <span class="cline-any cline-neutral">&nbsp;</span>
1716
- <span class="cline-any cline-yes">21x</span>
1717
- <span class="cline-any cline-yes">21x</span>
1743
+ <span class="cline-any cline-yes">25x</span>
1744
+ <span class="cline-any cline-yes">25x</span>
1718
1745
  <span class="cline-any cline-neutral">&nbsp;</span>
1719
- <span class="cline-any cline-yes">21x</span>
1720
- <span class="cline-any cline-yes">21x</span>
1721
- <span class="cline-any cline-yes">21x</span>
1746
+ <span class="cline-any cline-yes">25x</span>
1747
+ <span class="cline-any cline-yes">25x</span>
1748
+ <span class="cline-any cline-yes">25x</span>
1722
1749
  <span class="cline-any cline-neutral">&nbsp;</span>
1723
1750
  <span class="cline-any cline-neutral">&nbsp;</span>
1724
1751
  <span class="cline-any cline-neutral">&nbsp;</span>
1725
- <span class="cline-any cline-yes">21x</span>
1752
+ <span class="cline-any cline-yes">25x</span>
1726
1753
  <span class="cline-any cline-neutral">&nbsp;</span>
1727
1754
  <span class="cline-any cline-neutral">&nbsp;</span>
1728
1755
  <span class="cline-any cline-neutral">&nbsp;</span>
1729
1756
  <span class="cline-any cline-neutral">&nbsp;</span>
1730
- <span class="cline-any cline-yes">21x</span>
1757
+ <span class="cline-any cline-yes">25x</span>
1731
1758
  <span class="cline-any cline-neutral">&nbsp;</span>
1732
1759
  <span class="cline-any cline-neutral">&nbsp;</span>
1733
1760
  <span class="cline-any cline-neutral">&nbsp;</span>
1734
1761
  <span class="cline-any cline-neutral">&nbsp;</span>
1735
1762
  <span class="cline-any cline-neutral">&nbsp;</span>
1736
- <span class="cline-any cline-yes">21x</span>
1737
- <span class="cline-any cline-yes">21x</span>
1738
- <span class="cline-any cline-yes">21x</span>
1739
- <span class="cline-any cline-yes">21x</span>
1763
+ <span class="cline-any cline-yes">25x</span>
1764
+ <span class="cline-any cline-yes">25x</span>
1765
+ <span class="cline-any cline-yes">25x</span>
1766
+ <span class="cline-any cline-yes">25x</span>
1740
1767
  <span class="cline-any cline-neutral">&nbsp;</span>
1741
1768
  <span class="cline-any cline-neutral">&nbsp;</span>
1742
1769
  <span class="cline-any cline-neutral">&nbsp;</span>
1743
- <span class="cline-any cline-yes">21x</span>
1744
- <span class="cline-any cline-yes">21x</span>
1770
+ <span class="cline-any cline-yes">25x</span>
1771
+ <span class="cline-any cline-yes">25x</span>
1745
1772
  <span class="cline-any cline-neutral">&nbsp;</span>
1746
1773
  <span class="cline-any cline-neutral">&nbsp;</span>
1747
1774
  <span class="cline-any cline-neutral">&nbsp;</span>
1748
1775
  <span class="cline-any cline-neutral">&nbsp;</span>
1749
1776
  <span class="cline-any cline-neutral">&nbsp;</span>
1750
- <span class="cline-any cline-yes">21x</span>
1777
+ <span class="cline-any cline-yes">25x</span>
1751
1778
  <span class="cline-any cline-no">&nbsp;</span>
1752
1779
  <span class="cline-any cline-no">&nbsp;</span>
1753
1780
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1762,7 +1789,6 @@
1762
1789
  <span class="cline-any cline-neutral">&nbsp;</span>
1763
1790
  <span class="cline-any cline-neutral">&nbsp;</span>
1764
1791
  <span class="cline-any cline-neutral">&nbsp;</span>
1765
- <span class="cline-any cline-neutral">&nbsp;</span>
1766
1792
  <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import http from "http";
1767
1793
  import crypto from "node:crypto";
1768
1794
  import fs from "fs";
@@ -1771,7 +1797,7 @@ import process from "node:process";
1771
1797
  import path from "path";
1772
1798
  import { fileURLToPath } from "url";
1773
1799
  import pkg from "./package.json" with { type: "json" };
1774
- import createDebug from "debug";
1800
+ import { debuglog as createDebug } from "node:util";
1775
1801
  import Article from "./Article.js";
1776
1802
  import DatabaseModel from "./model/DatabaseModel.js";
1777
1803
  import { fetchData, postData } from "./model/APIModel.js";
@@ -1867,9 +1893,9 @@ export default class Blog {
1867
1893
  this.#title = title;
1868
1894
  }
1869
1895
  &nbsp;
1870
- <span class="fstat-no" title="function not covered" > se</span>tPassword(password) {
1871
- <span class="cstat-no" title="statement not covered" > this.#password = password;</span>
1872
- }
1896
+ setPassword(password) {
1897
+ <span class="fstat-no" title="function not covered" ></span> this.#password = password;
1898
+ }<span class="cstat-no" title="statement not covered" ></span>
1873
1899
  &nbsp;
1874
1900
  /**
1875
1901
  * Appends CSS rules to the \&lt;style\&gt;-tag.
@@ -1897,9 +1923,9 @@ export default class Blog {
1897
1923
  * @param {*} adapter a database adapter like PostgresAdapter or SqliteAdapter
1898
1924
  */
1899
1925
  setDatabaseAdapter(adapter) {
1900
- <span class="missing-if-branch" title="else path not taken" >E</span>if (!this.#databaseModel) {
1901
- <span class="missing-if-branch" title="else path not taken" >E</span>if (this.database.type === "file") {
1902
- const adapter = new FileAdapter(this.database);
1926
+ if (!this.#databaseModel) {
1927
+ <span class="missing-if-branch" title="else path not taken" >E</span> if (this.database.type === "file") {
1928
+ <span class="missing-if-branch" title="else path not taken" >E</span> const adapter = new FileAdapter(this.database);
1903
1929
  this.#databaseModel = new DatabaseModel(adapter);
1904
1930
  }
1905
1931
  }
@@ -1910,9 +1936,9 @@ export default class Blog {
1910
1936
  * Appends CSS rules to the \&lt;style\&gt;-tag.
1911
1937
  * @param {string} style - A string containing CSS rules.
1912
1938
  */
1913
- <span class="fstat-no" title="function not covered" > se</span>t style(style) {
1914
- <span class="cstat-no" title="statement not covered" > this.#styles += style;</span>
1915
- <span class="cstat-no" title="statement not covered" > this.compilestyle = true;</span>
1939
+ set style(style) {
1940
+ this.#styles += style;
1941
+ this.compilestyle = true;
1916
1942
  }
1917
1943
  &nbsp;
1918
1944
  /**
@@ -1953,10 +1979,10 @@ export default class Blog {
1953
1979
  Location: "/",
1954
1980
  });
1955
1981
  res.end();
1956
- } else <span class="missing-if-branch" title="else path not taken" >E</span>{
1957
- <span class="cstat-no" title="statement not covered" > res.writeHead(401, { "Content-Type": "text/html" });</span>
1982
+ } else {
1983
+ res.w<span class="missing-if-branch" title="else path not taken" >E</span>riteHead(401, { "Content-Type": "text/html" });
1958
1984
  <span class="cstat-no" title="statement not covered" > res.end(`${header("My Blog")}</span>
1959
- &lt;body&gt;
1985
+ &lt;body&gt;<span class="cstat-no" title="statement not covered" ></span>
1960
1986
  &lt;h1&gt;Unauthorized&lt;/h1&gt;&lt;div class="box"&gt;&lt;p&gt;Please enter the password.&lt;form method="POST"&gt;
1961
1987
  &lt;input type="password" name="password" placeholder="Password" /&gt;
1962
1988
  &lt;button style="margin: 2px;"&gt;Login&lt;/button&gt;&lt;/form&gt;&lt;/div&gt;
@@ -1965,22 +1991,22 @@ export default class Blog {
1965
1991
  }
1966
1992
  &nbsp;
1967
1993
  #handleLogout(req, res) {
1968
- <span class="cstat-no" title="statement not covered" > debug("handle logout");</span>
1969
- <span class="cstat-no" title="statement not covered" > if (req.headers.cookie) {</span>
1970
- const params = <span class="cstat-no" title="statement not covered" >new URLSearchParams(</span>
1971
- req.headers.cookie.replace(/; /g, "&amp;"),
1994
+ debug("handle logout");
1995
+ <span class="cstat-no" title="statement not covered" > if (req.headers.cookie) </span>{
1996
+ <span class="cstat-no" title="statement not covered" > const params = new URLSearchParams(</span>
1997
+ req.headers.c<span class="cstat-no" title="statement not covered" >ookie.replace(/; /g, "&amp;"),</span>
1972
1998
  );
1973
- const sessionId = <span class="cstat-no" title="statement not covered" >params.get("session");</span>
1974
- <span class="cstat-no" title="statement not covered" > if (this.sessions.has(sessionId)) {</span>
1999
+ const sessionId = params.get("session");
2000
+ if (this.sessions.<span class="cstat-no" title="statement not covered" >has(sessionId)) {</span>
1975
2001
  <span class="cstat-no" title="statement not covered" > this.sessions.delete(sessionId);</span>
1976
- }
2002
+ }<span class="cstat-no" title="statement not covered" ></span>
1977
2003
  }
1978
- <span class="cstat-no" title="statement not covered" > res.writeHead(303, {</span>
1979
- "Set-Cookie": "session=; HttpOnly; Path=/; Max-Age=0",
2004
+ res.writeHead(303, {
2005
+ <span class="cstat-no" title="statement not covered" > "Set-Cookie": "session=; HttpOnly; Path=/; Max-Age=0",</span>
1980
2006
  Location: "/",
1981
2007
  });
1982
- <span class="cstat-no" title="statement not covered" > res.end();</span>
1983
- }
2008
+ res.end();
2009
+ }<span class="cstat-no" title="statement not covered" ></span>
1984
2010
  &nbsp;
1985
2011
  /** initializes database */
1986
2012
  async init() {
@@ -2018,17 +2044,17 @@ export default class Blog {
2018
2044
  const match = publicCSS.match(
2019
2045
  /\/\* source-hash: ([a-f0-9]{64}) \*\//,
2020
2046
  );
2021
- <span class="missing-if-branch" title="else path not taken" >E</span>if (match) publicHash = match[1];
2022
- })
2047
+ if (match) publicHash = match[1];
2048
+ })<span class="missing-if-branch" title="else path not taken" >E</span>
2023
2049
  .catch((err) =&gt; console.error(err)), // public/styles.min.css doesn't exist, will be created.
2024
2050
  fs.promises
2025
2051
  .readFile(srcStylePath, "utf8")
2026
2052
  .then((content) =&gt; {
2027
2053
  srcStyles = content;
2028
2054
  })
2029
- .catch(<span class="fstat-no" title="function not covered" >(e</span>rr) =&gt; {
2030
- <span class="cstat-no" title="statement not covered" > if (err.code !== "ENOENT") <span class="cstat-no" title="statement not covered" >console.error(err);</span></span>
2031
- }), // ignore if src/styles.css doesn't exist
2055
+ .catch((err) =&gt; {
2056
+ if (e<span class="fstat-no" title="function not covered" >rr</span>.code !== "ENOENT") console.error(err);
2057
+ })<span class="cstat-no" title="statement not covered" >, // ignore if src/styles.c<span class="cstat-no" title="statement not covered" >ss doesn't exist</span></span>
2032
2058
  ]);
2033
2059
  &nbsp;
2034
2060
  const combinedStyles = this.#styles + srcStyles;
@@ -2049,8 +2075,8 @@ export default class Blog {
2049
2075
  finalStyles + `\n/* source-hash: ${srcHash} */`,
2050
2076
  );
2051
2077
  } catch (err) {
2052
- <span class="cstat-no" title="statement not covered" > console.error("Failed to write styles to public folder:", err);</span>
2053
- }
2078
+ console.error("Failed to write styles to public folder:", err);
2079
+ }<span class="cstat-no" title="statement not covered" ></span>
2054
2080
  }
2055
2081
  }
2056
2082
  &nbsp;
@@ -2066,8 +2092,8 @@ export default class Blog {
2066
2092
  } else {
2067
2093
  console.log(`database: ${this.database.type}`);
2068
2094
  if (!this.#databaseModel) {
2069
- <span class="missing-if-branch" title="else path not taken" >E</span>if (this.database.type === "file") {
2070
- const adapter = new FileAdapter(this.database);
2095
+ if (this.database.type === "file") {
2096
+ <span class="missing-if-branch" title="else path not taken" >E</span> const adapter = new FileAdapter(this.database);
2071
2097
  this.#databaseModel = new DatabaseModel(adapter);
2072
2098
  }
2073
2099
  }
@@ -2105,9 +2131,9 @@ export default class Blog {
2105
2131
  ),
2106
2132
  );
2107
2133
  }
2108
- <span class="missing-if-branch" title="if path not taken" >I</span>if (this.reloadStylesOnGET)
2109
- <span class="cstat-no" title="statement not covered" > console.log("reload scripts and styles on GET-Request");</span>
2110
- let title = "";
2134
+ if (this.reloadStylesOnGET)
2135
+ <span class="missing-if-branch" title="if path not taken" >I</span> console.log("reload scripts and styles on GET-Request");
2136
+ le<span class="cstat-no" title="statement not covered" >t title = "";</span>
2111
2137
  if (this.#title != null &amp;&amp; this.#title.length &gt; 0)
2112
2138
  title = this.#title; // use blog title if set
2113
2139
  else title = dbTitle; // use title from the database
@@ -2132,8 +2158,8 @@ export default class Blog {
2132
2158
  const title = params.get("title");
2133
2159
  const content = params.get("content");
2134
2160
  &nbsp;
2135
- <span class="missing-if-branch" title="else path not taken" >E</span>if (title &amp;&amp; content) {
2136
- const newArticleData = { title, content };
2161
+ if (title &amp;&amp; content) {
2162
+ <span class="missing-if-branch" title="else path not taken" >E</span> const newArticleData = { title, content };
2137
2163
  try {
2138
2164
  // Save the new article to the database via the ApiServer
2139
2165
  const promises = [];
@@ -2148,8 +2174,8 @@ export default class Blog {
2148
2174
  this.#articles.remove(1); // "Sample Entry #1"
2149
2175
  this.#articles.remove(2); // "Sample Entry #2"
2150
2176
  } catch (error) {
2151
- <span class="cstat-no" title="statement not covered" > console.error("Failed to post new article to API:", error);</span>
2152
- }
2177
+ console.error("Failed to post new article to API:", error);
2178
+ }<span class="cstat-no" title="statement not covered" ></span>
2153
2179
  }
2154
2180
  &nbsp;
2155
2181
  res.writeHead(303, { Location: "/" });
@@ -2158,8 +2184,8 @@ export default class Blog {
2158
2184
  }
2159
2185
  &nbsp;
2160
2186
  /** start a http server with default port 8080 */
2161
- async startServer(port = <span class="branch-0 cbranch-no" title="branch not covered" >8080)</span> {
2162
- await this.init();
2187
+ async startServer(port = 8080) {
2188
+ await this.init();<span class="branch-0 cbranch-no" title="branch not covered" ></span>
2163
2189
  &nbsp;
2164
2190
  const server = http.createServer(async (req, res) =&gt; {
2165
2191
  //debug("query %s", req.url);
@@ -2171,82 +2197,82 @@ export default class Blog {
2171
2197
  &nbsp;
2172
2198
  // Web Page Routes
2173
2199
  if (req.url === "/login") {
2174
- <span class="missing-if-branch" title="if path not taken" >I</span>if (req.method === "GET") {
2175
- <span class="cstat-no" title="statement not covered" > res.writeHead(200, { "Content-Type": "text/html" });</span>
2200
+ if (req.method === "GET") {
2201
+ <span class="missing-if-branch" title="if path not taken" >I</span> res.writeHead(200, { "Content-Type": "text/html" });
2176
2202
  <span class="cstat-no" title="statement not covered" > res.end(`${header("My Blog")}</span>
2177
- &lt;body&gt;
2203
+ &lt;body&gt;<span class="cstat-no" title="statement not covered" ></span>
2178
2204
  &lt;h1&gt;Login&lt;/h1&gt;&lt;div class="box"&gt;&lt;form method="POST"&gt;
2179
2205
  &lt;input type="password" name="password" placeholder="Password" /&gt;
2180
2206
  &lt;button style="margin: 2px;"&gt;Login&lt;/button&gt;&lt;/form&gt;&lt;/div&gt;
2181
2207
  &lt;/body&gt;&lt;/html&gt;`);
2182
- <span class="cstat-no" title="statement not covered" > return;</span>
2183
- } else <span class="missing-if-branch" title="else path not taken" >E</span>if (req.method === "POST") {
2184
- await this.#handleLogin(req, res);
2208
+ return;
2209
+ } <span class="cstat-no" title="statement not covered" >else if </span>(req.method === "POST") {
2210
+ await<span class="missing-if-branch" title="else path not taken" >E</span> this.#handleLogin(req, res);
2185
2211
  return;
2186
2212
  }
2187
2213
  }
2188
2214
  &nbsp;
2189
- <span class="missing-if-branch" title="if path not taken" >I</span>if (req.url === "/logout") {
2190
- <span class="cstat-no" title="statement not covered" > this.#handleLogout(req, res);</span>
2215
+ if (req.url === "/logout") {
2216
+ <span class="missing-if-branch" title="if path not taken" >I</span> this.#handleLogout(req, res);
2191
2217
  <span class="cstat-no" title="statement not covered" > return;</span>
2192
- }
2218
+ }<span class="cstat-no" title="statement not covered" ></span>
2193
2219
  // POST new article
2194
- <span class="missing-if-branch" title="if path not taken" >I</span>if (req.method === "POST" &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >req.url === "/")</span> {
2195
- <span class="cstat-no" title="statement not covered" > if (!this.#isAuthenticated(req)) {</span>
2220
+ if (req.method === "POST" &amp;&amp; req.url === "/") {
2221
+ <span class="missing-if-branch" title="if path not taken" >I</span> if (!this.#isAuthenticated(<span class="branch-1 cbranch-no" title="branch not covered" >req)) {</span>
2196
2222
  <span class="cstat-no" title="statement not covered" > res.writeHead(403, { "Content-Type": "text/plain" });</span>
2197
2223
  <span class="cstat-no" title="statement not covered" > res.end("Forbidden");</span>
2198
2224
  <span class="cstat-no" title="statement not covered" > return;</span>
2199
- }
2200
- <span class="cstat-no" title="statement not covered" > await this.postArticle(req, res);</span>
2201
- // GET artciles
2225
+ }<span class="cstat-no" title="statement not covered" ></span>
2226
+ await this.postArticle(req, res);
2227
+ <span class="cstat-no" title="statement not covered" > // GET artciles</span>
2202
2228
  } else if (req.method === "GET" &amp;&amp; req.url === "/") {
2203
2229
  // load articles
2204
2230
  &nbsp;
2205
2231
  // reload styles and scripts on (every) request
2206
- <span class="missing-if-branch" title="if path not taken" >I</span>if (this.reloadStylesOnGET) {
2207
- <span class="cstat-no" title="statement not covered" > if (this.#stylesheetPath != null &amp;&amp; this.compilestyle) {</span>
2232
+ if (this.reloadStylesOnGET) {
2233
+ <span class="missing-if-branch" title="if path not taken" >I</span> if (this.#stylesheetPath != null &amp;&amp; this.compilestyle) {
2208
2234
  <span class="cstat-no" title="statement not covered" > await this.#processStylesheets(this.#stylesheetPath);</span>
2209
- }
2210
- const __filename = <span class="cstat-no" title="statement not covered" >fileURLToPath(import.meta.url);</span>
2211
- const __dirname = <span class="cstat-no" title="statement not covered" >path.dirname(__filename);</span>
2212
- const srcScriptPath = <span class="cstat-no" title="statement not covered" >path.join(__dirname, "src", "fetchData.js");</span>
2213
- <span class="cstat-no" title="statement not covered" > await this.#processScripts(srcScriptPath);</span>
2214
- }
2235
+ }<span class="cstat-no" title="statement not covered" ></span>
2236
+ const __filename = fileURLToPath(import.meta.url);
2237
+ const __dirname = p<span class="cstat-no" title="statement not covered" >ath.dirname(__filename);</span>
2238
+ const srcScriptPat<span class="cstat-no" title="statement not covered" >h = path.join(__dirname, </span>"src", "fetchData.js");
2239
+ await this.#processScr<span class="cstat-no" title="statement not covered" >ipts(srcScriptPath);</span>
2240
+ }<span class="cstat-no" title="statement not covered" ></span>
2215
2241
  &nbsp;
2216
2242
  let loggedin = false;
2217
2243
  if (!this.#isAuthenticated(req)) {
2218
2244
  // login
2219
2245
  loggedin = false;
2220
- } else <span class="missing-if-branch" title="else path not taken" >E</span>{
2221
- // logout
2222
- <span class="cstat-no" title="statement not covered" > loggedin = true;</span>
2223
- }
2246
+ } else {
2247
+ // lo<span class="missing-if-branch" title="else path not taken" >E</span>gout
2248
+ loggedin = true;
2249
+ }<span class="cstat-no" title="statement not covered" ></span>
2224
2250
  &nbsp;
2225
2251
  try {
2226
2252
  const html = await this.toHTML(loggedin); // render this blog to HTML
2227
2253
  res.writeHead(200, { "Content-Type": "text/html; charset=UTF-8" });
2228
2254
  res.end(html);
2229
2255
  } catch (err) {
2230
- <span class="cstat-no" title="statement not covered" > console.error(err);</span>
2231
- <span class="cstat-no" title="statement not covered" > res.writeHead(500, { "Content-Type": "text/plain" });</span>
2256
+ console.error(err);
2257
+ <span class="cstat-no" title="statement not covered" > res.writeHead(500, {</span> "Content-Type": "text/plain" });
2232
2258
  <span class="cstat-no" title="statement not covered" > res.end("Internal Server Error");</span>
2233
- }
2234
- } else <span class="missing-if-branch" title="else path not taken" >E</span>{
2235
- // Try to serve static files from public folder
2236
- <span class="cstat-no" title="statement not covered" > try {</span>
2237
- const publicDir = <span class="cstat-no" title="statement not covered" >path.join(process.cwd(), "public");</span>
2259
+ }<span class="cstat-no" title="statement not covered" ></span>
2260
+ } else {
2261
+ // Tr<span class="missing-if-branch" title="else path not taken" >E</span>y to serve static files from public folder
2262
+ try {
2263
+ <span class="cstat-no" title="statement not covered" > const publicDir = path.join(process.cwd(), "public");</span>
2238
2264
  const parsedUrl = <span class="cstat-no" title="statement not covered" >new URL(</span>
2239
- req.url,
2265
+ req.url,<span class="cstat-no" title="statement not covered" ></span>
2240
2266
  `http://${req.headers.host || "localhost"}`,
2241
2267
  );
2242
- const filePath = <span class="cstat-no" title="statement not covered" >path.join(publicDir, parsedUrl.pathname);</span>
2243
- &nbsp;
2244
- <span class="cstat-no" title="statement not covered" > if (filePath.startsWith(publicDir)) {</span>
2245
- const stats = <span class="cstat-no" title="statement not covered" >await fs.promises.stat(filePath);</span>
2246
- <span class="cstat-no" title="statement not covered" > if (stats.isFile()) {</span>
2247
- const ext = <span class="cstat-no" title="statement not covered" >path.extname(filePath).toLowerCase();</span>
2248
- const mimeTypes = <span class="cstat-no" title="statement not covered" >{</span>
2249
- ".html": "text/html",
2268
+ const filePath = path.join(publicDir, parsedUrl.pathname);
2269
+ <span class="cstat-no" title="statement not covered" ></span>
2270
+ if (filePath.startsWith(publicDir)) {
2271
+ <span class="cstat-no" title="statement not covered" > const stats = await fs.promises.stat(filePath);</span>
2272
+ if (stats.isFi<span class="cstat-no" title="statement not covered" >le()) {</span>
2273
+ <span class="cstat-no" title="statement not covered" > const ext = path.extname(filePath).toLowerCase();</span>
2274
+ const mimeTy<span class="cstat-no" title="statement not covered" >pes = {</span>
2275
+ ".html": "text/h<span class="cstat-no" title="statement not covered" >tml",</span>
2250
2276
  ".js": "text/javascript",
2251
2277
  ".css": "text/css",
2252
2278
  ".json": "application/json",
@@ -2256,31 +2282,31 @@ export default class Blog {
2256
2282
  ".svg": "image/svg+xml",
2257
2283
  ".ico": "image/x-icon",
2258
2284
  };
2259
- const contentType = <span class="cstat-no" title="statement not covered" >mimeTypes[ext] || "application/octet-stream";</span>
2260
- <span class="cstat-no" title="statement not covered" > res.writeHead(200, { "Content-Type": contentType });</span>
2285
+ const contentType = mimeTypes[ext] || "application/octet-stream";
2286
+ res.writeHead(200, {<span class="cstat-no" title="statement not covered" > "Content-Type": contentType });</span>
2261
2287
  <span class="cstat-no" title="statement not covered" > fs.createReadStream(filePath).pipe(res);</span>
2262
2288
  <span class="cstat-no" title="statement not covered" > return;</span>
2263
- }
2289
+ }<span class="cstat-no" title="statement not covered" ></span>
2264
2290
  }
2265
2291
  } catch (err) {
2266
2292
  // ENOENT (file not found) is expected, leading to a 404.
2267
2293
  // Only log other, unexpected errors.
2268
- <span class="cstat-no" title="statement not covered" > if (err.code !== "ENOENT") {</span>
2294
+ if (err.code !== "ENOENT") {
2269
2295
  <span class="cstat-no" title="statement not covered" > console.error(err);</span>
2270
- }
2296
+ }<span class="cstat-no" title="statement not covered" ></span>
2271
2297
  }
2272
2298
  &nbsp;
2273
2299
  // Error 404
2274
- <span class="cstat-no" title="statement not covered" > res.writeHead(404, { "Content-Type": "application/json" });</span>
2300
+ res.writeHead(404, { "Content-Type": "application/json" });
2275
2301
  <span class="cstat-no" title="statement not covered" > res.end(JSON.stringify({ message: "Not Found" }));</span>
2276
- }
2302
+ }<span class="cstat-no" title="statement not covered" ></span>
2277
2303
  });
2278
2304
  &nbsp;
2279
2305
  this.#server = server;
2280
2306
  &nbsp;
2281
2307
  return new Promise((resolve, reject) =&gt; {
2282
- const errorHandler = <span class="fstat-no" title="function not covered" >(e</span>rr) =&gt; <span class="cstat-no" title="statement not covered" >reject(err);</span>
2283
- this.#server.once("error", errorHandler);
2308
+ const errorHandler = (err) =&gt; reject(err);
2309
+ this.#server.once("er<span class="fstat-no" title="function not covered" >ro</span>r", err<span class="cstat-no" title="statement not covered" >orHandler);</span>
2284
2310
  this.#server.listen(port, "0.0.0.0", () =&gt; {
2285
2311
  // &lt;-- for docker 0.0.0.0, localhost 127.0.0.1
2286
2312
  this.#server.removeListener("error", errorHandler);
@@ -2295,8 +2321,8 @@ export default class Blog {
2295
2321
  if (this.#server) {
2296
2322
  // if server is running
2297
2323
  this.#server.close((err) =&gt; {
2298
- <span class="missing-if-branch" title="if path not taken" >I</span>if (err &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >err.code !== "ERR_SERVER_NOT_RUNNING")</span> <span class="cstat-no" title="statement not covered" >return reject(err);</span>
2299
- console.log("Server closed.");
2324
+ if (err &amp;&amp; err.code !== "ERR_SERVER_NOT_RUNNING") return reject(err);
2325
+ <span class="missing-if-branch" title="if path not taken" >I</span>console.log<span class="branch-1 cbranch-no" title="branch not covered" >("Server closed.");<span class="cstat-no" title="statement not covered" ></span></span>
2300
2326
  resolve();
2301
2327
  });
2302
2328
  } else {
@@ -2311,42 +2337,55 @@ export default class Blog {
2311
2337
  debug("applyBlogData");
2312
2338
  if (this.#articles.storage.clear) {
2313
2339
  this.#articles.storage.clear();
2314
- } else <span class="missing-if-branch" title="else path not taken" >E</span>{
2315
- //this.#articles.setDataModel(this.#makeDataModel()); // Fallback if clear() isn't implemented
2340
+ } else {
2341
+ //thi<span class="missing-if-branch" title="else path not taken" >E</span>s.#articles.setDataModel(this.#makeDataModel()); // Fallback if clear() isn't implemented
2316
2342
  }
2317
2343
  this.#title = data.title;
2318
2344
  // Assuming data contains a title and an array of articles with title and content
2319
- <span class="missing-if-branch" title="else path not taken" >E</span>if (data.articles &amp;&amp; Array.isArray(data.articles)) {
2320
- const insertBalanced = (start, end) =&gt; {
2321
- if (start &gt; end) return;
2322
- const mid = Math.floor((start + end) / 2);
2323
- const articleData = data.articles[mid];
2324
- const article = new Article(
2325
- articleData.id,
2326
- articleData.title,
2327
- articleData.content,
2328
- articleData.createdAt,
2329
- );
2330
- this.addArticle(article);
2331
- insertBalanced(start, mid - 1);
2332
- insertBalanced(mid + 1, end);
2333
- };
2334
- insertBalanced(0, data.articles.length - 1);
2345
+ if (this.#articles &amp;&amp; data.articles &amp;&amp; Array.isArray(data.articles)) {
2346
+ <span class="missing-if-branch" title="else path not taken" >E</span> if (this.#articles.getStorageName().includes("BinarySearchTree")) {
2347
+ debug("using special insert method for BST");
2348
+ const insertBalanced = (start, end) =&gt; {
2349
+ if (start &gt; end) return;
2350
+ const mid = Math.floor((start + end) / 2);
2351
+ const articleData = data.articles[mid];
2352
+ const article = new Article(
2353
+ articleData.id,
2354
+ articleData.title,
2355
+ articleData.content,
2356
+ articleData.createdAt,
2357
+ );
2358
+ this.addArticle(article);
2359
+ insertBalanced(start, mid - 1);
2360
+ insertBalanced(mid + 1, end);
2361
+ };
2362
+ insertBalanced(0, data.articles.length - 1);
2363
+ } else {
2364
+ for (const articleData of data.articles) {
2365
+ const article = new Article(
2366
+ articleData.id,
2367
+ articleData.title,
2368
+ articleData.content,
2369
+ articleData.createdAt,
2370
+ );
2371
+ this.addArticle(article);
2372
+ }
2373
+ }
2335
2374
  }
2336
2375
  }
2337
2376
  &nbsp;
2338
2377
  async #loadFromAPI() {
2339
2378
  const data = await fetchData(this.#apiUrl);
2340
- <span class="missing-if-branch" title="else path not taken" >E</span>if (data) {
2341
- this.#applyBlogData(data);
2379
+ if (data) {
2380
+ <span class="missing-if-branch" title="else path not taken" >E</span> this.#applyBlogData(data);
2342
2381
  }
2343
2382
  }
2344
2383
  &nbsp;
2345
2384
  // controller
2346
2385
  /** everything that happens in /api */
2347
2386
  async #jsonAPI(req, res) {
2348
- const url = new URL(req.url, `http://${req.headers.host || <span class="branch-1 cbranch-no" title="branch not covered" >"localhost"}</span>`);
2349
- const pathname = url.pathname;
2387
+ const url = new URL(req.url, `http://${req.headers.host || "localhost"}`);
2388
+ const pathname = url.pathname;<span class="branch-1 cbranch-no" title="branch not covered" ></span>
2350
2389
  &nbsp;
2351
2390
  if (req.method === "GET") {
2352
2391
  if (pathname === "/api" || pathname === "/api/") {
@@ -2357,19 +2396,19 @@ export default class Blog {
2357
2396
  res.end(JSON.stringify(data));
2358
2397
  }
2359
2398
  // Search
2360
- <span class="missing-if-branch" title="if path not taken" >I</span>if (url.searchParams.has("q")) {
2361
- const query = <span class="cstat-no" title="statement not covered" >url.searchParams.get("q");</span>
2362
- <span class="cstat-no" title="statement not covered" > res.writeHead(200, { "Content-Type": "application/json" });</span>
2363
- const results = <span class="cstat-no" title="statement not covered" >this.#articles.search(query);</span>
2364
- <span class="cstat-no" title="statement not covered" > res.end(JSON.stringify({ articles: results }));</span>
2399
+ if (url.searchParams.has("q")) {
2400
+ <span class="missing-if-branch" title="if path not taken" >I</span> const query = url.searchParams.get("q");
2401
+ res.writeHead(<span class="cstat-no" title="statement not covered" >200, { "Content-Type": "ap</span>plication/json" });
2402
+ <span class="cstat-no" title="statement not covered" > const results = this.#articles.search(query);</span>
2403
+ res.end(JSON.str<span class="cstat-no" title="statement not covered" >ingify({ articles: results })</span>);
2365
2404
  <span class="cstat-no" title="statement not covered" > return;</span>
2366
- }
2405
+ }<span class="cstat-no" title="statement not covered" ></span>
2367
2406
  // GET all blog data
2368
2407
  if (pathname === "/api/articles") {
2369
2408
  // Use 'offset' param as startId (filter) to get items starting at ID
2370
2409
  const pLimit = parseInt(url.searchParams.get("limit"));
2371
- const limit = !isNaN(pLimit) ? <span class="branch-0 cbranch-no" title="branch not covered" >pLimit </span>: null;
2372
- &nbsp;
2410
+ const limit = !isNaN(pLimit) ? pLimit : null;
2411
+ <span class="branch-0 cbranch-no" title="branch not covered" ></span>
2373
2412
  const start = url.searchParams.get("startdate");
2374
2413
  const end = url.searchParams.get("enddate");
2375
2414
  //const parsedStart = parseDateParam(qStartdate);
@@ -2407,41 +2446,41 @@ export default class Blog {
2407
2446
  // extern
2408
2447
  res.writeHead(201, { "Content-Type": "application/json" });
2409
2448
  res.end(JSON.stringify(newArticle));
2410
- } else <span class="cstat-no" title="statement not covered" ><span class="missing-if-branch" title="else path not taken" >E</span>if (req.method === "DELETE" &amp;&amp; pathname === "/api/articles") {</span>
2411
- <span class="cstat-no" title="statement not covered" > if (!this.#isAuthenticated(req)) {</span>
2449
+ } else if (req.method === "DELETE" &amp;&amp; pathname === "/api/articles") {
2450
+ if (!<span class="cstat-no" title="statement not covered" ><span class="missing-if-branch" title="else path not taken" >E</span>this.#isAuthenticated(req)) {</span>
2412
2451
  <span class="cstat-no" title="statement not covered" > res.writeHead(403, { "Content-Type": "application/json" });</span>
2413
2452
  <span class="cstat-no" title="statement not covered" > res.end(JSON.stringify({ error: "Forbidden" }));</span>
2414
2453
  <span class="cstat-no" title="statement not covered" > return;</span>
2415
- }
2416
- const id = <span class="cstat-no" title="statement not covered" >url.searchParams.get("id");</span>
2417
- <span class="cstat-no" title="statement not covered" > if (id) {</span>
2454
+ }<span class="cstat-no" title="statement not covered" ></span>
2455
+ const id = url.searchParams.get("id");
2456
+ if (id) {<span class="cstat-no" title="statement not covered" ></span>
2418
2457
  <span class="cstat-no" title="statement not covered" > this.#articles.remove(parseInt(id));</span>
2419
2458
  <span class="cstat-no" title="statement not covered" > if (this.#databaseModel) {</span>
2420
2459
  <span class="cstat-no" title="statement not covered" > await this.#databaseModel.remove(parseInt(id));</span>
2421
- }
2422
- <span class="cstat-no" title="statement not covered" > res.writeHead(200, { "Content-Type": "application/json" });</span>
2460
+ }<span class="cstat-no" title="statement not covered" ></span>
2461
+ res.writeHead(200, { "Content-Type": "application/json" });
2423
2462
  <span class="cstat-no" title="statement not covered" > res.end(JSON.stringify({ status: "deleted", id }));</span>
2424
- }
2425
- } else <span class="cstat-no" title="statement not covered" >if (req.method === "PUT" &amp;&amp; pathname === "/api/articles") {</span>
2426
- <span class="cstat-no" title="statement not covered" > if (!this.#isAuthenticated(req)) {</span>
2463
+ }<span class="cstat-no" title="statement not covered" ></span>
2464
+ } else if (req.method === "PUT" &amp;&amp; pathname === "/api/articles") {
2465
+ if (!<span class="cstat-no" title="statement not covered" >this.#isAuthenticated(req)) {</span>
2427
2466
  <span class="cstat-no" title="statement not covered" > res.writeHead(403, { "Content-Type": "application/json" });</span>
2428
2467
  <span class="cstat-no" title="statement not covered" > res.end(JSON.stringify({ error: "Forbidden" }));</span>
2429
2468
  <span class="cstat-no" title="statement not covered" > return;</span>
2430
- }
2431
- const id = <span class="cstat-no" title="statement not covered" >url.searchParams.get("id");</span>
2432
- const body = <span class="cstat-no" title="statement not covered" >await new Promise(<span class="fstat-no" title="function not covered" >(r</span>esolve) =&gt; {</span>
2433
- let data = <span class="cstat-no" title="statement not covered" >"";</span>
2434
- <span class="cstat-no" title="statement not covered" > req.on("data", <span class="fstat-no" title="function not covered" >(c</span>hunk) =&gt; (<span class="cstat-no" title="statement not covered" >data += chunk)</span>);</span>
2435
- <span class="cstat-no" title="statement not covered" > req.on("end", <span class="fstat-no" title="function not covered" >()</span> =&gt; <span class="cstat-no" title="statement not covered" >resolve(data))</span>;</span>
2436
- });
2437
- const { title, content } = <span class="cstat-no" title="statement not covered" >JSON.parse(body);</span>
2438
- <span class="cstat-no" title="statement not covered" > this.#articles.update(parseInt(id), title, content);</span>
2469
+ }<span class="cstat-no" title="statement not covered" ></span>
2470
+ const id = url.searchParams.get("id");
2471
+ const body <span class="cstat-no" title="statement not covered" >= await new Promise((resolv</span>e) =&gt; {
2472
+ let data = <span class="cstat-no" title="statement not covered" >"";<span class="fstat-no" title="function not covered" ></span></span>
2473
+ req.on("dat<span class="cstat-no" title="statement not covered" >a",</span> (chunk) =&gt; (data += chunk));
2474
+ <span class="cstat-no" title="statement not covered" > req.on("end", (<span class="fstat-no" title="function not covered" >) </span>=&gt; resolve<span class="cstat-no" title="statement not covered" >(data));</span></span>
2475
+ })<span class="cstat-no" title="statement not covered" >;<span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ></span></span></span>
2476
+ const { title, content } = JSON.parse(body);
2477
+ this.#articles.update(parse<span class="cstat-no" title="statement not covered" >Int(id), title, c</span>ontent);
2439
2478
  <span class="cstat-no" title="statement not covered" > if (this.#databaseModel) {</span>
2440
2479
  <span class="cstat-no" title="statement not covered" > await this.#databaseModel.update(parseInt(id), { title, content });</span>
2441
- }
2442
- <span class="cstat-no" title="statement not covered" > res.writeHead(200, { "Content-Type": "application/json" });</span>
2480
+ }<span class="cstat-no" title="statement not covered" ></span>
2481
+ res.writeHead(200, { "Content-Type": "application/json" });
2443
2482
  <span class="cstat-no" title="statement not covered" > res.end(JSON.stringify({ status: "updated", id }));</span>
2444
- }
2483
+ }<span class="cstat-no" title="statement not covered" ></span>
2445
2484
  }
2446
2485
  &nbsp;
2447
2486
  /** set external API */
@@ -2473,8 +2512,8 @@ export default class Blog {
2473
2512
  login: "",
2474
2513
  };
2475
2514
  &nbsp;
2476
- <span class="missing-if-branch" title="if path not taken" >I</span>if (loggedin) <span class="cstat-no" title="statement not covered" >data.login = `&lt;a href="/logout"&gt;logout&lt;/a&gt;`;</span>
2477
- else data.login = `&lt;a href="/login"&gt;login&lt;/a&gt;`;
2515
+ if (loggedin) data.login = `&lt;a href="/logout"&gt;logout&lt;/a&gt;`;
2516
+ <span class="missing-if-branch" title="if path not taken" >I</span>else data.logi<span class="cstat-no" title="statement not covered" >n = `&lt;a href="/login"&gt;login&lt;/a&gt;`;</span>
2478
2517
  &nbsp;
2479
2518
  //debug("typeof data: %o", typeof data);
2480
2519
  //debug("typeof data.articles: %o", typeof data.articles);
@@ -2483,9 +2522,9 @@ export default class Blog {
2483
2522
  debug("first article: ");
2484
2523
  debug("%d %s %s", article.id, article.title, article.getContentVeryShort());
2485
2524
  const html = formatHTML(data);
2486
- <span class="missing-if-branch" title="else path not taken" >E</span>if (validate(html)) return html;
2487
- <span class="cstat-no" title="statement not covered" > throw new Error("Error. Invalid HTML!");</span>
2488
- }
2525
+ if (validate(html)) return html;
2526
+ <span class="missing-if-branch" title="else path not taken" >E</span>throw new Error("Error. Invalid HTML!");
2527
+ }<span class="cstat-no" title="statement not covered" ></span>
2489
2528
  &nbsp;
2490
2529
  /**
2491
2530
  * read files, compare checksums, compile and write to public/styles.min.css
@@ -2512,8 +2551,8 @@ export default class Blog {
2512
2551
  const fileData = await Promise.all(
2513
2552
  styleFiles.sort().map(async (f) =&gt; {
2514
2553
  const content = await fs.promises.readFile(f, "utf-8");
2515
- <span class="missing-if-branch" title="if path not taken" >I</span>if (content == "") <span class="cstat-no" title="statement not covered" >throw new Error("Invalid Filepath or empty file!");</span>
2516
- return { path: f, content };
2554
+ if (content == "") throw new Error("Invalid Filepath or empty file!");
2555
+ <span class="missing-if-branch" title="if path not taken" >I</span>return { path: f, c<span class="cstat-no" title="statement not covered" >ontent };</span>
2517
2556
  }),
2518
2557
  );
2519
2558
  &nbsp;
@@ -2545,9 +2584,9 @@ export default class Blog {
2545
2584
  path.join(publicDir, "styles.min.css"),
2546
2585
  this.compiledStyles + `\n/* source-hash: ${currentHash} */`,
2547
2586
  );
2548
- } else <span class="missing-if-branch" title="else path not taken" >E</span>{
2549
- <span class="cstat-no" title="statement not covered" > console.log("styles are up-to-date");</span>
2550
- }
2587
+ } else {
2588
+ conso<span class="missing-if-branch" title="else path not taken" >E</span>le.log("styles are up-to-date");
2589
+ }<span class="cstat-no" title="statement not covered" ></span>
2551
2590
  }
2552
2591
  }
2553
2592
  &nbsp;
@@ -2557,18 +2596,18 @@ export default class Blog {
2557
2596
  */
2558
2597
  async #processScripts(files) {
2559
2598
  // Normalize input to array
2560
- const fileList = Array.isArray(files) ? <span class="branch-0 cbranch-no" title="branch not covered" >files </span>: [files];
2561
- const scriptFiles = fileList.filter(
2599
+ const fileList = Array.isArray(files) ? files : [files];
2600
+ const scriptFiles = fileList.filter(<span class="branch-0 cbranch-no" title="branch not covered" ></span>
2562
2601
  (f) =&gt;
2563
2602
  typeof f === "string" &amp;&amp; f.endsWith(".js") &amp;&amp; !f.endsWith(".min.js"),
2564
2603
  );
2565
2604
  &nbsp;
2566
- <span class="missing-if-branch" title="else path not taken" >E</span>if (scriptFiles.length &gt; 0) {
2567
- const fileData = await Promise.all(
2605
+ if (scriptFiles.length &gt; 0) {
2606
+ <span class="missing-if-branch" title="else path not taken" >E</span> const fileData = await Promise.all(
2568
2607
  scriptFiles.map(async (f) =&gt; {
2569
2608
  const content = await fs.promises.readFile(f, "utf-8");
2570
- <span class="missing-if-branch" title="if path not taken" >I</span>if (content == "") <span class="cstat-no" title="statement not covered" >throw new Error("Invalid Filepath or empty file!");</span>
2571
- return { path: f, content };
2609
+ if (content == "") throw new Error("Invalid Filepath or empty file!");
2610
+ <span class="missing-if-branch" title="if path not taken" >I</span>return { path: f, c<span class="cstat-no" title="statement not covered" >ontent };</span>
2572
2611
  }),
2573
2612
  );
2574
2613
  &nbsp;
@@ -2583,30 +2622,30 @@ export default class Blog {
2583
2622
  )
2584
2623
  .digest("hex");
2585
2624
  &nbsp;
2586
- <span class="missing-if-branch" title="else path not taken" >E</span>if (!this.#scriptsHash) {
2587
- try {
2625
+ if (!this.#scriptsHash) {
2626
+ <span class="missing-if-branch" title="else path not taken" >E</span> try {
2588
2627
  const publicDir = path.join(process.cwd(), "public");
2589
2628
  const existing = await fs.promises.readFile(
2590
2629
  path.join(publicDir, "scripts.min.js"),
2591
2630
  "utf-8",
2592
2631
  );
2593
2632
  const match = existing.match(/\/\* source-hash: ([a-f0-9]{64}) \*\//);
2594
- <span class="missing-if-branch" title="else path not taken" >E</span>if (match) this.#scriptsHash = match[1];
2595
- } catch (err) {
2633
+ if (match) this.#scriptsHash = match[1];
2634
+ } <span class="missing-if-branch" title="else path not taken" >E</span>catch (err) {
2596
2635
  // ignore
2597
2636
  }
2598
2637
  }
2599
2638
  &nbsp;
2600
- <span class="missing-if-branch" title="if path not taken" >I</span>if (currentHash !== this.#scriptsHash) {
2601
- <span class="cstat-no" title="statement not covered" > console.log("Script assets have changed. Recompiling...");</span>
2639
+ if (currentHash !== this.#scriptsHash) {
2640
+ <span class="missing-if-branch" title="if path not taken" >I</span> console.log("Script assets have changed. Recompiling...");
2602
2641
  <span class="cstat-no" title="statement not covered" > this.#scriptsHash = currentHash;</span>
2603
- &nbsp;
2604
- const compiledScripts = <span class="cstat-no" title="statement not covered" >await compileScripts(fileData);</span>
2605
- &nbsp;
2606
- const publicDir = <span class="cstat-no" title="statement not covered" >path.join(process.cwd(), "public");</span>
2607
- <span class="cstat-no" title="statement not covered" > await fs.promises.mkdir(publicDir, { recursive: true });</span>
2642
+ <span class="cstat-no" title="statement not covered" ></span>
2643
+ const compiledScripts = await compileScripts(fileData);
2644
+ <span class="cstat-no" title="statement not covered" ></span>
2645
+ const publicDir = path.join(process.cwd(), "public");
2646
+ await fs.promises.<span class="cstat-no" title="statement not covered" >mkdir(publicDir, { recursive: true </span>});
2608
2647
  <span class="cstat-no" title="statement not covered" > await fs.promises.writeFile(</span>
2609
- path.join(publicDir, "scripts.min.js"),
2648
+ <span class="cstat-no" title="statement not covered" > path.join(publicDir, "scripts.min.js"),</span>
2610
2649
  compiledScripts + `\n/* source-hash: ${currentHash} */`,
2611
2650
  );
2612
2651
  }
@@ -2620,7 +2659,7 @@ export default class Blog {
2620
2659
  <div class='footer quiet pad2 space-top1 center small'>
2621
2660
  Code coverage generated by
2622
2661
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
2623
- at 2026-01-17T17:30:57.244Z
2662
+ at 2026-01-18T09:48:57.520Z
2624
2663
  </div>
2625
2664
  <script src="../prettify.js"></script>
2626
2665
  <script>