@platformos/platformos-check-common 0.0.7 → 0.0.9

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 (337) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +4 -4
  3. package/dist/AugmentedPlatformOSDocset.d.ts +11 -0
  4. package/dist/AugmentedPlatformOSDocset.js +81 -0
  5. package/dist/AugmentedPlatformOSDocset.js.map +1 -0
  6. package/dist/JSONValidator.js +1 -1
  7. package/dist/JSONValidator.js.map +1 -1
  8. package/dist/checks/deprecated-filter/index.js +4 -41
  9. package/dist/checks/deprecated-filter/index.js.map +1 -1
  10. package/dist/checks/deprecated-tag/index.js +21 -22
  11. package/dist/checks/deprecated-tag/index.js.map +1 -1
  12. package/dist/checks/duplicate-function-arguments/index.js +1 -1
  13. package/dist/checks/duplicate-function-arguments/index.js.map +1 -1
  14. package/dist/checks/duplicate-render-partial-arguments/index.js +1 -1
  15. package/dist/checks/duplicate-render-partial-arguments/index.js.map +1 -1
  16. package/dist/checks/graphql/index.js +1 -1
  17. package/dist/checks/graphql/index.js.map +1 -1
  18. package/dist/checks/graphql-variables/index.js +4 -0
  19. package/dist/checks/graphql-variables/index.js.map +1 -1
  20. package/dist/checks/img-width-and-height/index.js +1 -1
  21. package/dist/checks/img-width-and-height/index.js.map +1 -1
  22. package/dist/checks/index.d.ts +3 -3
  23. package/dist/checks/index.js +4 -79
  24. package/dist/checks/index.js.map +1 -1
  25. package/dist/checks/json-syntax-error/index.js +1 -1
  26. package/dist/checks/json-syntax-error/index.js.map +1 -1
  27. package/dist/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.js +1 -1
  28. package/dist/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.js.map +1 -1
  29. package/dist/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.d.ts +19 -0
  30. package/dist/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.js +79 -0
  31. package/dist/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.js.map +1 -0
  32. package/dist/checks/liquid-html-syntax-error/checks/UnknownTag.d.ts +3 -0
  33. package/dist/checks/liquid-html-syntax-error/checks/UnknownTag.js +32 -0
  34. package/dist/checks/liquid-html-syntax-error/checks/UnknownTag.js.map +1 -0
  35. package/dist/checks/liquid-html-syntax-error/index.js +23 -5
  36. package/dist/checks/liquid-html-syntax-error/index.js.map +1 -1
  37. package/dist/checks/matching-translations/index.d.ts +2 -2
  38. package/dist/checks/matching-translations/index.js +114 -90
  39. package/dist/checks/matching-translations/index.js.map +1 -1
  40. package/dist/checks/metadata-params/index.js +6 -3
  41. package/dist/checks/metadata-params/index.js.map +1 -1
  42. package/dist/checks/missing-asset/index.js +1 -1
  43. package/dist/checks/missing-asset/index.js.map +1 -1
  44. package/dist/checks/missing-partial/index.d.ts +6 -0
  45. package/dist/checks/missing-partial/index.js +70 -0
  46. package/dist/checks/missing-partial/index.js.map +1 -0
  47. package/dist/checks/orphaned-partial/index.js +4 -4
  48. package/dist/checks/orphaned-partial/index.js.map +1 -1
  49. package/dist/checks/parser-blocking-script/index.js +10 -36
  50. package/dist/checks/parser-blocking-script/index.js.map +1 -1
  51. package/dist/checks/parser-blocking-script/suggestions.d.ts +1 -2
  52. package/dist/checks/parser-blocking-script/suggestions.js +1 -11
  53. package/dist/checks/parser-blocking-script/suggestions.js.map +1 -1
  54. package/dist/checks/reserved-doc-param-names/index.js +6 -5
  55. package/dist/checks/reserved-doc-param-names/index.js.map +1 -1
  56. package/dist/checks/translation-key-exists/index.js +1 -1
  57. package/dist/checks/translation-key-exists/index.js.map +1 -1
  58. package/dist/checks/unclosed-html-element/index.js +5 -1
  59. package/dist/checks/unclosed-html-element/index.js.map +1 -1
  60. package/dist/checks/undefined-object/index.js +13 -31
  61. package/dist/checks/undefined-object/index.js.map +1 -1
  62. package/dist/checks/unique-doc-param-names/index.js +1 -1
  63. package/dist/checks/unique-doc-param-names/index.js.map +1 -1
  64. package/dist/checks/unknown-filter/index.js +3 -3
  65. package/dist/checks/unknown-filter/index.js.map +1 -1
  66. package/dist/checks/unknown-property/index.js +1 -1
  67. package/dist/checks/unknown-property/index.js.map +1 -1
  68. package/dist/checks/unrecognized-render-partial-arguments/index.js +2 -2
  69. package/dist/checks/unrecognized-render-partial-arguments/index.js.map +1 -1
  70. package/dist/checks/unused-assign/index.js +1 -1
  71. package/dist/checks/unused-assign/index.js.map +1 -1
  72. package/dist/checks/unused-doc-param/index.js +1 -1
  73. package/dist/checks/unused-doc-param/index.js.map +1 -1
  74. package/dist/checks/utils.js +1 -1
  75. package/dist/checks/utils.js.map +1 -1
  76. package/dist/checks/valid-content-for-arguments/index.js +1 -1
  77. package/dist/checks/valid-content-for-arguments/index.js.map +1 -1
  78. package/dist/checks/valid-doc-param-types/index.js +4 -4
  79. package/dist/checks/valid-doc-param-types/index.js.map +1 -1
  80. package/dist/checks/valid-html-translation/index.d.ts +2 -2
  81. package/dist/checks/valid-html-translation/index.js +4 -4
  82. package/dist/checks/valid-html-translation/index.js.map +1 -1
  83. package/dist/checks/valid-json/index.js +1 -1
  84. package/dist/checks/valid-json/index.js.map +1 -1
  85. package/dist/checks/valid-render-partial-argument-types/index.js +2 -2
  86. package/dist/checks/valid-render-partial-argument-types/index.js.map +1 -1
  87. package/dist/checks/variable-name/index.js +1 -1
  88. package/dist/checks/variable-name/index.js.map +1 -1
  89. package/dist/context-utils.d.ts +18 -7
  90. package/dist/context-utils.js +68 -109
  91. package/dist/context-utils.js.map +1 -1
  92. package/dist/disabled-checks/index.js +4 -2
  93. package/dist/disabled-checks/index.js.map +1 -1
  94. package/dist/doc-generator/DocBlockGenerator.d.ts +16 -0
  95. package/dist/doc-generator/DocBlockGenerator.js +464 -0
  96. package/dist/doc-generator/DocBlockGenerator.js.map +1 -0
  97. package/dist/doc-generator/index.d.ts +1 -0
  98. package/dist/doc-generator/index.js +6 -0
  99. package/dist/doc-generator/index.js.map +1 -0
  100. package/dist/find-root.d.ts +7 -10
  101. package/dist/find-root.js +10 -17
  102. package/dist/find-root.js.map +1 -1
  103. package/dist/fixes/autofix.d.ts +4 -4
  104. package/dist/fixes/autofix.js +2 -2
  105. package/dist/fixes/autofix.js.map +1 -1
  106. package/dist/fixes/correctors/index.js +4 -0
  107. package/dist/fixes/correctors/index.js.map +1 -1
  108. package/dist/index.d.ts +5 -5
  109. package/dist/index.js +50 -17
  110. package/dist/index.js.map +1 -1
  111. package/dist/jsonc/parse.d.ts +1 -1
  112. package/dist/jsonc/parse.js +1 -1
  113. package/dist/liquid-doc/arguments.d.ts +7 -8
  114. package/dist/liquid-doc/arguments.js +28 -29
  115. package/dist/liquid-doc/arguments.js.map +1 -1
  116. package/dist/liquid-doc/liquidDoc.d.ts +1 -1
  117. package/dist/liquid-doc/liquidDoc.js.map +1 -1
  118. package/dist/liquid-doc/utils.d.ts +3 -3
  119. package/dist/liquid-doc/utils.js +14 -3
  120. package/dist/liquid-doc/utils.js.map +1 -1
  121. package/dist/path.d.ts +1 -0
  122. package/dist/path.js +16 -1
  123. package/dist/path.js.map +1 -1
  124. package/{src/test/MockTheme.ts → dist/test/MockApp.d.ts} +2 -3
  125. package/dist/test/MockApp.js +16 -0
  126. package/dist/test/MockApp.js.map +1 -0
  127. package/dist/test/MockFileSystem.d.ts +3 -3
  128. package/dist/test/MockFileSystem.js +6 -6
  129. package/dist/test/MockFileSystem.js.map +1 -1
  130. package/dist/test/index.d.ts +1 -1
  131. package/dist/test/index.js +1 -1
  132. package/dist/test/index.js.map +1 -1
  133. package/dist/test/test-helper.d.ts +10 -9
  134. package/dist/test/test-helper.js +15 -106
  135. package/dist/test/test-helper.js.map +1 -1
  136. package/dist/to-schema.d.ts +1 -1
  137. package/dist/to-source-code.d.ts +3 -2
  138. package/dist/to-source-code.js +20 -0
  139. package/dist/to-source-code.js.map +1 -1
  140. package/dist/tsconfig.tsbuildinfo +1 -1
  141. package/dist/types/platformos-liquid-docs.d.ts +128 -0
  142. package/dist/types/platformos-liquid-docs.js +3 -0
  143. package/dist/types/platformos-liquid-docs.js.map +1 -0
  144. package/dist/types/schemas/index.d.ts +0 -2
  145. package/dist/types/schemas/index.js.map +1 -1
  146. package/dist/types.d.ts +26 -67
  147. package/dist/types.js +3 -5
  148. package/dist/types.js.map +1 -1
  149. package/dist/utils/block.js.map +1 -1
  150. package/dist/utils/index.d.ts +0 -1
  151. package/dist/utils/index.js +0 -1
  152. package/dist/utils/index.js.map +1 -1
  153. package/dist/yaml/parse.d.ts +5 -0
  154. package/dist/yaml/parse.js +94 -0
  155. package/dist/yaml/parse.js.map +1 -0
  156. package/package.json +4 -3
  157. package/src/{AugmentedThemeDocset.spec.ts → AugmentedPlatformOSDocset.spec.ts} +47 -34
  158. package/src/AugmentedPlatformOSDocset.ts +89 -0
  159. package/src/JSONValidator.ts +1 -1
  160. package/src/checks/deprecated-filter/index.spec.ts +76 -248
  161. package/src/checks/deprecated-filter/index.ts +5 -53
  162. package/src/checks/deprecated-tag/index.spec.ts +85 -34
  163. package/src/checks/deprecated-tag/index.ts +27 -22
  164. package/src/checks/duplicate-function-arguments/index.ts +1 -1
  165. package/src/checks/duplicate-render-partial-arguments/index.spec.ts +12 -12
  166. package/src/checks/duplicate-render-partial-arguments/index.ts +1 -1
  167. package/src/checks/graphql/index.ts +1 -1
  168. package/src/checks/graphql-variables/index.spec.ts +95 -0
  169. package/src/checks/graphql-variables/index.ts +4 -0
  170. package/src/checks/img-width-and-height/index.ts +2 -2
  171. package/src/checks/index.ts +11 -80
  172. package/src/checks/invalid-hash-assign-target/index.spec.ts +27 -27
  173. package/src/checks/json-syntax-error/index.ts +2 -2
  174. package/src/checks/liquid-html-syntax-error/checks/InvalidBooleanExpression.spec.ts +0 -11
  175. package/src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.spec.ts +1 -2
  176. package/src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.ts +2 -2
  177. package/src/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.spec.ts +259 -0
  178. package/src/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.ts +89 -0
  179. package/src/checks/liquid-html-syntax-error/checks/UnknownTag.spec.ts +293 -0
  180. package/src/checks/liquid-html-syntax-error/checks/UnknownTag.ts +43 -0
  181. package/src/checks/liquid-html-syntax-error/index.spec.ts +1 -6
  182. package/src/checks/liquid-html-syntax-error/index.ts +26 -5
  183. package/src/checks/matching-translations/index.spec.ts +187 -354
  184. package/src/checks/matching-translations/index.ts +117 -107
  185. package/src/checks/metadata-params/index.ts +6 -8
  186. package/src/checks/missing-asset/index.ts +1 -1
  187. package/src/checks/{missing-template → missing-partial}/index.spec.ts +6 -6
  188. package/src/checks/{missing-template → missing-partial}/index.ts +12 -26
  189. package/src/checks/orphaned-partial/index.ts +3 -3
  190. package/src/checks/parser-blocking-script/index.spec.ts +0 -118
  191. package/src/checks/parser-blocking-script/index.ts +3 -33
  192. package/src/checks/parser-blocking-script/suggestions.ts +1 -28
  193. package/src/checks/translation-key-exists/index.ts +1 -1
  194. package/src/checks/unclosed-html-element/index.ts +5 -1
  195. package/src/checks/undefined-object/index.spec.ts +32 -111
  196. package/src/checks/undefined-object/index.ts +15 -34
  197. package/src/checks/unique-doc-param-names/index.ts +1 -1
  198. package/src/checks/unknown-filter/index.spec.ts +2 -2
  199. package/src/checks/unknown-filter/index.ts +3 -3
  200. package/src/checks/unknown-property/index.ts +1 -1
  201. package/src/checks/unrecognized-render-partial-arguments/index.spec.ts +5 -5
  202. package/src/checks/unrecognized-render-partial-arguments/index.ts +2 -5
  203. package/src/checks/unused-assign/index.spec.ts +0 -30
  204. package/src/checks/unused-assign/index.ts +2 -2
  205. package/src/checks/unused-doc-param/index.ts +1 -1
  206. package/src/checks/utils.ts +1 -1
  207. package/src/checks/valid-doc-param-types/index.ts +4 -4
  208. package/src/checks/valid-html-translation/index.spec.ts +42 -32
  209. package/src/checks/valid-html-translation/index.ts +7 -7
  210. package/src/checks/valid-json/index.ts +2 -2
  211. package/src/checks/valid-render-partial-argument-types/index.spec.ts +13 -13
  212. package/src/checks/valid-render-partial-argument-types/index.ts +2 -5
  213. package/src/checks/variable-name/index.ts +1 -1
  214. package/src/context-utils.spec.ts +49 -77
  215. package/src/context-utils.ts +81 -129
  216. package/src/disabled-checks/index.spec.ts +26 -26
  217. package/src/disabled-checks/index.ts +2 -2
  218. package/src/disabled-checks/test-checks.ts +4 -4
  219. package/src/find-root.ts +12 -22
  220. package/src/fixes/autofix.spec.ts +2 -2
  221. package/src/fixes/autofix.ts +4 -4
  222. package/src/fixes/correctors/index.ts +4 -0
  223. package/src/ignore.spec.ts +4 -5
  224. package/src/index.ts +51 -21
  225. package/src/jsonc/parse.ts +1 -1
  226. package/src/liquid-doc/arguments.spec.ts +19 -45
  227. package/src/liquid-doc/arguments.ts +35 -42
  228. package/src/liquid-doc/liquidDoc.spec.ts +1 -1
  229. package/src/liquid-doc/liquidDoc.ts +1 -2
  230. package/src/liquid-doc/utils.ts +17 -8
  231. package/src/path.ts +16 -0
  232. package/src/test/MockApp.ts +17 -0
  233. package/src/test/MockFileSystem.spec.ts +10 -11
  234. package/src/test/MockFileSystem.ts +6 -6
  235. package/src/test/contain-offense.spec.ts +11 -3
  236. package/src/test/index.ts +1 -1
  237. package/src/test/test-helper.ts +43 -145
  238. package/src/to-source-code.ts +20 -1
  239. package/src/types/{theme-liquid-docs.ts → platformos-liquid-docs.ts} +8 -13
  240. package/src/types.ts +29 -92
  241. package/src/utils/index.ts +0 -1
  242. package/src/visitor.spec.ts +2 -2
  243. package/src/yaml/parse.ts +111 -0
  244. package/src/AugmentedThemeDocset.ts +0 -137
  245. package/src/checks/app-block-missing-schema/index.spec.ts +0 -121
  246. package/src/checks/app-block-missing-schema/index.ts +0 -46
  247. package/src/checks/app-block-valid-tags/index.spec.ts +0 -96
  248. package/src/checks/app-block-valid-tags/index.ts +0 -54
  249. package/src/checks/asset-preload/index.spec.ts +0 -78
  250. package/src/checks/asset-preload/index.ts +0 -65
  251. package/src/checks/asset-size-app-block-css/index.spec.ts +0 -88
  252. package/src/checks/asset-size-app-block-css/index.ts +0 -78
  253. package/src/checks/asset-size-app-block-javascript/index.spec.ts +0 -66
  254. package/src/checks/asset-size-app-block-javascript/index.ts +0 -78
  255. package/src/checks/asset-size-css/index.spec.ts +0 -166
  256. package/src/checks/asset-size-css/index.ts +0 -160
  257. package/src/checks/asset-size-javascript/index.spec.ts +0 -184
  258. package/src/checks/asset-size-javascript/index.ts +0 -144
  259. package/src/checks/block-id-usage/index.spec.ts +0 -76
  260. package/src/checks/block-id-usage/index.ts +0 -72
  261. package/src/checks/cdn-preconnect/index.spec.ts +0 -40
  262. package/src/checks/cdn-preconnect/index.ts +0 -43
  263. package/src/checks/content-for-header-modification/index.spec.ts +0 -65
  264. package/src/checks/content-for-header-modification/index.ts +0 -72
  265. package/src/checks/deprecate-bgsizes/index.spec.ts +0 -41
  266. package/src/checks/deprecate-bgsizes/index.ts +0 -49
  267. package/src/checks/deprecate-lazysizes/index.spec.ts +0 -26
  268. package/src/checks/deprecate-lazysizes/index.ts +0 -58
  269. package/src/checks/deprecated-filter/fixes.ts +0 -264
  270. package/src/checks/deprecated-fonts-on-sections-and-blocks/deprecated-fonts-data.ts +0 -1343
  271. package/src/checks/deprecated-fonts-on-sections-and-blocks/index.spec.ts +0 -613
  272. package/src/checks/deprecated-fonts-on-sections-and-blocks/index.ts +0 -284
  273. package/src/checks/deprecated-fonts-on-settings-schema/index.spec.ts +0 -102
  274. package/src/checks/deprecated-fonts-on-settings-schema/index.ts +0 -66
  275. package/src/checks/duplicate-content-for-arguments/index.spec.ts +0 -98
  276. package/src/checks/duplicate-content-for-arguments/index.ts +0 -43
  277. package/src/checks/empty-block-content/index.spec.ts +0 -117
  278. package/src/checks/empty-block-content/index.ts +0 -60
  279. package/src/checks/hardcoded-routes/index.spec.ts +0 -58
  280. package/src/checks/hardcoded-routes/index.ts +0 -100
  281. package/src/checks/json-missing-block/index.spec.ts +0 -435
  282. package/src/checks/json-missing-block/index.ts +0 -56
  283. package/src/checks/json-missing-block/missing-block-utils.ts +0 -147
  284. package/src/checks/liquid-free-settings/index.spec.ts +0 -180
  285. package/src/checks/liquid-free-settings/index.ts +0 -79
  286. package/src/checks/missing-content-for-arguments/index.spec.ts +0 -144
  287. package/src/checks/missing-content-for-arguments/index.ts +0 -46
  288. package/src/checks/pagination-size/index.spec.ts +0 -158
  289. package/src/checks/pagination-size/index.ts +0 -104
  290. package/src/checks/remote-asset/index.spec.ts +0 -280
  291. package/src/checks/remote-asset/index.ts +0 -238
  292. package/src/checks/reserved-doc-param-names/index.spec.ts +0 -62
  293. package/src/checks/reserved-doc-param-names/index.ts +0 -57
  294. package/src/checks/schema-presets-block-order/index.spec.ts +0 -344
  295. package/src/checks/schema-presets-block-order/index.ts +0 -154
  296. package/src/checks/schema-presets-static-blocks/index.spec.ts +0 -145
  297. package/src/checks/schema-presets-static-blocks/index.ts +0 -126
  298. package/src/checks/static-stylesheet-and-javascript-tags/index.spec.ts +0 -257
  299. package/src/checks/static-stylesheet-and-javascript-tags/index.ts +0 -48
  300. package/src/checks/unique-settings-id/index.spec.ts +0 -24
  301. package/src/checks/unique-settings-id/index.ts +0 -84
  302. package/src/checks/unique-settings-id/test-data.ts +0 -1191
  303. package/src/checks/unique-static-block-id/index.spec.ts +0 -55
  304. package/src/checks/unique-static-block-id/index.ts +0 -60
  305. package/src/checks/unrecognized-content-for-arguments/index.spec.ts +0 -145
  306. package/src/checks/unrecognized-content-for-arguments/index.ts +0 -55
  307. package/src/checks/valid-block-target/index.spec.ts +0 -1396
  308. package/src/checks/valid-block-target/index.ts +0 -142
  309. package/src/checks/valid-content-for-argument-types/index.spec.ts +0 -382
  310. package/src/checks/valid-content-for-argument-types/index.ts +0 -42
  311. package/src/checks/valid-content-for-arguments/index.spec.ts +0 -107
  312. package/src/checks/valid-content-for-arguments/index.ts +0 -98
  313. package/src/checks/valid-local-blocks/index.spec.ts +0 -286
  314. package/src/checks/valid-local-blocks/index.ts +0 -100
  315. package/src/checks/valid-local-blocks/valid-block-utils.ts +0 -97
  316. package/src/checks/valid-schema/index.spec.ts +0 -174
  317. package/src/checks/valid-schema/index.ts +0 -41
  318. package/src/checks/valid-schema-name/index.spec.ts +0 -112
  319. package/src/checks/valid-schema-name/index.ts +0 -75
  320. package/src/checks/valid-settings-key/index.spec.ts +0 -321
  321. package/src/checks/valid-settings-key/index.ts +0 -144
  322. package/src/checks/valid-static-block-type/index.spec.ts +0 -38
  323. package/src/checks/valid-static-block-type/index.ts +0 -58
  324. package/src/checks/valid-visible-if/index.spec.ts +0 -619
  325. package/src/checks/valid-visible-if/index.ts +0 -184
  326. package/src/checks/valid-visible-if/visible-if-utils.ts +0 -158
  327. package/src/tags/content-for.ts +0 -25
  328. package/src/to-schema.ts +0 -231
  329. package/src/types/schemas/index.ts +0 -5
  330. package/src/types/schemas/preset.ts +0 -52
  331. package/src/types/schemas/section.ts +0 -86
  332. package/src/types/schemas/setting.ts +0 -320
  333. package/src/types/schemas/template.ts +0 -34
  334. package/src/types/schemas/theme-block.ts +0 -34
  335. package/src/types/theme-schemas.ts +0 -80
  336. package/src/utils/block.ts +0 -300
  337. package/src/utils/markup.ts +0 -10
