wp-studio 1.7.8-beta2 → 1.7.8-beta4

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 (312) hide show
  1. package/README.md +54 -1
  2. package/assets/demo.gif +0 -0
  3. package/dist/cli/{_events-BRGCap7g.mjs → _events-C2dFSpKE.mjs} +2 -2
  4. package/dist/cli/{certificate-manager-Dd4zv2_k.mjs → certificate-manager-BMngpL-s.mjs} +12 -4
  5. package/dist/cli/{index-9Oz-0bqF.mjs → index-CkFXAp-n.mjs} +5 -5
  6. package/dist/cli/{index-CT4S2538.mjs → index-odShRBgM.mjs} +171 -117
  7. package/dist/cli/{login-D4E3GoXe.mjs → login-BeT1uKwW.mjs} +2 -2
  8. package/dist/cli/{logout-DE-RoshK.mjs → logout-BFQJBJD0.mjs} +2 -2
  9. package/dist/cli/main.mjs +3 -2
  10. package/dist/cli/proxy-daemon.mjs +1 -1
  11. package/dist/cli/{resume-DLoXmzNG.mjs → resume-D_K0QEl5.mjs} +1 -1
  12. package/dist/cli/{set-B8YYUENH.mjs → set-C5l116L7.mjs} +2 -2
  13. package/dist/cli/{set-B0L-QiXT.mjs → set-DzcR6sFr.mjs} +2 -2
  14. package/dist/cli/{status-DEOAA0yx.mjs → status-CbXnAskz.mjs} +1 -1
  15. package/dist/cli/{wp-CobSX6C6.mjs → wp-CUKyZNTP.mjs} +1 -1
  16. package/dist/cli/wp-files/latest/available-site-translations.json +1 -1
  17. package/dist/cli/wp-files/latest/languages/admin-de_DE.l10n.php +2 -2
  18. package/dist/cli/wp-files/latest/languages/admin-network-de_DE.l10n.php +1 -1
  19. package/dist/cli/wp-files/latest/languages/admin-pl_PL.l10n.php +2 -2
  20. package/dist/cli/wp-files/latest/languages/de_DE-0cc31205f20441b3df1d1b46100f6b8d.json +1 -1
  21. package/dist/cli/wp-files/latest/languages/de_DE-0ce75ad2f775d1cac9696967d484808c.json +1 -1
  22. package/dist/cli/wp-files/latest/languages/de_DE-0eebe503220d4a00341eb011b92769b4.json +1 -1
  23. package/dist/cli/wp-files/latest/languages/de_DE-17179a5f2930647c89151e365f843b6e.json +1 -1
  24. package/dist/cli/wp-files/latest/languages/de_DE-1780a2033cf98d69ce13c2e5c8510004.json +1 -1
  25. package/dist/cli/wp-files/latest/languages/de_DE-1a0cd6a7128913b15c1a10dd68951869.json +1 -1
  26. package/dist/cli/wp-files/latest/languages/de_DE-1bba9045bb07c89671c88a3f328548e8.json +1 -1
  27. package/dist/cli/wp-files/latest/languages/de_DE-1c4303f02ff93b290e9faad991eeb06f.json +1 -1
  28. package/dist/cli/wp-files/latest/languages/de_DE-1d17475f620f63a92e2c5d2681c51ee8.json +1 -1
  29. package/dist/cli/wp-files/latest/languages/de_DE-2617ce121227a46077ede6c69aa9fcb5.json +1 -1
  30. package/dist/cli/wp-files/latest/languages/de_DE-270d72d1cff17227d37f3244759cbecb.json +1 -1
  31. package/dist/cli/wp-files/latest/languages/de_DE-28b3c3d595952907e08d98287077426c.json +1 -1
  32. package/dist/cli/wp-files/latest/languages/de_DE-2b390f85a3048c5b4255fb45960b6514.json +1 -1
  33. package/dist/cli/wp-files/latest/languages/de_DE-2c5d274ea625dd91556554ad82901529.json +1 -1
  34. package/dist/cli/wp-files/latest/languages/de_DE-320f4ad9792aaa6dedb1e71cbdf85d57.json +1 -1
  35. package/dist/cli/wp-files/latest/languages/de_DE-440127dd25bde48a531ded36f33e927b.json +1 -1
  36. package/dist/cli/wp-files/latest/languages/de_DE-49c6d4acf36cf3aca9f0b2a77617304f.json +1 -1
  37. package/dist/cli/wp-files/latest/languages/de_DE-4a38fe1c0c45989e44682ba6109d9f46.json +1 -1
  38. package/dist/cli/wp-files/latest/languages/de_DE-4bfa11da57ff2600004bb500368247f4.json +1 -1
  39. package/dist/cli/wp-files/latest/languages/de_DE-50278328b502f4eb3f2b8b7ab49324a1.json +1 -1
  40. package/dist/cli/wp-files/latest/languages/de_DE-5251f7623766a714c8207c7edb938628.json +1 -1
  41. package/dist/cli/wp-files/latest/languages/de_DE-529362903a5a05b34b06b5e793fb4cf8.json +1 -1
  42. package/dist/cli/wp-files/latest/languages/de_DE-569e85ef168299eb8c8f24d8ef8c8a78.json +1 -1
  43. package/dist/cli/wp-files/latest/languages/de_DE-6025add6bde16aaeb12787d250f9b414.json +1 -1
  44. package/dist/cli/wp-files/latest/languages/de_DE-60d06fac6f98e8e8f0ec5a945738b660.json +1 -1
  45. package/dist/cli/wp-files/latest/languages/de_DE-68f2cec7514bf8563c723a4d675fcfe6.json +1 -1
  46. package/dist/cli/wp-files/latest/languages/de_DE-7233008897033de5ee0d14f86a42a65a.json +1 -1
  47. package/dist/cli/wp-files/latest/languages/de_DE-7289286ed59e90a8f36ae797df62220b.json +1 -1
  48. package/dist/cli/wp-files/latest/languages/de_DE-7436b7ee9e4f11ac0d618d8cc886eb66.json +1 -1
  49. package/dist/cli/wp-files/latest/languages/de_DE-77fdfadaf2e1ca3a027d1956b910bc50.json +1 -1
  50. package/dist/cli/wp-files/latest/languages/de_DE-7b74c8457eaa7fcc50db41b431f8a003.json +1 -1
  51. package/dist/cli/wp-files/latest/languages/de_DE-7c90cd4398ee2d9d3628c387a87a70e5.json +1 -1
  52. package/dist/cli/wp-files/latest/languages/de_DE-7d5ca435e60d92f024d46c9257aaa0f7.json +1 -1
  53. package/dist/cli/wp-files/latest/languages/de_DE-7f13c36c641b114bf18cd0bcc9ecc7e0.json +1 -1
  54. package/dist/cli/wp-files/latest/languages/de_DE-803bf1ce2131e13efc590c1bc47851fc.json +1 -1
  55. package/dist/cli/wp-files/latest/languages/de_DE-81c889563f09dd13de1701135dc62941.json +1 -1
  56. package/dist/cli/wp-files/latest/languages/de_DE-81d6f084cb273e02e15b01bd9ece87f7.json +1 -1
  57. package/dist/cli/wp-files/latest/languages/de_DE-8240df461220d1d3a028a9a4c5652a5b.json +1 -1
  58. package/dist/cli/wp-files/latest/languages/de_DE-8860e58c20c6a2ab5876a0f07be43bd9.json +1 -1
  59. package/dist/cli/wp-files/latest/languages/de_DE-93882e8f9976382d7f724ac595ed7151.json +1 -1
  60. package/dist/cli/wp-files/latest/languages/de_DE-947c76bb5095da30e16668eec15406b2.json +1 -1
  61. package/dist/cli/wp-files/latest/languages/de_DE-9b256ea9cd54df92095e04c76758ceb0.json +1 -1
  62. package/dist/cli/wp-files/latest/languages/de_DE-9c3519f4870fac83dc0dbf18cb6bd4c4.json +1 -1
  63. package/dist/cli/wp-files/latest/languages/de_DE-9d47a87c240c1d10701cd6a02b28aa1b.json +1 -1
  64. package/dist/cli/wp-files/latest/languages/de_DE-a25d1cc7bf7ca0b4e114f6bea64943f4.json +1 -1
  65. package/dist/cli/wp-files/latest/languages/de_DE-a2796e57f680e25d84c4b352ee6d7280.json +1 -1
  66. package/dist/cli/wp-files/latest/languages/de_DE-a9dc201dcd011fe71849743133052619.json +1 -1
  67. package/dist/cli/wp-files/latest/languages/de_DE-aabfce98c410957228848dc581e3c420.json +1 -1
  68. package/dist/cli/wp-files/latest/languages/de_DE-ac23eee47530ac63a1178c827db28087.json +1 -1
  69. package/dist/cli/wp-files/latest/languages/de_DE-bf0f094965d3d4a95b47babcb35fc136.json +1 -1
  70. package/dist/cli/wp-files/latest/languages/de_DE-bf23b24175490c2e46aaf92ff6a0c70f.json +1 -1
  71. package/dist/cli/wp-files/latest/languages/de_DE-c31d5f185753910c14afebc6deb2ce24.json +1 -1
  72. package/dist/cli/wp-files/latest/languages/de_DE-ca28138671823450e87dfd354f7afc6b.json +1 -1
  73. package/dist/cli/wp-files/latest/languages/de_DE-daeb084aab42199d26393a56c3465bc0.json +1 -1
  74. package/dist/cli/wp-files/latest/languages/de_DE-e2791ba830489d23043be8650a22a22b.json +1 -1
  75. package/dist/cli/wp-files/latest/languages/de_DE-e2e4c4b80f3adf2c70b431bfdb1b4872.json +1 -1
  76. package/dist/cli/wp-files/latest/languages/de_DE-e53526243551a102928735ec9eed4edf.json +1 -1
  77. package/dist/cli/wp-files/latest/languages/de_DE-f575f481034e90e21d832e415fd95fcf.json +1 -1
  78. package/dist/cli/wp-files/latest/languages/de_DE-f70806bf0c7d62f2908bd5a1c3fe4efc.json +1 -1
  79. package/dist/cli/wp-files/latest/languages/de_DE-f8f49d9fc4a9cf7d78ec99285417bd9c.json +1 -1
  80. package/dist/cli/wp-files/latest/languages/de_DE.l10n.php +27 -27
  81. package/dist/cli/wp-files/latest/languages/pl_PL-0cc31205f20441b3df1d1b46100f6b8d.json +1 -1
  82. package/dist/cli/wp-files/latest/languages/pl_PL-0eebe503220d4a00341eb011b92769b4.json +1 -1
  83. package/dist/cli/wp-files/latest/languages/pl_PL-1c4303f02ff93b290e9faad991eeb06f.json +1 -1
  84. package/dist/cli/wp-files/latest/languages/pl_PL-1d17475f620f63a92e2c5d2681c51ee8.json +1 -1
  85. package/dist/cli/wp-files/latest/languages/pl_PL-2b390f85a3048c5b4255fb45960b6514.json +1 -1
  86. package/dist/cli/wp-files/latest/languages/pl_PL-4a38fe1c0c45989e44682ba6109d9f46.json +1 -1
  87. package/dist/cli/wp-files/latest/languages/pl_PL-4bfa11da57ff2600004bb500368247f4.json +1 -1
  88. package/dist/cli/wp-files/latest/languages/pl_PL-50278328b502f4eb3f2b8b7ab49324a1.json +1 -1
  89. package/dist/cli/wp-files/latest/languages/pl_PL-5251f7623766a714c8207c7edb938628.json +1 -1
  90. package/dist/cli/wp-files/latest/languages/pl_PL-529362903a5a05b34b06b5e793fb4cf8.json +1 -1
  91. package/dist/cli/wp-files/latest/languages/pl_PL-569e85ef168299eb8c8f24d8ef8c8a78.json +1 -1
  92. package/dist/cli/wp-files/latest/languages/pl_PL-6025add6bde16aaeb12787d250f9b414.json +1 -1
  93. package/dist/cli/wp-files/latest/languages/pl_PL-7436b7ee9e4f11ac0d618d8cc886eb66.json +1 -1
  94. package/dist/cli/wp-files/latest/languages/pl_PL-77fdfadaf2e1ca3a027d1956b910bc50.json +1 -1
  95. package/dist/cli/wp-files/latest/languages/pl_PL-7b74c8457eaa7fcc50db41b431f8a003.json +1 -1
  96. package/dist/cli/wp-files/latest/languages/pl_PL-7d5ca435e60d92f024d46c9257aaa0f7.json +1 -1
  97. package/dist/cli/wp-files/latest/languages/pl_PL-81d6f084cb273e02e15b01bd9ece87f7.json +1 -1
  98. package/dist/cli/wp-files/latest/languages/pl_PL-8240df461220d1d3a028a9a4c5652a5b.json +1 -1
  99. package/dist/cli/wp-files/latest/languages/pl_PL-9b256ea9cd54df92095e04c76758ceb0.json +1 -1
  100. package/dist/cli/wp-files/latest/languages/pl_PL-9c3519f4870fac83dc0dbf18cb6bd4c4.json +1 -1
  101. package/dist/cli/wp-files/latest/languages/pl_PL-9d47a87c240c1d10701cd6a02b28aa1b.json +1 -1
  102. package/dist/cli/wp-files/latest/languages/pl_PL-a9dc201dcd011fe71849743133052619.json +1 -1
  103. package/dist/cli/wp-files/latest/languages/pl_PL-aabfce98c410957228848dc581e3c420.json +1 -1
  104. package/dist/cli/wp-files/latest/languages/pl_PL-ca28138671823450e87dfd354f7afc6b.json +1 -1
  105. package/dist/cli/wp-files/latest/languages/pl_PL-e2e4c4b80f3adf2c70b431bfdb1b4872.json +1 -1
  106. package/dist/cli/wp-files/sqlite-command/composer.json +4 -3
  107. package/dist/cli/wp-files/sqlite-command/composer.lock +132 -80
  108. package/dist/cli/wp-files/sqlite-command/vendor/autoload.php +1 -1
  109. package/dist/cli/wp-files/sqlite-command/vendor/composer/autoload_classmap.php +58 -70
  110. package/dist/cli/wp-files/sqlite-command/vendor/composer/autoload_namespaces.php +1 -0
  111. package/dist/cli/wp-files/sqlite-command/vendor/composer/autoload_psr4.php +1 -1
  112. package/dist/cli/wp-files/sqlite-command/vendor/composer/autoload_real.php +5 -5
  113. package/dist/cli/wp-files/sqlite-command/vendor/composer/autoload_static.php +78 -80
  114. package/dist/cli/wp-files/sqlite-command/vendor/composer/installed.json +104 -49
  115. package/dist/cli/wp-files/sqlite-command/vendor/composer/installed.php +29 -16
  116. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/CHANGELOG.md +103 -0
  117. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Comparator/Comparator.php +62 -0
  118. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Comparator/DateComparator.php +50 -0
  119. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Comparator/NumberComparator.php +78 -0
  120. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Exception/AccessDeniedException.php +19 -0
  121. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Exception/DirectoryNotFoundException.php +19 -0
  122. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Finder.php +851 -0
  123. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Gitignore.php +91 -0
  124. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Glob.php +116 -0
  125. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/CustomFilterIterator.php +61 -0
  126. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php +58 -0
  127. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php +48 -0
  128. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php +110 -0
  129. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php +51 -0
  130. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php +58 -0
  131. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/FilenameFilterIterator.php +45 -0
  132. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/LazyIterator.php +32 -0
  133. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php +107 -0
  134. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/PathFilterIterator.php +56 -0
  135. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php +134 -0
  136. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php +57 -0
  137. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/SortableIterator.php +115 -0
  138. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php +173 -0
  139. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/LICENSE +19 -0
  140. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/README.md +14 -0
  141. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/SplFileInfo.php +80 -0
  142. package/dist/cli/wp-files/sqlite-command/vendor/symfony/finder/composer.json +31 -0
  143. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/mustache/.gitattributes +8 -0
  144. package/dist/cli/wp-files/sqlite-command/vendor/{mustache → wp-cli}/mustache/LICENSE +1 -1
  145. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/mustache/README.md +76 -0
  146. package/dist/cli/wp-files/sqlite-command/vendor/{mustache → wp-cli}/mustache/composer.json +6 -16
  147. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/mustache/src/Mustache/Autoloader.php +88 -0
  148. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Cache/AbstractCache.php +7 -15
  149. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Cache/FilesystemCache.php +15 -20
  150. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Cache/NoopCache.php +4 -8
  151. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Cache.php +7 -10
  152. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Compiler.php +87 -144
  153. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Context.php +19 -23
  154. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Engine.php +134 -251
  155. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Exception/InvalidArgumentException.php +2 -6
  156. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Exception/LogicException.php +2 -6
  157. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Exception/RuntimeException.php +2 -6
  158. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Exception/SyntaxException.php +8 -7
  159. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Exception/UnknownFilterException.php +7 -7
  160. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Exception/UnknownHelperException.php +7 -7
  161. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Exception/UnknownTemplateException.php +7 -7
  162. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Exception.php +5 -4
  163. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/HelperCollection.php +17 -22
  164. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/LambdaHelper.php +8 -28
  165. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Loader/ArrayLoader.php +9 -12
  166. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Loader/CascadingLoader.php +15 -18
  167. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Loader/FilesystemLoader.php +18 -24
  168. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Loader/InlineLoader.php +13 -19
  169. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Loader/MutableLoader.php +7 -4
  170. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Loader/ProductionFilesystemLoader.php +16 -23
  171. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Loader/StringLoader.php +4 -8
  172. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Loader.php +7 -8
  173. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Logger/AbstractLogger.php +26 -22
  174. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Logger/StreamLogger.php +20 -25
  175. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Logger.php +37 -13
  176. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Parser.php +93 -100
  177. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Source/FilesystemSource.php +7 -11
  178. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Source.php +5 -4
  179. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Template.php +32 -39
  180. package/dist/cli/wp-files/sqlite-command/vendor/{mustache/mustache/src → wp-cli/mustache/src/Mustache}/Tokenizer.php +29 -33
  181. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/.actrc +3 -0
  182. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/.gitattributes +6 -0
  183. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/.mailmap +234 -0
  184. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/README.md +4 -4
  185. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/VERSION +1 -1
  186. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/CHANGELOG.md +0 -65
  187. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/README.md +1 -2
  188. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/certificates/cacert.pem +372 -315
  189. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/certificates/cacert.pem.sha256 +1 -1
  190. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/composer.json +5 -7
  191. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Iri.php +18 -20
  192. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Requests.php +1 -1
  193. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Response/Headers.php +1 -1
  194. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Transport/Curl.php +1 -5
  195. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Transport/Fsockopen.php +0 -2
  196. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Utility/CaseInsensitiveDictionary.php +0 -12
  197. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Utility/FilteredIterator.php +2 -2
  198. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/composer.json +13 -30
  199. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/dependencies.yml +6 -0
  200. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/manifest.json +1 -1
  201. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Autoloader.php +2 -4
  202. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/AutoloaderStep.php +1 -10
  203. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/CheckRoot.php +2 -20
  204. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/DefineProtectedCommands.php +3 -3
  205. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludeFrameworkAutoloader.php +4 -3
  206. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludeRequestsAutoloader.php +3 -4
  207. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/InitializeContexts.php +0 -3
  208. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/InitializeLogger.php +1 -1
  209. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php +3 -6
  210. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/{RegisterShutdownHandler.php → LoadDispatcher.php} +4 -6
  211. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LoadRequiredCommand.php +5 -9
  212. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LoadUtilityFunctions.php +0 -1
  213. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Completions.php +6 -149
  214. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Configurator.php +49 -202
  215. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Context/Admin.php +21 -113
  216. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Context/Auto.php +1 -1
  217. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Context/Cli.php +1 -0
  218. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Context/Frontend.php +1 -0
  219. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandFactory.php +26 -63
  220. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CompositeCommand.php +9 -19
  221. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/Subcommand.php +19 -284
  222. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/DocParser.php +5 -17
  223. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Exception/NonExistentKeyException.php +3 -6
  224. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Extractor.php +54 -30
  225. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Fetchers/Base.php +3 -7
  226. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Fetchers/Comment.php +2 -4
  227. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Fetchers/Post.php +3 -8
  228. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Fetchers/Signup.php +1 -3
  229. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Fetchers/Site.php +4 -12
  230. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Fetchers/User.php +1 -3
  231. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/FileCache.php +33 -135
  232. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Formatter.php +57 -221
  233. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Inflector.php +4 -4
  234. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Iterators/CSV.php +1 -6
  235. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Iterators/Query.php +1 -3
  236. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Iterators/Table.php +1 -7
  237. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Iterators/Transform.php +0 -2
  238. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Loggers/Base.php +0 -15
  239. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Loggers/Quiet.php +3 -2
  240. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Loggers/Regular.php +3 -4
  241. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/NoOp.php +0 -4
  242. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Process.php +7 -40
  243. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/RequestsLibrary.php +1 -4
  244. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php +234 -795
  245. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/SynopsisParser.php +26 -116
  246. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/SynopsisValidator.php +1 -1
  247. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Traverser/RecursiveDataStructureTraverser.php +26 -69
  248. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/UpgraderSkin.php +1 -1
  249. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/WpHttpCacheManager.php +5 -67
  250. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/WpOrgApi.php +3 -3
  251. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/boot-fs.php +2 -2
  252. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/bootstrap.php +2 -5
  253. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/class-wp-cli.php +62 -311
  254. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/commands/src/CLI_Alias_Command.php +60 -292
  255. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/commands/src/CLI_Cache_Command.php +1 -1
  256. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php +31 -191
  257. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/commands/src/Help_Command.php +35 -177
  258. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/config-spec.php +4 -28
  259. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/utils-wp.php +47 -81
  260. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/utils.php +200 -512
  261. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/wp-cli.php +2 -2
  262. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/wp-settings-cli.php +465 -0
  263. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/templates/man-params.mustache +4 -0
  264. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/templates/man.mustache +0 -8
  265. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/ArgValidationTest.php +74 -0
  266. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/CommandFactoryTest.php +420 -0
  267. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/ConfiguratorTest.php +87 -0
  268. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/DocParserTest.php +213 -0
  269. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/ExtractorTest.php +293 -0
  270. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/FileCacheTest.php +207 -0
  271. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/HelpTest.php +119 -0
  272. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/InflectorTest.php +37 -0
  273. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/LoggingTest.php +124 -0
  274. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/ProcessTest.php +30 -0
  275. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/SynopsisParserTest.php +194 -0
  276. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/UtilsTest.php +1092 -0
  277. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/WPCLITest.php +16 -0
  278. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/WP_CLI/Iterators/CSVTest.php +109 -0
  279. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/WP_CLI/Traversers/RecursiveDataStructureTraverserTest.php +151 -0
  280. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/WP_CLI/WpOrgApiTest.php +166 -0
  281. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/WpVersionCompareTest.php +78 -0
  282. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/bootstrap.php +17 -0
  283. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/data/commandfactory-doc_comment-class-win.php +70 -0
  284. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/data/commandfactory-doc_comment-class.php +70 -0
  285. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/data/commandfactory-doc_comment-function-win.php +19 -0
  286. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/data/commandfactory-doc_comment-function.php +19 -0
  287. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/data/expand_globs/bar.ab2 +0 -0
  288. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/data/expand_globs/baz.ab1 +0 -0
  289. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/data/expand_globs/baz.ac1 +0 -0
  290. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/data/expand_globs/baz.efg2 +0 -0
  291. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/data/expand_globs/foo.ab1 +0 -0
  292. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/data/expand_globs/foo.ab2 +0 -0
  293. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/data/expand_globs/foo.efg1 +0 -0
  294. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/data/expand_globs/foo.efg2 +0 -0
  295. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/tests/mock-requests-transport.php +34 -0
  296. package/dist/cli/wp-files/sqlite-command/version +1 -1
  297. package/package.json +4 -3
  298. package/patches/archiver+7.0.1.patch +14 -0
  299. package/dist/cli/wp-files/sqlite-command/vendor/mustache/mustache/.php-cs-fixer.php +0 -20
  300. package/dist/cli/wp-files/sqlite-command/vendor/mustache/mustache/README.md +0 -94
  301. package/dist/cli/wp-files/sqlite-command/vendor/mustache/mustache/src/RenderedString.php +0 -51
  302. package/dist/cli/wp-files/sqlite-command/vendor/mustache/mustache/src/compat.php +0 -282
  303. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/.typos.toml +0 -14
  304. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/AGENTS.md +0 -121
  305. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/scripts/proxy/proxy.py +0 -5
  306. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/scripts/proxy/start.sh +0 -19
  307. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/bundle/rmccue/requests/scripts/proxy/stop.sh +0 -10
  308. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Path.php +0 -260
  309. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/ShutdownHandler.php +0 -329
  310. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/schemas/wp-cli-config.json +0 -218
  311. package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/schemas/wp-cli.example.yml +0 -55
  312. /package/dist/cli/wp-files/sqlite-command/vendor/wp-cli/wp-cli/{codecov.yml → tests/data/expand_globs/bar.ab1} +0 -0