@@ -1,400 +1,233 @@
1
1
  import { expect, describe, it } from 'vitest';
2
- import { autofix, check, highlightedOffenses } from '../../test';
2
+ import { check } from '../../test';
3
3
  import { MatchingTranslations } from '../../checks/matching-translations/index';
4
4
 
5
- const prettyJSON = (json: any) => JSON.stringify(json, null, 2);
6
-
7
5
  describe('Module: MatchingTranslations', async () => {
8
6
  it('should report offenses when the translation file is missing a key', async () => {
9
- for (const prefix of ['', '.schema']) {
10
- const theme = {
11
- [`locales/en.default${prefix}.json`]: JSON.stringify({
12
- hello: 'Hello',
13
- world: 'World',
14
- }),
15
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
16
- hello: 'Olá',
17
- }),
18
- };
19
-
20
- const offenses = await check(theme, [MatchingTranslations]);
21
-
22
- expect(offenses).to.be.of.length(1);
23
- expect(offenses).to.containOffense("The translation for 'world' is missing");
24
- }
7
+ const app = {
8
+ 'app/translations/en.yml': 'en:\n hello: Hello\n world: World\n',
9
+ 'app/translations/pt-BR.yml': 'pt-BR:\n hello: Olá\n',
10
+ };
11
+
12
+ const offenses = await check(app, [MatchingTranslations]);
13
+
14
+ expect(offenses).to.be.of.length(1);
15
+ expect(offenses).to.containOffense("The translation for 'world' is missing");
25
16
  });
26
17
 
27
18
  it('should report offenses when the default translation is missing a key', async () => {
28
- for (const prefix of ['', '.schema']) {
29
- const theme = {
30
- [`locales/en.default${prefix}.json`]: JSON.stringify({
31
- hello: 'Hello',
32
- }),
33
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
34
- hello: 'Olá',
35
- world: 'Mundo',
36
- }),
37
- };
38
-
39
- const offenses = await check(theme, [MatchingTranslations]);
40
-
41
- expect(offenses).to.be.of.length(1);
42
- expect(offenses).to.containOffense("A default translation for 'world' does not exist");
43
- expect(offenses[0]!).to.suggest(
44
- theme[`locales/pt-BR${prefix}.json`],
45
- 'Delete unneeded translation key',
46
- {
47
- startIndex: 0,
48
- endIndex: theme[`locales/pt-BR${prefix}.json`].length,
49
- insert: prettyJSON({
50
- hello: 'Olá',
51
- }),
52
- },
53
- );
54
- }
19
+ const app = {
20
+ 'app/translations/en.yml': 'en:\n hello: Hello\n',
21
+ 'app/translations/pt-BR.yml': 'pt-BR:\n hello: Olá\n world: Mundo\n',
22
+ };
23
+
24
+ const offenses = await check(app, [MatchingTranslations]);
25
+
26
+ expect(offenses).to.be.of.length(1);
27
+ expect(offenses).to.containOffense("A translation for 'world' does not exist in the en locale");
55
28
  });