@@ -0,0 +1,1092 @@
1
+ <?php
2
+
3
+ use WP_CLI\ExitException;
4
+ use WP_CLI\Loggers;
5
+ use WP_CLI\Tests\TestCase;
6
+ use WP_CLI\Utils;
7
+
8
+ class UtilsTest extends TestCase {
9
+
10
+ public static function set_up_before_class() {
11
+ require_once dirname( __DIR__ ) . '/php/class-wp-cli.php';
12
+ require_once __DIR__ . '/mock-requests-transport.php';
13
+ }
14
+
15
+ public function testIncrementVersion() {
16
+ // Keyword increments.
17
+ $this->assertEquals(
18
+ Utils\increment_version( '1.2.3-pre', 'same' ),
19
+ '1.2.3-pre'
20
+ );
21
+
22
+ $this->assertEquals(
23
+ Utils\increment_version( '1.2.3-pre', 'patch' ),
24
+ '1.2.4'
25
+ );
26
+
27
+ $this->assertEquals(
28
+ Utils\increment_version( '1.2.3-pre', 'minor' ),
29
+ '1.3.0'
30
+ );
31
+
32
+ $this->assertEquals(
33
+ Utils\increment_version( '1.2.3-pre', 'major' ),
34
+ '2.0.0'
35
+ );
36
+
37
+ // Custom version string.
38
+ $this->assertEquals(
39
+ Utils\increment_version( '1.2.3-pre', '4.5.6-alpha1' ),
40
+ '4.5.6-alpha1'
41
+ );
42
+ }
43
+
44
+ public function testGetSemVer() {
45
+ $original_version = '0.19.1';
46
+ $this->assertEmpty( Utils\get_named_sem_ver( '0.18.0', $original_version ) );
47
+ $this->assertEmpty( Utils\get_named_sem_ver( '0.19.1', $original_version ) );
48
+ $this->assertEmpty( Utils\get_named_sem_ver( 'nonsense', $original_version ) );
49
+ $this->assertEmpty( Utils\get_named_sem_ver( '0.18.1-beta3', $original_version ) );
50
+ $this->assertEmpty( Utils\get_named_sem_ver( '0.19.1-dev1', $original_version ) );
51
+ $this->assertEmpty( Utils\get_named_sem_ver( '0.19.1-beta3', $original_version ) );
52
+ $this->assertEmpty( Utils\get_named_sem_ver( '0.19.2-dev1', $original_version ) ); // -dev suffix not accepted by SemVer.
53
+ $this->assertEquals( 'patch', Utils\get_named_sem_ver( '0.19.2-beta3', $original_version ) );
54
+ $this->assertEquals( 'patch', Utils\get_named_sem_ver( '0.19.2', $original_version ) );
55
+ $this->assertEquals( 'minor', Utils\get_named_sem_ver( '0.20.0', $original_version ) );
56
+ $this->assertEquals( 'minor', Utils\get_named_sem_ver( '0.20.3', $original_version ) );
57
+ $this->assertEquals( 'major', Utils\get_named_sem_ver( '1.0.0', $original_version ) );
58
+ $this->assertEquals( 'major', Utils\get_named_sem_ver( '1.1.1', $original_version ) );
59
+ }
60
+
61
+ public function testGetSemVerWP() {
62
+ $original_version = '3.0';
63
+ $this->assertEmpty( Utils\get_named_sem_ver( '2.8', $original_version ) );
64
+ $this->assertEmpty( Utils\get_named_sem_ver( '2.9.1', $original_version ) );
65
+ $this->assertEmpty( Utils\get_named_sem_ver( 'nonsense', $original_version ) );
66
+ $this->assertEmpty( Utils\get_named_sem_ver( '2.0-beta3', $original_version ) );
67
+ $this->assertEmpty( Utils\get_named_sem_ver( '3.0-dev1', $original_version ) );
68
+ $this->assertEmpty( Utils\get_named_sem_ver( '3.0-beta3', $original_version ) );
69
+ $this->assertEmpty( Utils\get_named_sem_ver( '3.0.1-dev1', $original_version ) ); // -dev suffix not accepted by SemVer.
70
+ $this->assertEquals( 'patch', Utils\get_named_sem_ver( '3.0.1-beta3', $original_version ) );
71
+ $this->assertEquals( 'patch', Utils\get_named_sem_ver( '3.0.1', $original_version ) );
72
+ $this->assertEquals( 'minor', Utils\get_named_sem_ver( '3.1-beta3', $original_version ) );
73
+ $this->assertEquals( 'minor', Utils\get_named_sem_ver( '3.1', $original_version ) );
74
+ $this->assertEquals( 'minor', Utils\get_named_sem_ver( '3.1.1', $original_version ) );
75
+ $this->assertEquals( 'major', Utils\get_named_sem_ver( '4.0', $original_version ) );
76
+ $this->assertEquals( 'major', Utils\get_named_sem_ver( '4.1.1', $original_version ) );
77
+ }
78
+
79
+ public function testParseSSHUrl() {
80
+ $testcase = 'foo';
81
+ $this->assertEquals( [ 'host' => 'foo' ], Utils\parse_ssh_url( $testcase ) );
82
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
83
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
84
+ $this->assertEquals( 'foo', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
85
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
86
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
87
+
88
+ $testcase = 'foo.com';
89
+ $this->assertEquals( [ 'host' => 'foo.com' ], Utils\parse_ssh_url( $testcase ) );
90
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
91
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
92
+ $this->assertEquals( 'foo.com', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
93
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
94
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
95
+
96
+ $testcase = 'foo.com:2222';
97
+ $expected = [
98
+ 'host' => 'foo.com',
99
+ 'port' => 2222,
100
+ ];
101
+ $this->assertEquals( $expected, Utils\parse_ssh_url( $testcase ) );
102
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
103
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
104
+ $this->assertEquals( 'foo.com', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
105
+ $this->assertEquals( 2222, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
106
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
107
+
108
+ $testcase = 'foo.com:2222/path/to/dir';
109
+ $expected = [
110
+ 'host' => 'foo.com',
111
+ 'port' => 2222,
112
+ 'path' => '/path/to/dir',
113
+ ];
114
+ $this->assertEquals( $expected, Utils\parse_ssh_url( $testcase ) );
115
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
116
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
117
+ $this->assertEquals( 'foo.com', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
118
+ $this->assertEquals( 2222, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
119
+ $this->assertEquals( '/path/to/dir', Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
120
+
121
+ $testcase = 'foo.com~/path/to/dir';
122
+ $expected = [
123
+ 'host' => 'foo.com',
124
+ 'path' => '~/path/to/dir',
125
+ ];
126
+ $this->assertEquals( $expected, Utils\parse_ssh_url( $testcase ) );
127
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
128
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
129
+ $this->assertEquals( 'foo.com', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
130
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
131
+ $this->assertEquals( '~/path/to/dir', Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
132
+
133
+ // No host.
134
+ $testcase = '~/path/to/dir';
135
+ $this->assertEquals( [], Utils\parse_ssh_url( $testcase ) );
136
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
137
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
138
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
139
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
140
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
141
+
142
+ // Host and path, no port, with scp notation.
143
+ $testcase = 'foo.com:~/path/to/dir';
144
+ $expected = [
145
+ 'host' => 'foo.com',
146
+ 'path' => '~/path/to/dir',
147
+ ];
148
+ $this->assertEquals( $expected, Utils\parse_ssh_url( $testcase ) );
149
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
150
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
151
+ $this->assertEquals( 'foo.com', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
152
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
153
+ $this->assertEquals( '~/path/to/dir', Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
154
+
155
+ $testcase = 'foo.com:2222~/path/to/dir';
156
+ $expected = [
157
+ 'host' => 'foo.com',
158
+ 'path' => '~/path/to/dir',
159
+ 'port' => '2222',
160
+ ];
161
+ $this->assertEquals( $expected, Utils\parse_ssh_url( $testcase ) );
162
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
163
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
164
+ $this->assertEquals( 'foo.com', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
165
+ $this->assertEquals( '2222', Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
166
+ $this->assertEquals( '~/path/to/dir', Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
167
+
168
+ // Explicit scheme, user, host, path, no port.
169
+ $testcase = 'ssh:bar@foo.com:~/path/to/dir';
170
+ $expected = [
171
+ 'scheme' => 'ssh',
172
+ 'user' => 'bar',
173
+ 'host' => 'foo.com',
174
+ 'path' => '~/path/to/dir',
175
+ ];
176
+ $this->assertEquals( $expected, Utils\parse_ssh_url( $testcase ) );
177
+ $this->assertEquals( 'ssh', Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
178
+ $this->assertEquals( 'bar', Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
179
+ $this->assertEquals( 'foo.com', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
180
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
181
+ $this->assertEquals( '~/path/to/dir', Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
182
+
183
+ // Container scheme
184
+ $testcase = 'docker:wordpress';
185
+ $expected = [
186
+ 'scheme' => 'docker',
187
+ 'host' => 'wordpress',
188
+ ];
189
+ $this->assertEquals( $expected, Utils\parse_ssh_url( $testcase ) );
190
+ $this->assertEquals( 'docker', Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
191
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
192
+ $this->assertEquals( 'wordpress', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
193
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
194
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
195
+
196
+ // Container scheme with user, and host.
197
+ $testcase = 'docker:bar@wordpress';
198
+ $expected = [
199
+ 'scheme' => 'docker',
200
+ 'user' => 'bar',
201
+ 'host' => 'wordpress',
202
+ ];
203
+ $this->assertEquals( $expected, Utils\parse_ssh_url( $testcase ) );
204
+ $this->assertEquals( 'docker', Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
205
+ $this->assertEquals( 'bar', Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
206
+ $this->assertEquals( 'wordpress', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
207
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
208
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
209
+
210
+ // Container scheme with user, host, and path.
211
+ $testcase = 'docker-compose:bar@wordpress:~/path/to/dir';
212
+ $expected = [
213
+ 'scheme' => 'docker-compose',
214
+ 'user' => 'bar',
215
+ 'host' => 'wordpress',
216
+ 'path' => '~/path/to/dir',
217
+ ];
218
+ $this->assertEquals( $expected, Utils\parse_ssh_url( $testcase ) );
219
+ $this->assertEquals( 'docker-compose', Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
220
+ $this->assertEquals( 'bar', Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
221
+ $this->assertEquals( 'wordpress', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
222
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
223
+ $this->assertEquals( '~/path/to/dir', Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
224
+
225
+ // Container scheme with user, host, and path.
226
+ $testcase = 'docker-compose-run:bar@wordpress:~/path/to/dir';
227
+ $expected = [
228
+ 'scheme' => 'docker-compose-run',
229
+ 'user' => 'bar',
230
+ 'host' => 'wordpress',
231
+ 'path' => '~/path/to/dir',
232
+ ];
233
+ $this->assertEquals( $expected, Utils\parse_ssh_url( $testcase ) );
234
+ $this->assertEquals( 'docker-compose-run', Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
235
+ $this->assertEquals( 'bar', Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
236
+ $this->assertEquals( 'wordpress', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
237
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
238
+ $this->assertEquals( '~/path/to/dir', Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
239
+
240
+ // Vagrant scheme.
241
+ $testcase = 'vagrant:default';
242
+ $expected = [
243
+ 'scheme' => 'vagrant',
244
+ 'host' => 'default',
245
+ ];
246
+ $this->assertEquals( $expected, Utils\parse_ssh_url( $testcase ) );
247
+ $this->assertEquals( 'vagrant', Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
248
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
249
+ $this->assertEquals( 'default', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
250
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
251
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
252
+
253
+ // Vagrant scheme.
254
+ $testcase = 'vagrant:/var/www/html';
255
+ $expected = [
256
+ 'scheme' => 'vagrant',
257
+ 'host' => '',
258
+ 'path' => '/var/www/html',
259
+ ];
260
+ $this->assertEquals( $expected, Utils\parse_ssh_url( $testcase ) );
261
+ $this->assertEquals( 'vagrant', Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
262
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
263
+ $this->assertEquals( '', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
264
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
265
+ $this->assertEquals( '/var/www/html', Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
266
+
267
+ // Unsupported scheme, should not match.
268
+ $testcase = 'foo:bar';
269
+ $this->assertEquals( [], Utils\parse_ssh_url( $testcase ) );
270
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_SCHEME ) );
271
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_USER ) );
272
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) );
273
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) );
274
+ $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) );
275
+ }
276
+
277
+ public static function parseStrToArgvData() {
278
+ return [
279
+ [ [], '' ],
280
+ [ [ 'option', 'get', 'home' ], 'option get home' ],
281
+ [ [ 'core', 'download', '--path=/var/www/' ], 'core download --path=/var/www/' ],
282
+ [ [ 'eval', 'echo wp_get_current_user()->user_login;' ], 'eval "echo wp_get_current_user()->user_login;"' ],
283
+ [ [ 'post', 'create', '--post_title="Hello world!"' ], 'post create --post_title="Hello world!"' ],
284
+ [ [ 'post', 'create', '--post_title=\'Mixed "quotes are working" hopefully\'' ], 'post create --post_title=\'Mixed "quotes are working" hopefully\'' ],
285
+ [ [ 'post', 'create', '--post_title="Escaped \"double \"quotes!"' ], 'post create --post_title="Escaped \"double \"quotes!"' ],
286
+ [ [ 'post', 'create', "--post_title='Escaped \'single \'quotes!'" ], "post create --post_title='Escaped \'single \'quotes!'" ],
287
+ [ [ 'search-replace', '//old-domain.com', '//new-domain.com', 'specifictable', '--all-tables' ], 'search-replace "//old-domain.com" "//new-domain.com" "specifictable" --all-tables' ],
288
+ [ [ 'i18n', 'make-pot', '/home/wporgdev/co/wordpress/trunk', '/home/wporgdev/co/wp-pot/trunk/wordpress-continents-cities.pot', '--include="wp-admin/includes/continents-cities.php"', "--package-name='WordPress'", '--headers=\'{"Report-Msgid-Bugs-To":"https://core.trac.wordpress.org/"}\'', "--file-comment='Copyright (C) 2019 by the contributors\nThis file is distributed under the same license as the WordPress package.'", '--skip-js', '--skip-audit', '--ignore-domain' ], "i18n make-pot '/home/wporgdev/co/wordpress/trunk' '/home/wporgdev/co/wp-pot/trunk/wordpress-continents-cities.pot' --include=\"wp-admin/includes/continents-cities.php\" --package-name='WordPress' --headers='{\"Report-Msgid-Bugs-To\":\"https://core.trac.wordpress.org/\"}' --file-comment='Copyright (C) 2019 by the contributors\nThis file is distributed under the same license as the WordPress package.' --skip-js --skip-audit --ignore-domain" ],
289
+ ];
290
+ }
291
+
292
+ /**
293
+ * @dataProvider parseStrToArgvData
294
+ */
295
+ public function testParseStrToArgv( $expected, $parseable_string ) {
296
+ $this->assertEquals( $expected, Utils\parse_str_to_argv( $parseable_string ) );
297
+ }
298
+
299
+ public function testAssocArgsToString() {
300
+ // Strip quotes for Windows compat.
301
+ $strip_quotes = function ( $str ) {
302
+ return str_replace( [ '"', "'" ], '', $str );
303
+ };
304
+
305
+ $expected = " --url='foo.dev' --porcelain --apple='banana'";
306
+ $input = [
307
+ 'url' => 'foo.dev',
308
+ 'porcelain' => true,
309
+ 'apple' => 'banana',
310
+ ];
311
+ $actual = Utils\assoc_args_to_str( $input );
312
+ $this->assertSame( $strip_quotes( $expected ), $strip_quotes( $actual ) );
313
+
314
+ $expected = " --url='foo.dev' --require='file-a.php' --require='file-b.php' --porcelain --apple='banana'";
315
+ $input = [
316
+ 'url' => 'foo.dev',
317
+ 'require' => [
318
+ 'file-a.php',
319
+ 'file-b.php',
320
+ ],
321
+ 'porcelain' => true,
322
+ 'apple' => 'banana',
323
+ ];
324
+ $actual = Utils\assoc_args_to_str( $input );
325
+ $this->assertSame( $strip_quotes( $expected ), $strip_quotes( $actual ) );
326
+ }
327
+
328
+ public function testMysqlHostToCLIArgs() {
329
+ // Test hostname only, with and without 'p:' modifier.
330
+ $expected = [
331
+ 'host' => 'hostname',
332
+ ];
333
+ $testcase = 'hostname';
334
+ $this->assertEquals( $expected, Utils\mysql_host_to_cli_args( $testcase ) );
335
+
336
+ $testcase = 'p:hostname';
337
+ $this->assertEquals( $expected, Utils\mysql_host_to_cli_args( $testcase ) );
338
+
339
+ // Test hostname with port number, with and without 'p:' modifier
340
+ $expected = [
341
+ 'host' => 'hostname',
342
+ 'port' => 3306,
343
+ 'protocol' => 'tcp',
344
+ ];
345
+ $testcase = 'hostname:3306';
346
+ $this->assertEquals( $expected, Utils\mysql_host_to_cli_args( $testcase ) );
347
+
348
+ $testcase = 'p:hostname:3306';
349
+ $this->assertEquals( $expected, Utils\mysql_host_to_cli_args( $testcase ) );
350
+
351
+ // Test hostname with socket path, with and without 'p:' modifier.
352
+ $expected = [
353
+ 'host' => 'hostname',
354
+ 'socket' => '/path/to/socket',
355
+ ];
356
+ $testcase = 'hostname:/path/to/socket';
357
+ $this->assertEquals( $expected, Utils\mysql_host_to_cli_args( $testcase ) );
358
+
359
+ $testcase = 'p:hostname:/path/to/socket';
360
+ $this->assertEquals( $expected, Utils\mysql_host_to_cli_args( $testcase ) );
361
+ }
362
+
363
+ public function testForceEnvOnNixSystems() {
364
+ $env_is_windows = getenv( 'WP_CLI_TEST_IS_WINDOWS' );
365
+
366
+ putenv( 'WP_CLI_TEST_IS_WINDOWS=0' );
367
+ $this->assertSame( '/usr/bin/env cmd', Utils\force_env_on_nix_systems( 'cmd' ) );
368
+ $this->assertSame( '/usr/bin/env cmd', Utils\force_env_on_nix_systems( '/usr/bin/env cmd' ) );
369
+
370
+ putenv( 'WP_CLI_TEST_IS_WINDOWS=1' );
371
+ $this->assertSame( 'cmd', Utils\force_env_on_nix_systems( 'cmd' ) );
372
+ $this->assertSame( 'cmd', Utils\force_env_on_nix_systems( '/usr/bin/env cmd' ) );
373
+
374
+ putenv( false === $env_is_windows ? 'WP_CLI_TEST_IS_WINDOWS' : "WP_CLI_TEST_IS_WINDOWS=$env_is_windows" );
375
+ }
376
+
377
+ public function testGetHomeDir() {
378
+
379
+ // Save environments.
380
+ $home = getenv( 'HOME' );
381
+ $homedrive = getenv( 'HOMEDRIVE' );
382
+ $homepath = getenv( 'HOMEPATH' );
383
+
384
+ putenv( 'HOME=/home/user' );
385
+ $this->assertSame( '/home/user', Utils\get_home_dir() );
386
+
387
+ putenv( 'HOME' );
388
+
389
+ putenv( 'HOMEDRIVE=D:' );
390
+ putenv( 'HOMEPATH' );
391
+ $this->assertSame( 'D:', Utils\get_home_dir() );
392
+
393
+ putenv( 'HOMEPATH=\\Windows\\User\\' );
394
+ $this->assertSame( 'D:\\Windows\\User', Utils\get_home_dir() );
395
+
396
+ putenv( 'HOMEPATH=\\Windows\\User\\HOGE\\' );
397
+ $this->assertSame( 'D:\\Windows\\User\\HOGE', Utils\get_home_dir() );
398
+
399
+ // Restore environments.
400
+ putenv( false === $home ? 'HOME' : "HOME=$home" );
401
+ putenv( false === $homedrive ? 'HOMEDRIVE' : "HOME=$homedrive" );
402
+ putenv( false === $homepath ? 'HOMEPATH' : "HOME=$homepath" );
403
+ }
404
+
405
+ public function testTrailingslashit() {
406
+ $this->assertSame( 'a/', Utils\trailingslashit( 'a' ) );
407
+ $this->assertSame( 'a/', Utils\trailingslashit( 'a/' ) );
408
+ $this->assertSame( 'a/', Utils\trailingslashit( 'a\\' ) );
409
+ $this->assertSame( 'a/', Utils\trailingslashit( 'a\\//\\' ) );
410
+ }
411
+
412
+ /**
413
+ * @dataProvider dataNormalizePath
414
+ */
415
+ public function testNormalizePath( $path, $expected ) {
416
+ $this->assertEquals( $expected, Utils\normalize_path( $path ) );
417
+ }
418
+
419
+ public static function dataNormalizePath() {
420
+ return [
421
+ [ '', '' ],
422
+ // Windows paths.
423
+ [ 'C:\\www\\path\\', 'C:/www/path/' ],
424
+ [ 'C:\\www\\\\path\\', 'C:/www/path/' ],
425
+ [ 'c:/www/path', 'C:/www/path' ],
426
+ [ 'c:\\www\\path\\', 'C:/www/path/' ], // Uppercase drive letter.
427
+ [ 'c:', 'C:' ],
428
+ [ 'c:\\', 'C:/' ],
429
+ [ 'c:\\\\www\\path\\', 'C:/www/path/' ],
430
+ [ '\\\\Domain\\DFSRoots\\share\\path\\', '//Domain/DFSRoots/share/path/' ],
431
+ [ '\\\\Server\\share\\path', '//Server/share/path' ],
432
+ [ '\\\\Server\\share', '//Server/share' ],
433
+ // Linux paths.
434
+ [ '/', '/' ],
435
+ [ '/www/path/', '/www/path/' ],
436
+ [ '/www/path/////', '/www/path/' ],
437
+ [ '/www/path', '/www/path' ],
438
+ [ '/www/path', '/www/path' ],
439
+ ];
440
+ }
441
+
442
+ public function testNormalizeEols() {
443
+ $this->assertSame( "\na\ra\na\n", Utils\normalize_eols( "\r\na\ra\r\na\r\n" ) );
444
+ }
445
+
446
+ public function testGetTempDir() {
447
+ $this->assertTrue( '/' === substr( Utils\get_temp_dir(), -1 ) );
448
+ }
449
+
450
+ public function testHttpRequestBadAddress() {
451
+ // Save WP_CLI state.
452
+ $class_wp_cli_capture_exit = new \ReflectionProperty( 'WP_CLI', 'capture_exit' );
453
+ $class_wp_cli_capture_exit->setAccessible( true );
454
+ $prev_capture_exit = $class_wp_cli_capture_exit->getValue();
455
+
456
+ $prev_logger = WP_CLI::get_logger();
457
+
458
+ // Enable exit exception.
459
+ $class_wp_cli_capture_exit->setValue( null, true );
460
+
461
+ $logger = new Loggers\Execution();
462
+ WP_CLI::set_logger( $logger );
463
+
464
+ $exception = null;
465
+ try {
466
+ Utils\http_request( 'GET', 'https://nosuchhost_asdf_asdf_asdf.com', null /*data*/, [] /*headers*/, [ 'timeout' => 0.01 ] );
467
+ } catch ( ExitException $ex ) {
468
+ $exception = $ex;
469
+ }
470
+ $this->assertTrue( null !== $exception );
471
+ $this->assertTrue( 1 === $exception->getCode() );
472
+ $this->assertTrue( empty( $logger->stdout ) );
473
+ $this->assertTrue( false === strpos( $logger->stderr, 'Warning' ) );
474
+ $this->assertTrue( 0 === strpos( $logger->stderr, 'Error: Failed to get url' ) );
475
+
476
+ // Restore.
477
+ $class_wp_cli_capture_exit->setValue( null, $prev_capture_exit );
478
+ WP_CLI::set_logger( $prev_logger );
479
+ }
480
+
481
+ public static function dataHttpRequestBadCAcert() {
482
+ return [
483
+ 'default request' => [
484
+ [],
485
+ RuntimeException::class,
486
+ 'Failed to get url \'https://example.com\': cURL error 77: error setting certificate',
487
+ ],
488
+ 'secure request' => [
489
+ [ 'insecure' => false ],
490
+ RuntimeException::class,
491
+ 'Failed to get url \'https://example.com\': cURL error 77: error setting certificate',
492
+ ],
493
+ 'insecure request' => [
494
+ [ 'insecure' => true ],
495
+ false,
496
+ 'Warning: Re-trying without verify after failing to get verified url',
497
+ ],
498
+ ];
499
+ }
500
+
501
+ /**
502
+ * @dataProvider dataHttpRequestBadCAcert()
503
+ *
504
+ * @param array $additional_options Associative array of additional options to pass to http_request().
505
+ * @param string $exception Class of the exception to expect.
506
+ * @param string $exception_message Message of the exception to expect.
507
+ */
508
+ public function testHttpRequestBadCAcert( $additional_options, $exception, $exception_message ) {
509
+ if ( ! extension_loaded( 'curl' ) ) {
510
+ $this->markTestSkipped( 'curl not available' );
511
+ }
512
+
513
+ // Create temporary file to use as a bad certificate file.
514
+ $bad_cacert_path = tempnam( sys_get_temp_dir(), 'wp-cli-badcacert-pem-' );
515
+ file_put_contents( $bad_cacert_path, "-----BEGIN CERTIFICATE-----\nasdfasdf\n-----END CERTIFICATE-----\n" );
516
+
517
+ $options = array_merge(
518
+ [
519
+ 'halt_on_error' => false,
520
+ 'verify' => $bad_cacert_path,
521
+ ],
522
+ $additional_options
523
+ );
524
+
525
+ if ( false !== $exception ) {
526
+ $this->expectException( $exception );
527
+ $this->expectExceptionMessage( $exception_message );
528
+ } else {
529
+ // Save WP_CLI state.
530
+ $prev_logger = WP_CLI::get_logger();
531
+ $logger = new Loggers\Execution();
532
+ WP_CLI::set_logger( $logger );
533
+ }
534
+
535
+ Utils\http_request( 'GET', 'https://example.com', null, [], $options );
536
+
537
+ // Restore.
538
+ WP_CLI::set_logger( $prev_logger );
539
+
540
+ $this->assertTrue( empty( $logger->stdout ) );
541
+ $this->assertNotFalse( strpos( $logger->stderr, $exception_message ) );
542
+ }
543
+
544
+ /**
545
+ * @dataProvider dataHttpRequestVerify
546
+ */
547
+ public function testHttpRequestVerify( $expected, $options ) {
548
+ $transport_spy = new Mock_Requests_Transport();
549
+ $options['transport'] = $transport_spy;
550
+
551
+ Utils\http_request( 'GET', 'https://wordpress.org', null /*data*/, [] /*headers*/, $options );
552
+
553
+ $this->assertCount( 1, $transport_spy->requests );
554
+ $this->assertEquals( $expected, $transport_spy->requests[0]['options']['verify'] );
555
+ }
556
+
557
+ public static function dataHttpRequestVerify() {
558
+ return [
559
+ 'not passed' => [
560
+ true,
561
+ [],
562
+ ],
563
+ 'true' => [
564
+ true,
565
+ [ 'verify' => true ],
566
+ ],
567
+ 'false' => [
568
+ false,
569
+ [ 'verify' => false ],
570
+ ],
571
+ 'custom cacert' => [
572
+ __FILE__,
573
+ [ 'verify' => __FILE__ ],
574
+ ],
575
+ ];
576
+ }
577
+
578
+ public function testGetDefaultCaCert() {
579
+ $default_cert = Utils\get_default_cacert();
580
+ $this->assertStringEndsWith(
581
+ '/rmccue/requests/certificates/cacert.pem',
582
+ $default_cert
583
+ );
584
+ $this->assertFileExists( $default_cert );
585
+ }
586
+
587
+ /**
588
+ * @dataProvider dataPastTenseVerb
589
+ */
590
+ public function testPastTenseVerb( $verb, $expected ) {
591
+ $this->assertSame( $expected, Utils\past_tense_verb( $verb ) );
592
+ }
593
+
594
+ public static function dataPastTenseVerb() {
595
+ return [
596
+ // Known to be used by commands.
597
+ [ 'activate', 'activated' ],
598
+ [ 'deactivate', 'deactivated' ],
599
+ [ 'delete', 'deleted' ],
600
+ [ 'import', 'imported' ],
601
+ [ 'install', 'installed' ],
602
+ [ 'network activate', 'network activated' ],
603
+ [ 'network deactivate', 'network deactivated' ],
604
+ [ 'regenerate', 'regenerated' ],
605
+ [ 'reset', 'reset' ],
606
+ [ 'spam', 'spammed' ],
607
+ [ 'toggle', 'toggled' ],
608
+ [ 'uninstall', 'uninstalled' ],
609
+ [ 'update', 'updated' ],
610
+ // Some others.
611
+ [ 'call', 'called' ],
612
+ [ 'check', 'checked' ],
613
+ [ 'crop', 'cropped' ],
614
+ [ 'fix', 'fixed' ], // One vowel + final "x" excluded.
615
+ [ 'ah', 'ahed' ], // One vowel + final "h" excluded.
616
+ [ 'show', 'showed' ], // One vowel + final "w" excluded.
617
+ [ 'ski', 'skied' ],
618
+ [ 'slay', 'slayed' ], // One vowel + final "y" excluded (nearly all irregular anyway).
619
+ [ 'submit', 'submited' ], // BUG: multi-voweled verbs that double not catered for - should be "submitted".
620
+ [ 'try', 'tried' ],
621
+ ];
622
+ }
623
+
624
+ /**
625
+ * @dataProvider dataExpandGlobs
626
+ */
627
+ public function testExpandGlobs( $path, $expected ) {
628
+ $expand_globs_no_glob_brace = getenv( 'WP_CLI_TEST_EXPAND_GLOBS_NO_GLOB_BRACE' );
629
+
630
+ $dir = __DIR__ . '/data/expand_globs/';
631
+ $concat = function ( $v ) use ( $dir ) {
632
+ return $dir . $v;
633
+ };
634
+ $expected = array_map( $concat, $expected );
635
+ sort( $expected );
636
+
637
+ putenv( 'WP_CLI_TEST_EXPAND_GLOBS_NO_GLOB_BRACE=0' );
638
+ $out = Utils\expand_globs( $dir . $path );
639
+ sort( $out );
640
+ $this->assertSame( $expected, $out );
641
+
642
+ putenv( 'WP_CLI_TEST_EXPAND_GLOBS_NO_GLOB_BRACE=1' );
643
+ $out = Utils\expand_globs( $dir . $path );
644
+ sort( $out );
645
+ $this->assertSame( $expected, $out );
646
+
647
+ putenv( false === $expand_globs_no_glob_brace ? 'WP_CLI_TEST_EXPAND_GLOBS_NO_GLOB_BRACE' : "WP_CLI_TEST_EXPAND_GLOBS_NO_GLOB_BRACE=$expand_globs_no_glob_brace" );
648
+ }
649
+
650
+ public static function dataExpandGlobs() {
651
+ // Files in "data/expand_globs": foo.ab1, foo.ab2, foo.efg1, foo.efg2, bar.ab1, bar.ab2, baz.ab1, baz.ac1, baz.efg2.
652
+ return [
653
+ [ 'foo.ab1', [ 'foo.ab1' ] ],
654
+ [ '{foo,bar}.ab1', [ 'foo.ab1', 'bar.ab1' ] ],
655
+ [ '{foo,baz}.a{b,c}1', [ 'foo.ab1', 'baz.ab1', 'baz.ac1' ] ],
656
+ [ '{foo,baz}.{ab,ac}1', [ 'foo.ab1', 'baz.ab1', 'baz.ac1' ] ],
657
+ [ '{foo,bar}.{ab1,efg1}', [ 'foo.ab1', 'foo.efg1', 'bar.ab1' ] ],
658
+ [ '{foo,bar,baz}.{ab,ac,efg}1', [ 'foo.ab1', 'foo.efg1', 'bar.ab1', 'baz.ab1', 'baz.ac1' ] ],
659
+ [ '{foo,ba{r,z}}.ab1', [ 'foo.ab1', 'bar.ab1', 'baz.ab1' ] ],
660
+ [ '{foo,ba{r,z}}.{ab1,efg1}', [ 'foo.ab1', 'foo.efg1', 'bar.ab1', 'baz.ab1' ] ],
661
+ [ '{foo,bar}.{ab{1,2},efg1}', [ 'foo.ab1', 'foo.ab2', 'foo.efg1', 'bar.ab1', 'bar.ab2' ] ],
662
+ [ '{foo,ba{r,z}}.{a{b,c}{1,2},efg{1,2}}', [ 'foo.ab1', 'foo.ab2', 'foo.efg1', 'foo.efg2', 'bar.ab1', 'bar.ab2', 'baz.ab1', 'baz.ac1', 'baz.efg2' ] ],
663
+
664
+ [ 'no_such_file', [ 'no_such_file' ] ], // Documenting this behaviour here, which is odd (though advertized) - more natural to return an empty array.
665
+ ];
666
+ }
667
+
668
+ /**
669
+ * @dataProvider dataReportBatchOperationResults
670
+ */
671
+ public function testReportBatchOperationResults( $stdout, $stderr, $noun, $verb, $total, $successes, $failures, $skips ) {
672
+ // Save WP_CLI state.
673
+ $class_wp_cli_capture_exit = new \ReflectionProperty( 'WP_CLI', 'capture_exit' );
674
+ $class_wp_cli_capture_exit->setAccessible( true );
675
+ $prev_capture_exit = $class_wp_cli_capture_exit->getValue();
676
+
677
+ $prev_logger = WP_CLI::get_logger();
678
+
679
+ // Enable exit exception.
680
+ $class_wp_cli_capture_exit->setValue( null, true );
681
+
682
+ $logger = new Loggers\Execution();
683
+ WP_CLI::set_logger( $logger );
684
+
685
+ $exception = null;
686
+
687
+ try {
688
+ Utils\report_batch_operation_results( $noun, $verb, $total, $successes, $failures, $skips );
689
+ } catch ( ExitException $ex ) {
690
+ $exception = $ex;
691
+ }
692
+ $this->assertSame( $stdout, $logger->stdout );
693
+ $this->assertSame( $stderr, $logger->stderr );
694
+
695
+ // Restore.
696
+ $class_wp_cli_capture_exit->setValue( null, $prev_capture_exit );
697
+ WP_CLI::set_logger( $prev_logger );
698
+ }
699
+
700
+ public static function dataReportBatchOperationResults() {
701
+ return [
702
+ [ "Success: Noun already verbed.\n", '', 'noun', 'verb', 1, 0, 0, null ],
703
+ [ "Success: Verbed 1 of 1 nouns.\n", '', 'noun', 'verb', 1, 1, 0, null ],
704
+ [ "Success: Verbed 1 of 2 nouns.\n", '', 'noun', 'verb', 2, 1, 0, null ],
705
+ [ "Success: Verbed 2 of 2 nouns.\n", '', 'noun', 'verb', 2, 2, 0, 0 ],
706
+ [ "Success: Verbed 1 of 2 nouns (1 skipped).\n", '', 'noun', 'verb', 2, 1, 0, 1 ],
707
+ [ "Success: Verbed 2 of 4 nouns (2 skipped).\n", '', 'noun', 'verb', 4, 2, 0, 2 ],
708
+ [ '', "Error: No nouns verbed.\n", 'noun', 'verb', 1, 0, 1, null ],
709
+ [ '', "Error: No nouns verbed.\n", 'noun', 'verb', 2, 0, 1, null ],
710
+ [ '', "Error: No nouns verbed (2 failed).\n", 'noun', 'verb', 3, 0, 2, 0 ],
711
+ [ '', "Error: No nouns verbed (2 failed, 1 skipped).\n", 'noun', 'verb', 3, 0, 2, 1 ],
712
+ [ '', "Error: Only verbed 1 of 2 nouns.\n", 'noun', 'verb', 2, 1, 1, null ],
713
+ [ '', "Error: Only verbed 1 of 3 nouns (2 failed).\n", 'noun', 'verb', 3, 1, 2, 0 ],
714
+ [ '', "Error: Only verbed 1 of 6 nouns (3 failed, 2 skipped).\n", 'noun', 'verb', 6, 1, 3, 2 ],
715
+ ];
716
+ }
717
+
718
+ public function testGetPHPBinary() {
719
+ $env_php_used = getenv( 'WP_CLI_PHP_USED' );
720
+ $env_php = getenv( 'WP_CLI_PHP' );
721
+
722
+ putenv( 'WP_CLI_PHP_USED' );
723
+ putenv( 'WP_CLI_PHP' );
724
+ $get_php_binary = Utils\get_php_binary();
725
+ $this->assertTrue( is_executable( $get_php_binary ) );
726
+
727
+ putenv( 'WP_CLI_PHP_USED=/my-php-5.3' );
728
+ putenv( 'WP_CLI_PHP' );
729
+ $get_php_binary = Utils\get_php_binary();
730
+ $this->assertSame( $get_php_binary, '/my-php-5.3' );
731
+
732
+ putenv( 'WP_CLI_PHP=/my-php-7.3' );
733
+ $get_php_binary = Utils\get_php_binary();
734
+ $this->assertSame( $get_php_binary, '/my-php-5.3' ); // WP_CLI_PHP_USED wins.
735
+
736
+ putenv( 'WP_CLI_PHP_USED' );
737
+ $get_php_binary = Utils\get_php_binary();
738
+ $this->assertSame( $get_php_binary, '/my-php-7.3' );
739
+
740
+ putenv( false === $env_php_used ? 'WP_CLI_PHP_USED' : "WP_CLI_PHP_USED=$env_php_used" );
741
+ putenv( false === $env_php ? 'WP_CLI_PHP' : "WP_CLI_PHP=$env_php" );
742
+ }
743
+
744
+ /**
745
+ * @dataProvider dataProcOpenCompatWinEnv
746
+ */
747
+ public function testProcOpenCompatWinEnv( $cmd, $env, $expected_cmd, $expected_env ) {
748
+ $env_is_windows = getenv( 'WP_CLI_TEST_IS_WINDOWS' );
749
+
750
+ putenv( 'WP_CLI_TEST_IS_WINDOWS=1' );
751
+
752
+ $cmd = Utils\_proc_open_compat_win_env( $cmd, $env );
753
+ $this->assertSame( $expected_cmd, $cmd );
754
+ $this->assertSame( $expected_env, $env );
755
+
756
+ putenv( false === $env_is_windows ? 'WP_CLI_TEST_IS_WINDOWS' : "WP_CLI_TEST_IS_WINDOWS=$env_is_windows" );
757
+ }
758
+
759
+ public static function dataProcOpenCompatWinEnv() {
760
+ return [
761
+ [ 'echo', [], 'echo', [] ],
762
+ [ 'ENV=blah echo', [], 'echo', [ 'ENV' => 'blah' ] ],
763
+ [ 'ENV="blah blah" echo', [], 'echo', [ 'ENV' => 'blah blah' ] ],
764
+ [ 'ENV_1="blah1 blah1" ENV_2="blah2" ENV_3=blah3 echo', [], 'echo', [ 'ENV_1' => 'blah1 blah1', 'ENV_2' => 'blah2', 'ENV_3' => 'blah3' ] ],
765
+ [ 'ENV= echo', [], 'echo', [ 'ENV' => '' ] ],
766
+ [ 'ENV=0 echo', [], 'echo', [ 'ENV' => '0' ] ],
767
+
768
+ // With `$env` set.
769
+ [ 'echo', [ 'ENV' => 'in' ], 'echo', [ 'ENV' => 'in' ] ],
770
+ [ 'ENV=blah echo', [ 'ENV_1' => 'in1', 'ENV_2' => 'in2' ], 'echo', [ 'ENV_1' => 'in1', 'ENV_2' => 'in2', 'ENV' => 'blah' ] ],
771
+ [ 'ENV="blah blah" echo', [ 'ENV' => 'in' ], 'echo', [ 'ENV' => 'blah blah' ] ],
772
+
773
+ // Special cases.
774
+ [ '1=1 echo', [], '1=1 echo', [] ], // Must begin with alphabetic or underscore.
775
+ [ '_eNv=1 echo', [], 'echo', [ '_eNv' => '1' ] ], // Mixed-case and beginning with underscore allowed.
776
+ [ 'ENV=\'blah blah\' echo', [], 'blah\' echo', [ 'ENV' => '\'blah' ] ], // Unix escaping not supported, ie treated literally.
777
+ ];
778
+ }
779
+
780
+ public static function dataEscLike() {
781
+ return [
782
+ [ 'howdy%', 'howdy\\%' ],
783
+ [ 'howdy_', 'howdy\\_' ],
784
+ [ 'howdy\\', 'howdy\\\\' ],
785
+ [ 'howdy\\howdy%howdy_', 'howdy\\\\howdy\\%howdy\\_' ],
786
+ [ 'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?', 'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?' ],
787
+ ];
788
+ }
789
+
790
+ /**
791
+ * @dataProvider dataEscLike
792
+ */
793
+ public function test_esc_like( $input, $expected ) {
794
+ $this->assertEquals( $expected, Utils\esc_like( $input ) );
795
+ }
796
+
797
+ /**
798
+ * @dataProvider dataEscLike
799
+ */
800
+ public function test_esc_like_with_wpdb( $input, $expected ) {
801
+ global $wpdb;
802
+ $wpdb = $this->getMockBuilder( 'stdClass' );
803
+
804
+ // Handle different PHPUnit versions (5.7 for PHP 5.6 vs newer versions)
805
+ // This can be simplified if we drop support for PHP 5.6.
806
+ if ( method_exists( $wpdb, 'addMethods' ) ) {
807
+ $wpdb = $wpdb->addMethods( [ 'esc_like' ] );
808
+ } else {
809
+ $wpdb = $wpdb->setMethods( [ 'esc_like' ] );
810
+ }
811
+
812
+ $wpdb = $wpdb->getMock();
813
+ $wpdb->method( 'esc_like' )
814
+ ->willReturn( addcslashes( $input, '_%\\' ) );
815
+ $this->assertEquals( $expected, Utils\esc_like( $input ) );
816
+ $this->assertEquals( $expected, Utils\esc_like( $input ) );
817
+ }
818
+
819
+ /**
820
+ * @dataProvider dataEscLike
821
+ */
822
+ public function test_esc_like_with_wpdb_being_null( $input, $expected ) {
823
+ global $wpdb;
824
+ $wpdb = null;
825
+ $this->assertEquals( $expected, Utils\esc_like( $input ) );
826
+ }
827
+
828
+ /**
829
+ * @dataProvider dataIsJson
830
+ */
831
+ public function testIsJson( $argument, $ignore_scalars, $expected ) {
832
+ $this->assertEquals( $expected, Utils\is_json( $argument, $ignore_scalars ) );
833
+ }
834
+
835
+ public static function dataIsJson() {
836
+ return [
837
+ [ '42', true, false ],
838
+ [ '42', false, true ],
839
+ [ '"test"', true, false ],
840
+ [ '"test"', false, true ],
841
+ [ '{"key1":"value1","key2":"value2"}', true, true ],
842
+ [ '{"key1":"value1","key2":"value2"}', false, true ],
843
+ [ '["value1","value2"]', true, true ],
844
+ [ '["value1","value2"]', false, true ],
845
+ [ '0', true, false ],
846
+ [ '0', false, true ],
847
+ [ '', true, false ],
848
+ [ '', false, false ],
849
+ ];
850
+ }
851
+
852
+ /**
853
+ * @dataProvider dataParseShellArray
854
+ */
855
+ public function testParseShellArray( $assoc_args, $array_arguments, $expected ) {
856
+ $this->assertEquals( $expected, Utils\parse_shell_arrays( $assoc_args, $array_arguments ) );
857
+ }
858
+
859
+ public static function dataParseShellArray() {
860
+ return [
861
+ [ [ 'alpha' => '{"key":"value"}' ], [], [ 'alpha' => '{"key":"value"}' ] ],
862
+ [ [ 'alpha' => '{"key":"value"}' ], [ 'alpha' ], [ 'alpha' => [ 'key' => 'value' ] ] ],
863
+ [ [ 'alpha' => '{"key":"value"}' ], [ 'beta' ], [ 'alpha' => '{"key":"value"}' ] ],
864
+ ];
865
+ }
866
+
867
+ /**
868
+ * @dataProvider dataPluralize
869
+ */
870
+ public function testPluralize( $singular, $count, $expected ) {
871
+ $this->assertEquals( $expected, Utils\pluralize( $singular, $count ) );
872
+ }
873
+
874
+ public static function dataPluralize() {
875
+ return [
876
+ [ 'string', 1, 'string' ],
877
+ [ 'string', 2, 'strings' ],
878
+ [ 'string', null, 'strings' ],
879
+ ];
880
+ }
881
+
882
+ /**
883
+ * @dataProvider dataPickFields
884
+ */
885
+ public function testPickFields( $data, $fields, $expected ) {
886
+ $this->assertEquals( $expected, Utils\pick_fields( $data, $fields ) );
887
+ }
888
+
889
+ public static function dataPickFields() {
890
+ return [
891
+ [ [ 'keyA' => 'valA', 'keyB' => 'valB', 'keyC' => 'valC' ], [ 'keyB' ], [ 'keyB' => 'valB' ] ],
892
+ [ [ '1' => 'valA', '2' => 'valB', '3' => 'valC' ], [ '2' ], [ '2' => 'valB' ] ],
893
+ [ [ 1 => 'valA', 2 => 'valB', 3 => 'valC' ], [ 2 ], [ 2 => 'valB' ] ],
894
+ [ (object) [ 'keyA' => 'valA', 'keyB' => 'valB', 'keyC' => 'valC' ], [ 'keyB' ], [ 'keyB' => 'valB' ] ],
895
+ [ [], [ 'keyB' ], [ 'keyB' => null ] ],
896
+ [ [ 'keyA' => 'valA', 'keyB' => 'valB', 'keyC' => 'valC' ], [ 'keyD' ], [ 'keyD' => null ] ],
897
+ [ [ 'keyA' => 'valA', 'keyB' => 'valB', 'keyC' => 'valC' ], [ 'keyA', 'keyB', 'keyC', 'keyD' ], [ 'keyA' => 'valA', 'keyB' => 'valB', 'keyC' => 'valC', 'keyD' => null ] ],
898
+ ];
899
+ }
900
+
901
+ /**
902
+ * @dataProvider dataParseUrl
903
+ */
904
+ public function testParseUrl( $url, $component, $auto_add_scheme, $expected ) {
905
+ $this->assertEquals( $expected, Utils\parse_url( $url, $component, $auto_add_scheme ) );
906
+ }
907
+
908
+ public static function dataParseUrl() {
909
+ return [
910
+ [ 'http://user:pass@example.com:9090/path?arg=value#anchor', -1, true, [ 'scheme' => 'http', 'host' => 'example.com', 'port' => 9090, 'user' => 'user', 'pass' => 'pass', 'path' => '/path', 'query' => 'arg=value', 'fragment' => 'anchor' ] ],
911
+ [ 'example.com:9090/path?arg=value#anchor', -1, true, [ 'scheme' => 'http', 'host' => 'example.com', 'port' => 9090, 'path' => '/path', 'query' => 'arg=value', 'fragment' => 'anchor' ] ],
912
+ [ 'example.com:9090/path?arg=value#anchor', -1, false, [ 'host' => 'example.com', 'port' => 9090, 'path' => '/path', 'query' => 'arg=value', 'fragment' => 'anchor' ] ],
913
+ [ 'https://example.com', PHP_URL_HOST, true, 'example.com' ],
914
+ ];
915
+ }
916
+
917
+ /**
918
+ * @dataProvider dataEscapeCsvValue
919
+ */
920
+ public function testEscapeCsvValue( $input, $expected ) {
921
+ $this->assertEquals( $expected, Utils\escape_csv_value( $input ) );
922
+ }
923
+
924
+ public static function dataEscapeCsvValue() {
925
+ return [
926
+ // Values starting with special characters that should be escaped.
927
+ [ '=formula', "'=formula" ],
928
+ [ '+positive', "'+positive" ],
929
+ [ '-negative', "'-negative" ],
930
+ [ '@mention', "'@mention" ],
931
+ [ "\tindented", "'\tindented" ],
932
+ [ "\rcarriage", "'\rcarriage" ],
933
+
934
+ // Values that should not be escaped.
935
+ [ 'normal text', 'normal text' ],
936
+ [ 'text with = in middle', 'text with = in middle' ],
937
+ [ '123', '123' ],
938
+ [ '', '' ],
939
+ [ ' leading space', ' leading space' ],
940
+ [ 'trailing space ', 'trailing space ' ],
941
+ [ '=x==y=', "'=x==y=" ], // Only escapes when the first character is special
942
+ ];
943
+ }
944
+
945
+ public function testWriteCsv() {
946
+ // Create a temporary file
947
+ $temp_file = tmpfile();
948
+
949
+ // Test data with various cases that need escaping
950
+ $headers = [ 'name', 'formula', 'quoted', 'comma', 'backslash' ];
951
+ $rows = [
952
+ [
953
+ 'name' => 'John Doe',
954
+ 'formula' => '=SUM(A1:A2)',
955
+ 'quoted' => 'Contains "quotes"',
956
+ 'comma' => 'Item 1, Item 2',
957
+ 'backslash' => 'C:\\path\\to\\file',
958
+ ],
959
+ [
960
+ 'name' => '@username',
961
+ 'formula' => '+1234',
962
+ 'quoted' => "'Single quotes'",
963
+ 'comma' => '-123,45',
964
+ 'backslash' => 'Escape \\this',
965
+ ],
966
+ ];
967
+
968
+ // Write to CSV
969
+ Utils\write_csv( $temp_file, $rows, $headers );
970
+
971
+ // Rewind file and read contents
972
+ rewind( $temp_file );
973
+ $csv_content = stream_get_contents( $temp_file );
974
+
975
+ // Normalize line endings for cross-platform testing
976
+ $csv_content = str_replace( "\r\n", "\n", $csv_content );
977
+
978
+ // Check individual components instead of the exact string
979
+ $this->assertStringContainsString( 'name,formula,quoted,comma,backslash', $csv_content );
980
+ $this->assertStringContainsString( '"John Doe"', $csv_content );
981
+ $this->assertStringContainsString( '\'=SUM(A1:A2)', $csv_content );
982
+ $this->assertStringContainsString( '"Contains ""quotes"""', $csv_content );
983
+ $this->assertStringContainsString( '"Item 1, Item 2"', $csv_content );
984
+ $this->assertStringContainsString( '\'@username', $csv_content );
985
+ $this->assertStringContainsString( '\'Single quotes\'', $csv_content );
986
+ $this->assertStringContainsString( '\'+1234', $csv_content );
987
+ $this->assertStringContainsString( '\'-123,45', $csv_content );
988
+ }
989
+
990
+ public function testWriteCsvWithoutHeaders() {
991
+ // Create a temporary file
992
+ $temp_file = tmpfile();
993
+
994
+ // Test data without using headers
995
+ $rows = [
996
+ [ 'John Doe', '=SUM(A1:A2)', 'Contains "quotes"' ],
997
+ [ '@username', '+1234', '-amount' ],
998
+ ];
999
+
1000
+ // Write to CSV without headers
1001
+ Utils\write_csv( $temp_file, $rows );
1002
+
1003
+ // Rewind file and read contents
1004
+ rewind( $temp_file );
1005
+ $csv_content = stream_get_contents( $temp_file );
1006
+
1007
+ // Normalize line endings for cross-platform testing
1008
+ $csv_content = str_replace( "\r\n", "\n", $csv_content );
1009
+
1010
+ // Check individual components instead of the exact string
1011
+ $this->assertStringContainsString( '"John Doe"', $csv_content );
1012
+ $this->assertStringContainsString( '\'=SUM(A1:A2)', $csv_content );
1013
+ $this->assertStringContainsString( '"Contains ""quotes"""', $csv_content );
1014
+ $this->assertStringContainsString( '\'@username', $csv_content );
1015
+ $this->assertStringContainsString( '\'+1234', $csv_content );
1016
+ $this->assertStringContainsString( '\'-amount', $csv_content );
1017
+ }
1018
+
1019
+ public function testWriteCsvWithFieldPicking() {
1020
+ // Create a temporary file
1021
+ $temp_file = tmpfile();
1022
+
1023
+ // Test data with additional fields that should be filtered out
1024
+ $rows = [
1025
+ [
1026
+ 'id' => 1,
1027
+ 'name' => 'John Doe',
1028
+ 'email' => 'john@example.com',
1029
+ 'formula' => '=HYPERLINK("http://malicious.com")',
1030
+ 'extra' => 'Should not appear',
1031
+ ],
1032
+ [
1033
+ 'id' => 2,
1034
+ 'name' => '@username',
1035
+ 'email' => 'user@example.com',
1036
+ 'formula' => '+1234',
1037
+ 'extra' => 'Should not appear',
1038
+ ],
1039
+ ];
1040
+
1041
+ // Only include these headers (should filter the rows accordingly)
1042
+ $headers = [ 'id', 'name', 'email', 'formula' ];
1043
+
1044
+ // Write to CSV, which should filter fields based on headers
1045
+ Utils\write_csv( $temp_file, $rows, $headers );
1046
+
1047
+ // Rewind file and read contents
1048
+ rewind( $temp_file );
1049
+ $csv_content = stream_get_contents( $temp_file );
1050
+
1051
+ // Normalize line endings for cross-platform testing
1052
+ $csv_content = str_replace( "\r\n", "\n", $csv_content );
1053
+
1054
+ // Check individual components instead of the exact string
1055
+ $this->assertStringContainsString( 'id,name,email,formula', $csv_content );
1056
+ $this->assertStringContainsString( '1,"John Doe",john@example.com', $csv_content );
1057
+ $this->assertStringContainsString( '\'=HYPERLINK', $csv_content );
1058
+ $this->assertStringContainsString( '2,\'@username,user@example.com', $csv_content );
1059
+ $this->assertStringContainsString( '\'+1234', $csv_content );
1060
+
1061
+ // Make sure 'extra' field is not in the output
1062
+ $this->assertStringNotContainsString( 'extra', $csv_content );
1063
+ $this->assertStringNotContainsString( 'Should not appear', $csv_content );
1064
+ }
1065
+
1066
+ public function testReplacePathConstsAddSlashes() {
1067
+ $expected = "define( 'ABSPATH', dirname( 'C:\\\\Users\\\\test\'s\\\\site' ) . '/' );";
1068
+ $source = "define( 'ABSPATH', dirname( __FILE__ ) . '/' );";
1069
+ $actual = Utils\replace_path_consts( $source, "C:\Users\\test's\site" );
1070
+ $this->assertSame( $expected, $actual );
1071
+ }
1072
+
1073
+ /**
1074
+ * @dataProvider dataValidClassAndMethodPair
1075
+ */
1076
+ public function testValidClassAndMethodPair( $pair, $is_valid ) {
1077
+ $this->assertEquals( $is_valid, Utils\is_valid_class_and_method_pair( $pair ) );
1078
+ }
1079
+
1080
+ public static function dataValidClassAndMethodPair() {
1081
+ return [
1082
+ [ 'string', false ],
1083
+ [ [], false ],
1084
+ [ [ 'WP_CLI' ], false ],
1085
+ [ [ true, false ], false ],
1086
+ [ [ 'WP_CLI', 'invalid_method' ], false ],
1087
+ [ [ 'Invalid_Class', 'invalid_method' ], false ],
1088
+ [ [ 'WP_CLI', 'add_command' ], true ],
1089
+ [ [ 'Exception', 'getMessage' ], true ],
1090
+ ];
1091
+ }
1092
+ }