56
29
 
57
30
  it('should report offenses when nested translation keys do not exist', async () => {
58
- for (const prefix of ['', '.schema']) {
59
- const theme = {
60
- [`locales/en.default${prefix}.json`]: JSON.stringify({
61
- hello: { world: 'Hello, world!' },
62
- }),
63
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
64
- hello: {},
65
- }),
66
- };
67
-
68
- const offenses = await check(theme, [MatchingTranslations]);
69
-
70
- expect(offenses).to.be.of.length(1);
71
- expect(offenses).to.containOffense({
72
- message: "The translation for 'hello.world' is missing",
73
- uri: `file:///locales/pt-BR${prefix}.json`,
74
- });
75
-
76
- const fixed = await autofix(theme, offenses);
77
- expect(fixed[`locales/pt-BR${prefix}.json`]).to.eql(
78
- prettyJSON({
79
- hello: {
80
- world: 'TODO',
81
- },
82
- }),
83
- );
84
- }
31
+ const app = {
32
+ 'app/translations/en.yml': 'en:\n hello:\n world: Hello, world!\n',
33
+ 'app/translations/pt-BR.yml': 'pt-BR:\n hello: {}\n',
34
+ };
35
+
36
+ const offenses = await check(app, [MatchingTranslations]);
37
+
38
+ expect(offenses).to.be.of.length(1);
39
+ expect(offenses).to.containOffense({
40
+ message: "The translation for 'hello.world' is missing",
41
+ uri: `file:///app/translations/pt-BR.yml`,
42
+ });
85
43
  });
86
44
 
87
45
  it('should report offenses when translation shapes do not match', async () => {
88
- for (const prefix of ['', '.schema']) {
89
- const theme = {
90
- [`locales/en.default${prefix}.json`]: JSON.stringify({
91
- hello: { world: 'Hello, world!' },
92
- }),
93
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
94
- hello: 'Olá',
95
- }),
96
- };
97
-
98
- const offenses = await check(theme, [MatchingTranslations]);
99
-
100
- expect(offenses).to.be.of.length(2);
101
- expect(offenses).to.containOffense({
102
- message: "A default translation for 'hello' does not exist",
103
- uri: `file:///locales/pt-BR${prefix}.json`,
104
- });
105
- expect(offenses).to.containOffense({
106
- message: "The translation for 'hello.world' is missing",
107
- uri: `file:///locales/pt-BR${prefix}.json`,
108
- });
109
-
110
- const fixed = await autofix(theme, offenses);
111
-
112
- expect(fixed[`locales/pt-BR${prefix}.json`]).to.eql(
113
- prettyJSON({
114
- hello: { world: 'TODO' },
115
- }),
116
- );
117
- }
46
+ const app = {
47
+ 'app/translations/en.yml': 'en:\n hello:\n world: Hello, world!\n',
48
+ 'app/translations/pt-BR.yml': 'pt-BR:\n hello: Olá\n',
49
+ };
50
+
51
+ const offenses = await check(app, [MatchingTranslations]);
52
+
53
+ expect(offenses).to.be.of.length(2);
54
+ expect(offenses).to.containOffense({
55
+ message: "A translation for 'hello' does not exist in the en locale",
56
+ uri: `file:///app/translations/pt-BR.yml`,
57
+ });
58
+ expect(offenses).to.containOffense({
59
+ message: "The translation for 'hello.world' is missing",
60
+ uri: `file:///app/translations/pt-BR.yml`,
61
+ });
118
62
  });
119
63
 
120
64
  it('should report offenses when nested translation keys do not match', async () => {
121
- for (const prefix of ['', '.schema']) {
122
- const theme = {
123
- [`locales/en.default${prefix}.json`]: JSON.stringify({
124
- hello: { world: 'Hello, world!' },
125
- }),
126
- [`locales/fr${prefix}.json`]: JSON.stringify({
127
- hello: { monde: 'Bonjour, monde' },
128
- }),
129
- [`locales/es-ES${prefix}.json`]: JSON.stringify({
130
- hello: { world: 'Hello, world!', mundo: { hola: '¡Hola, mundo!' } },
131
- }),
132
- };
133
-
134
- const offenses = await check(theme, [MatchingTranslations]);
135
-
136
- expect(offenses).to.be.of.length(3);
137
- expect(offenses).to.containOffense({
138
- message: "A default translation for 'hello.monde' does not exist",
139
- uri: `file:///locales/fr${prefix}.json`,
140
- });
141
- expect(offenses).to.containOffense({
142
- message: "A default translation for 'hello.mundo.hola' does not exist",
143
- uri: `file:///locales/es-ES${prefix}.json`,
144
- });
145
- expect(offenses).to.containOffense({
146
- message: "The translation for 'hello.world' is missing",
147
- uri: `file:///locales/fr${prefix}.json`,
148
- });
149
-
150
- const fixed = await autofix(theme, offenses);
151
- expect(fixed[`locales/fr${prefix}.json`]).to.eql(
152
- prettyJSON({
153
- hello: { monde: 'Bonjour, monde', world: 'TODO' },
154
- }),
155
- );
156
-
157
- // Default does not exist should be a suggestion and not autofixed.
158
- expect(fixed[`locales/es-ES${prefix}.json`]).to.eql(theme[`locales/es-ES${prefix}.json`]);
159
- }
160
- });
65
+ const app = {
66
+ 'app/translations/en.yml': 'en:\n hello:\n world: Hello, world!\n',
67
+ 'app/translations/fr.yml': 'fr:\n hello:\n monde: Bonjour, monde\n',
68
+ 'app/translations/es-ES.yml':
69
+ 'es-ES:\n hello:\n world: Hello, world!\n mundo:\n hola: "¡Hola, mundo!"\n',
70
+ };
71
+
72
+ const offenses = await check(app, [MatchingTranslations]);
73
+
74
+ expect(offenses).to.be.of.length(3);
75
+ expect(offenses).to.containOffense({
76
+ message: "A translation for 'hello.monde' does not exist in the en locale",
77
+ uri: `file:///app/translations/fr.yml`,
78
+ });
79
+ expect(offenses).to.containOffense({
80
+ message: "A translation for 'hello.mundo.hola' does not exist in the en locale",
81
+ uri: `file:///app/translations/es-ES.yml`,
82
+ });
83
+ expect(offenses).to.containOffense({
84
+ message: "The translation for 'hello.world' is missing",
85
+ uri: `file:///app/translations/fr.yml`,
86
+ });
87
+ });
88
+
89
+ it('should not report offenses when default translations do not exist (no en.yml)', async () => {
90
+ const app = {
91
+ 'app/translations/pt-BR.yml': 'pt-BR:\n hello: Olá\n',
92
+ };
93
+
94
+ const offenses = await check(app, [MatchingTranslations]);
161
95
 
162
- it('should not report offenses when default translations do not exist', async () => {
163
- for (const prefix of ['', '.schema']) {
164
- const theme = {
165
- [`locales/en${prefix}.json`]: JSON.stringify({
166
- hello: 'Hello',
167
- }),
168
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
169
- hello: 'Olá',
170
- }),
171
- };
172
-
173
- const offenses = await check(theme, [MatchingTranslations]);
174
-
175
- expect(offenses).to.be.of.length(0);
176
- }
96
+ expect(offenses).to.be.of.length(0);
177
97
  });
178
98
 
179
99
  it('should not report offenses when translations match', async () => {
180
- for (const prefix of ['', '.schema']) {
181
- const theme = {
182
- [`locales/en.default${prefix}.json`]: JSON.stringify({
183
- hello: 'Hello',
184
- world: 'World',
185
- }),
186
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
187
- hello: 'Olá',
188
- world: 'Mundo',
189
- }),
190
- };
191
-
192
- const offenses = await check(theme, [MatchingTranslations]);
193
-
194
- expect(offenses).to.be.of.length(0);
195
- }
100
+ const app = {
101
+ 'app/translations/en.yml': 'en:\n hello: Hello\n world: World\n',
102
+ 'app/translations/pt-BR.yml': 'pt-BR:\n hello: Olá\n world: Mundo\n',
103
+ };
104
+
105
+ const offenses = await check(app, [MatchingTranslations]);
106
+
107
+ expect(offenses).to.be.of.length(0);
196
108
  });
197
109
 
198
110
  it('should not report offenses when nested translations match', async () => {
199
- for (const prefix of ['', '.schema']) {
200
- const theme = {
201
- [`locales/en.default${prefix}.json`]: JSON.stringify({
202
- hello: { world: 'Hello, world!' },
203
- }),
204
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
205
- hello: { world: 'Olá, mundo!' },
206
- }),
207
- [`locales/fr${prefix}.json`]: JSON.stringify({
208
- hello: { world: 'Bonjour, monde' },
209
- }),
210
- };
211
-
212
- const offenses = await check(theme, [MatchingTranslations]);
213
-
214
- expect(offenses).to.be.of.length(0);
215
- }
216
- });
111
+ const app = {
112
+ 'app/translations/en.yml': 'en:\n hello:\n world: Hello, world!\n',
113
+ 'app/translations/pt-BR.yml': 'pt-BR:\n hello:\n world: Olá, mundo!\n',
114
+ 'app/translations/fr.yml': 'fr:\n hello:\n world: Bonjour, monde\n',
115
+ };
217
116
 
218
- it('should not report offenses and ignore pluralization', async () => {
219
- for (const prefix of ['', '.schema']) {
220
- const theme = {
221
- [`locales/en.default${prefix}.json`]: JSON.stringify({
222
- hello: {
223
- one: 'Hello, you',
224
- other: "Hello, y'all",
225
- },
226
- }),
227
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
228
- hello: {
229
- zero: 'Estou sozinho :(',
230
- few: 'Olá, galerinha :)',
231
- },
232
- }),
233
- };
234
-
235
- const offenses = await check(theme, [MatchingTranslations]);
236
-
237
- expect(offenses).to.be.of.length(0);
238
- }
239
- });
117
+ const offenses = await check(app, [MatchingTranslations]);
240
118
 
241
- it('should not report offenses and ignore keys provided by Shopify', async () => {
242
- for (const prefix of ['', '.schema']) {
243
- const theme = {
244
- [`locales/en.default${prefix}.json`]: JSON.stringify({
245
- hello: 'Hello',
246
- shopify: {
247
- checkout: {
248
- general: {
249
- page_title: 'Checkout',
250
- },
251
- },
252
- },
253
- }),
254
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
255
- hello: 'Olá',
256
- shopify: {
257
- sentence: {
258
- words_connector: 'hello world',
259
- },
260
- },
261
- }),
262
- };
263
-
264
- const offenses = await check(theme, [MatchingTranslations]);
265
-
266
- expect(offenses).to.be.of.length(0);
267
- }
119
+ expect(offenses).to.be.of.length(0);
268
120
  });
269
121
 
270
- it('should not report offenses and ignore "*.schema.json" files', async () => {
271
- const theme = {
272
- 'locales/en.default.json': JSON.stringify({ hello: 'Hello' }),
273
- 'locales/pt-BR.schema.json': JSON.stringify({}),
122
+ it('should not report offenses and ignore pluralization', async () => {
123
+ const app = {
124
+ 'app/translations/en.yml': 'en:\n hello:\n one: Hello, you\n other: "Hello, y\'all"\n',
125
+ 'app/translations/pt-BR.yml':
126
+ 'pt-BR:\n hello:\n zero: Estou sozinho :(\n few: "Olá, galerinha :)"\n',
274
127
  };
275
128
 
276
- const offenses = await check(theme, [MatchingTranslations]);
129
+ const offenses = await check(app, [MatchingTranslations]);
277
130
 
278
131
  expect(offenses).to.be.of.length(0);
279
132
  });
280
133
 
281
- it('should highlight the proper element when the translation file is missing a key', async () => {
282
- for (const prefix of ['', '.schema']) {
283
- const theme = {
284
- [`locales/en.default${prefix}.json`]: JSON.stringify({
285
- hello: 'Hello',
286
- world: 'World',
287
- }),
288
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
289
- hello: 'Olá',
290
- }),
291
- };
292
-
293
- const offenses = await check(theme, [MatchingTranslations]);
294
- const elements = highlightedOffenses(theme, offenses);
295
-
296
- expect(elements).to.deep.eq(['{"hello":"Olá"}']);
297
- }
134
+ it('should not highlight anything if the file is unparseable', async () => {
135
+ const app = {
136
+ 'app/translations/en.yml': 'en:\n hello:\n world: Hello, world!\n',
137
+ 'app/translations/pt-BR.yml': 'pt-BR:\n hello: :\n bad yaml',
138
+ };
139
+
140
+ const offenses = await check(app, [MatchingTranslations]);
141
+ expect(offenses).to.have.length(0);
298
142
  });
299
143
 
300
- it('should highlight the proper element when the default translation is missing a key', async () => {
301
- for (const prefix of ['', '.schema']) {
302
- const theme = {
303
- [`locales/en.default${prefix}.json`]: JSON.stringify({
304
- hello: 'Hello',
305
- }),
306
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
307
- hello: 'Olá',
308
- world: 'Mundo',
309
- }),
310
- };
311
-
312
- const offenses = await check(theme, [MatchingTranslations]);
313
- const elements = highlightedOffenses(theme, offenses);
314
-
315
- expect(elements).to.deep.eq(['"world":"Mundo"']);
316
- }
144
+ // --- Multi-file / multi-scope tests ---
145
+
146
+ it('should not flag keys from a different translation scope (module vs app)', async () => {
147
+ // Module translations are auto-prefixed with their module name at runtime, so each
148
+ // module is its own isolated scope. The app scope should never need keys from
149
+ // modules/common-styling/public/translations/en.yml.
150
+ const app = {
151
+ 'app/translations/en.yml': 'en:\n hello: Hello\n',
152
+ 'app/translations/pt-BR.yml': 'pt-BR:\n hello: Olá\n',
153
+ 'modules/common-styling/public/translations/en.yml':
154
+ 'en:\n password:\n toggle_visibility: Toggle\n',
155
+ };
156
+
157
+ const offenses = await check(app, [MatchingTranslations]);
158
+ expect(offenses).to.have.length(0);
317
159
  });
318
160
 
319
- it('should highlight the proper element when nested translation keys do not exist', async () => {
320
- for (const prefix of ['', '.schema']) {
321
- const theme = {
322
- [`locales/en.default${prefix}.json`]: JSON.stringify({
323
- hello: {
324
- world: 'Hello, world!',
325
- },
326
- welcome: 'Welcome',
327
- }),
328
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
329
- hello: {},
330
- welcome: 'Bem-vinda',
331
- }),
332
- };
333
-
334
- const offenses = await check(theme, [MatchingTranslations]);
335
- const elements = highlightedOffenses(theme, offenses);
336
-
337
- expect(elements).to.deep.eq(['"hello":{}']);
338
- }
161
+ it('should report missing keys in a module non-en file against that module own en translations', async () => {
162
+ const app = {
163
+ 'app/translations/en.yml': 'en:\n hello: Hello\n',
164
+ 'modules/common-styling/public/translations/en.yml':
165
+ 'en:\n password:\n toggle_visibility: Toggle\n',
166
+ 'modules/common-styling/public/translations/pt-BR.yml': 'pt-BR:\n other: Outro\n',
167
+ };
168
+
169
+ const offenses = await check(app, [MatchingTranslations]);
170
+ expect(offenses).to.have.length(1);
171
+ expect(offenses).to.containOffense({
172
+ message: "The translation for 'password.toggle_visibility' is missing",
173
+ uri: 'file:///modules/common-styling/public/translations/pt-BR.yml',
174
+ });
339
175
  });
340
176
 
341
- it('should highlight the proper element when nested translation keys do not exist and there is a sibling node', async () => {
342
- for (const prefix of ['', '.schema']) {
343
- const theme = {
344
- [`locales/en.default${prefix}.json`]: JSON.stringify({
345
- hello: {
346
- shopify: 'Shopify!',
347
- world: 'Hello, world!',
348
- },
349
- welcome: 'Welcome',
350
- }),
351
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
352
- hello: {
353
- shopify: 'Shopify!',
354
- },
355
- welcome: 'Bem-vinda',
356
- }),
357
- };
358
-
359
- const offenses = await check(theme, [MatchingTranslations]);
360
- const elements = highlightedOffenses(theme, offenses);
361
-
362
- expect(elements).to.deep.eq(['"hello":{"shopify":"Shopify!"}']);
363
- }
177
+ it('should skip files inside the en/ locale sub-directory (they are English source files)', async () => {
178
+ // Files like app/translations/en/validation.yml are English — the check must not
179
+ // lint them as if they were a "non-English" locale file to compare.
180
+ const app = {
181
+ 'app/translations/en/validation.yml': 'en:\n required: Required\n',
182
+ 'app/translations/pt-BR/validation.yml': 'pt-BR:\n required: Obrigatório\n',
183
+ };
184
+
185
+ const offenses = await check(app, [MatchingTranslations]);
186
+ expect(offenses).to.have.length(0);
364
187
  });
365
188
 
366
- it('should highlight the proper element when translation shapes do not match', async () => {
367
- for (const prefix of ['', '.schema']) {
368
- const theme = {
369
- [`locales/en.default${prefix}.json`]: JSON.stringify({
370
- hello: { world: 'Hello, world!' },
371
- }),
372
- [`locales/pt-BR${prefix}.json`]: JSON.stringify({
373
- hello: 'Olá',
374
- }),
375
- };
376
-
377
- const offenses = await check(theme, [MatchingTranslations]);
378
- const elements = highlightedOffenses(theme, offenses);
379
-
380
- // We have two elements because we have two offenses:
381
- // - A default translation for 'hello' does not exist"
382
- // - The translation for 'hello.world' is missing"
383
- expect(elements).to.deep.eq(['"hello":"Olá"', '"hello":"Olá"']);
384
- }
189
+ it('should aggregate multiple en/*.yml files within one scope as the reference set', async () => {
190
+ // Within the app scope, en/auth.yml and en/checkout.yml both contribute to the
191
+ // reference; pt-BR.yml must cover all of them.
192
+ const app = {
193
+ 'app/translations/en/auth.yml': 'en:\n login: Log in\n',
194
+ 'app/translations/en/checkout.yml': 'en:\n submit: Submit\n',
195
+ 'app/translations/pt-BR.yml': 'pt-BR:\n login: Entrar\n',
196
+ };
197
+
198
+ const offenses = await check(app, [MatchingTranslations]);
199
+ expect(offenses).to.have.length(1);
200
+ expect(offenses).to.containOffense({
201
+ message: "The translation for 'submit' is missing",
202
+ uri: 'file:///app/translations/pt-BR.yml',
203
+ });
385
204
  });
386
205
 
387
- it('should not highlight anything if the file is unparseable', async () => {
388
- for (const prefix of ['', '.schema']) {
389
- const theme = {
390
- [`locales/en.default${prefix}.json`]: JSON.stringify({
391
- hello: { world: 'Hello, world!' },
392
- }),
393
- [`locales/pt-BR${prefix}.json`]: `{"hello": }`,
394
- };
395
-
396
- const offenses = await check(theme, [MatchingTranslations]);
397
- expect(offenses).to.have.length(0);
398
- }
206
+ it('should aggregate en.yml and en/*.yml together as the scope reference set', async () => {
207
+ const app = {
208
+ 'app/translations/en.yml': 'en:\n hello: Hello\n',
209
+ 'app/translations/en/auth.yml': 'en:\n login: Log in\n',
210
+ 'app/translations/pt-BR.yml': 'pt-BR:\n hello: Olá\n',
211
+ };
212
+
213
+ const offenses = await check(app, [MatchingTranslations]);
214
+ expect(offenses).to.have.length(1);
215
+ expect(offenses).to.containOffense({
216
+ message: "The translation for 'login' is missing",
217
+ uri: 'file:///app/translations/pt-BR.yml',
218
+ });
219
+ });
220
+
221
+ it('should not report a key as missing if it is covered by another file in the same locale scope', async () => {
222
+ // pt-BR/validation.yml covers 'required' — pt-BR.yml should not be blamed for it
223
+ const app = {
224
+ 'app/translations/en.yml': 'en:\n hello: Hello\n',
225
+ 'app/translations/en/validation.yml': 'en:\n required: Required\n',
226
+ 'app/translations/pt-BR.yml': 'pt-BR:\n hello: Olá\n',
227
+ 'app/translations/pt-BR/validation.yml': 'pt-BR:\n required: Obrigatório\n',
228
+ };
229
+
230
+ const offenses = await check(app, [MatchingTranslations]);
231
+ expect(offenses).to.have.length(0);
399
232
  });
400
233
  });