JsonManipulatorTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. <?php
  2. /*
  3. * This file is part of Composer.
  4. *
  5. * (c) Nils Adermann <naderman@naderman.de>
  6. * Jordi Boggiano <j.boggiano@seld.be>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Composer\Test\Json;
  12. use Composer\Json\JsonManipulator;
  13. class JsonManipulatorTest extends \PHPUnit_Framework_TestCase
  14. {
  15. /**
  16. * @dataProvider linkProvider
  17. */
  18. public function testAddLink($json, $type, $package, $constraint, $expected)
  19. {
  20. $manipulator = new JsonManipulator($json);
  21. $this->assertTrue($manipulator->addLink($type, $package, $constraint));
  22. $this->assertEquals($expected, $manipulator->getContents());
  23. }
  24. public function linkProvider()
  25. {
  26. return array(
  27. array(
  28. '{}',
  29. 'require',
  30. 'vendor/baz',
  31. 'qux',
  32. '{
  33. "require": {
  34. "vendor/baz": "qux"
  35. }
  36. }
  37. '
  38. ),
  39. array(
  40. '{
  41. "foo": "bar"
  42. }',
  43. 'require',
  44. 'vendor/baz',
  45. 'qux',
  46. '{
  47. "foo": "bar",
  48. "require": {
  49. "vendor/baz": "qux"
  50. }
  51. }
  52. '
  53. ),
  54. array(
  55. '{
  56. "require": {
  57. }
  58. }',
  59. 'require',
  60. 'vendor/baz',
  61. 'qux',
  62. '{
  63. "require": {
  64. "vendor/baz": "qux"
  65. }
  66. }
  67. '
  68. ),
  69. array(
  70. '{
  71. "require": {
  72. "foo": "bar"
  73. }
  74. }',
  75. 'require',
  76. 'vendor/baz',
  77. 'qux',
  78. '{
  79. "require": {
  80. "foo": "bar",
  81. "vendor/baz": "qux"
  82. }
  83. }
  84. '
  85. ),
  86. array(
  87. '{
  88. "require":
  89. {
  90. "foo": "bar",
  91. "vendor/baz": "baz"
  92. }
  93. }',
  94. 'require',
  95. 'vendor/baz',
  96. 'qux',
  97. '{
  98. "require":
  99. {
  100. "foo": "bar",
  101. "vendor/baz": "qux"
  102. }
  103. }
  104. '
  105. ),
  106. array(
  107. '{
  108. "require":
  109. {
  110. "foo": "bar",
  111. "vendor\/baz": "baz"
  112. }
  113. }',
  114. 'require',
  115. 'vendor/baz',
  116. 'qux',
  117. '{
  118. "require":
  119. {
  120. "foo": "bar",
  121. "vendor/baz": "qux"
  122. }
  123. }
  124. '
  125. ),
  126. );
  127. }
  128. /**
  129. * @dataProvider removeSubNodeProvider
  130. */
  131. public function testRemoveSubNode($json, $name, $expected, $expectedContent = null)
  132. {
  133. $manipulator = new JsonManipulator($json);
  134. $this->assertEquals($expected, $manipulator->removeSubNode('repositories', $name));
  135. if (null !== $expectedContent) {
  136. $this->assertEquals($expectedContent, $manipulator->getContents());
  137. }
  138. }
  139. public function removeSubNodeProvider()
  140. {
  141. return array(
  142. 'works on simple ones first' => array(
  143. '{
  144. "repositories": {
  145. "foo": {
  146. "foo": "bar",
  147. "bar": "baz"
  148. },
  149. "bar": {
  150. "foo": "bar",
  151. "bar": "baz"
  152. }
  153. }
  154. }',
  155. 'foo',
  156. true,
  157. '{
  158. "repositories": {
  159. "bar": {
  160. "foo": "bar",
  161. "bar": "baz"
  162. }
  163. }
  164. }
  165. '
  166. ),
  167. 'works on simple ones last' => array(
  168. '{
  169. "repositories": {
  170. "foo": {
  171. "foo": "bar",
  172. "bar": "baz"
  173. },
  174. "bar": {
  175. "foo": "bar",
  176. "bar": "baz"
  177. }
  178. }
  179. }',
  180. 'bar',
  181. true,
  182. '{
  183. "repositories": {
  184. "foo": {
  185. "foo": "bar",
  186. "bar": "baz"
  187. }
  188. }
  189. }
  190. '
  191. ),
  192. 'works on simple ones unique' => array(
  193. '{
  194. "repositories": {
  195. "foo": {
  196. "foo": "bar",
  197. "bar": "baz"
  198. }
  199. }
  200. }',
  201. 'foo',
  202. true,
  203. '{
  204. "repositories": {
  205. }
  206. }
  207. '
  208. ),
  209. 'works on simple ones middle' => array(
  210. '{
  211. "repositories": {
  212. "foo": {
  213. "foo": "bar",
  214. "bar": "baz"
  215. },
  216. "bar": {
  217. "foo": "bar",
  218. "bar": "baz"
  219. },
  220. "baz": {
  221. "foo": "bar",
  222. "bar": "baz"
  223. }
  224. }
  225. }',
  226. 'bar',
  227. true,
  228. '{
  229. "repositories": {
  230. "foo": {
  231. "foo": "bar",
  232. "bar": "baz"
  233. },
  234. "baz": {
  235. "foo": "bar",
  236. "bar": "baz"
  237. }
  238. }
  239. }
  240. '
  241. ),
  242. 'works on empty repos' => array(
  243. '{
  244. "repositories": {
  245. }
  246. }',
  247. 'bar',
  248. true
  249. ),
  250. 'works on empty repos2' => array(
  251. '{
  252. "repositories": {}
  253. }',
  254. 'bar',
  255. true
  256. ),
  257. 'works on missing repos' => array(
  258. "{\n}",
  259. 'bar',
  260. true
  261. ),
  262. 'works on deep repos' => array(
  263. '{
  264. "repositories": {
  265. "foo": {
  266. "package": { "bar": "baz" }
  267. }
  268. }
  269. }',
  270. 'foo',
  271. true,
  272. '{
  273. "repositories": {
  274. }
  275. }
  276. '
  277. ),
  278. 'fails on deep repos with borked texts' => array(
  279. '{
  280. "repositories": {
  281. "foo": {
  282. "package": { "bar": "ba{z" }
  283. }
  284. }
  285. }',
  286. 'bar',
  287. false
  288. ),
  289. 'fails on deep repos with borked texts2' => array(
  290. '{
  291. "repositories": {
  292. "foo": {
  293. "package": { "bar": "ba}z" }
  294. }
  295. }
  296. }',
  297. 'bar',
  298. false
  299. ),
  300. );
  301. }
  302. public function testAddRepositoryCanInitializeEmptyRepositories()
  303. {
  304. $manipulator = new JsonManipulator('{
  305. "repositories": {
  306. }
  307. }');
  308. $this->assertTrue($manipulator->addRepository('bar', array('type' => 'composer')));
  309. $this->assertEquals('{
  310. "repositories": {
  311. "bar": {
  312. "type": "composer"
  313. }
  314. }
  315. }
  316. ', $manipulator->getContents());
  317. }
  318. public function testAddRepositoryCanInitializeFromScratch()
  319. {
  320. $manipulator = new JsonManipulator('{
  321. "a": "b"
  322. }');
  323. $this->assertTrue($manipulator->addRepository('bar2', array('type' => 'composer')));
  324. $this->assertEquals('{
  325. "a": "b",
  326. "repositories": {
  327. "bar2": {
  328. "type": "composer"
  329. }
  330. }
  331. }
  332. ', $manipulator->getContents());
  333. }
  334. public function testAddRepositoryCanAdd()
  335. {
  336. $manipulator = new JsonManipulator('{
  337. "repositories": {
  338. "foo": {
  339. "type": "vcs",
  340. "url": "lala"
  341. }
  342. }
  343. }');
  344. $this->assertTrue($manipulator->addRepository('bar', array('type' => 'composer')));
  345. $this->assertEquals('{
  346. "repositories": {
  347. "foo": {
  348. "type": "vcs",
  349. "url": "lala"
  350. },
  351. "bar": {
  352. "type": "composer"
  353. }
  354. }
  355. }
  356. ', $manipulator->getContents());
  357. }
  358. public function testAddRepositoryCanOverrideDeepRepos()
  359. {
  360. $manipulator = new JsonManipulator('{
  361. "repositories": {
  362. "baz": {
  363. "type": "package",
  364. "package": {}
  365. }
  366. }
  367. }');
  368. $this->assertTrue($manipulator->addRepository('baz', array('type' => 'composer')));
  369. $this->assertEquals('{
  370. "repositories": {
  371. "baz": {
  372. "type": "composer"
  373. }
  374. }
  375. }
  376. ', $manipulator->getContents());
  377. }
  378. public function testAddConfigSettingEscapes()
  379. {
  380. $manipulator = new JsonManipulator('{
  381. "config": {
  382. }
  383. }');
  384. $this->assertTrue($manipulator->addConfigSetting('test', 'a\b'));
  385. $this->assertTrue($manipulator->addConfigSetting('test2', "a\nb\fa"));
  386. $this->assertEquals('{
  387. "config": {
  388. "test": "a\\\\b",
  389. "test2": "a\nb\fa"
  390. }
  391. }
  392. ', $manipulator->getContents());
  393. }
  394. public function testAddConfigSettingCanAdd()
  395. {
  396. $manipulator = new JsonManipulator('{
  397. "config": {
  398. "foo": "bar"
  399. }
  400. }');
  401. $this->assertTrue($manipulator->addConfigSetting('bar', 'baz'));
  402. $this->assertEquals('{
  403. "config": {
  404. "foo": "bar",
  405. "bar": "baz"
  406. }
  407. }
  408. ', $manipulator->getContents());
  409. }
  410. public function testAddConfigSettingCanOverwrite()
  411. {
  412. $manipulator = new JsonManipulator('{
  413. "config": {
  414. "foo": "bar",
  415. "bar": "baz"
  416. }
  417. }');
  418. $this->assertTrue($manipulator->addConfigSetting('foo', 'zomg'));
  419. $this->assertEquals('{
  420. "config": {
  421. "foo": "zomg",
  422. "bar": "baz"
  423. }
  424. }
  425. ', $manipulator->getContents());
  426. }
  427. public function testAddConfigSettingCanOverwriteNumbers()
  428. {
  429. $manipulator = new JsonManipulator('{
  430. "config": {
  431. "foo": 500
  432. }
  433. }');
  434. $this->assertTrue($manipulator->addConfigSetting('foo', 50));
  435. $this->assertEquals('{
  436. "config": {
  437. "foo": 50
  438. }
  439. }
  440. ', $manipulator->getContents());
  441. }
  442. public function testAddConfigSettingCanOverwriteArrays()
  443. {
  444. $manipulator = new JsonManipulator('{
  445. "config": {
  446. "github-oauth": {
  447. "github.com": "foo"
  448. },
  449. "github-protocols": ["https"]
  450. }
  451. }');
  452. $this->assertTrue($manipulator->addConfigSetting('github-protocols', array('https', 'http')));
  453. $this->assertEquals('{
  454. "config": {
  455. "github-oauth": {
  456. "github.com": "foo"
  457. },
  458. "github-protocols": ["https", "http"]
  459. }
  460. }
  461. ', $manipulator->getContents());
  462. $this->assertTrue($manipulator->addConfigSetting('github-oauth', array('github.com' => 'bar', 'alt.example.org' => 'baz')));
  463. $this->assertEquals('{
  464. "config": {
  465. "github-oauth": {
  466. "github.com": "bar",
  467. "alt.example.org": "baz"
  468. },
  469. "github-protocols": ["https", "http"]
  470. }
  471. }
  472. ', $manipulator->getContents());
  473. }
  474. public function testAddConfigSettingCanAddSubKeyInEmptyConfig()
  475. {
  476. $manipulator = new JsonManipulator('{
  477. "config": {
  478. }
  479. }');
  480. $this->assertTrue($manipulator->addConfigSetting('github-oauth.bar', 'baz'));
  481. $this->assertEquals('{
  482. "config": {
  483. "github-oauth": {
  484. "bar": "baz"
  485. }
  486. }
  487. }
  488. ', $manipulator->getContents());
  489. }
  490. public function testAddConfigSettingCanAddSubKeyInEmptyVal()
  491. {
  492. $manipulator = new JsonManipulator('{
  493. "config": {
  494. "github-oauth": {},
  495. "github-oauth2": {
  496. }
  497. }
  498. }');
  499. $this->assertTrue($manipulator->addConfigSetting('github-oauth.bar', 'baz'));
  500. $this->assertTrue($manipulator->addConfigSetting('github-oauth2.a.bar', 'baz2'));
  501. $this->assertTrue($manipulator->addConfigSetting('github-oauth3.b', 'c'));
  502. $this->assertEquals('{
  503. "config": {
  504. "github-oauth": {
  505. "bar": "baz"
  506. },
  507. "github-oauth2": {
  508. "a.bar": "baz2"
  509. },
  510. "github-oauth3": {
  511. "b": "c"
  512. }
  513. }
  514. }
  515. ', $manipulator->getContents());
  516. }
  517. public function testAddConfigSettingCanAddSubKeyInHash()
  518. {
  519. $manipulator = new JsonManipulator('{
  520. "config": {
  521. "github-oauth": {
  522. "github.com": "foo"
  523. }
  524. }
  525. }');
  526. $this->assertTrue($manipulator->addConfigSetting('github-oauth.bar', 'baz'));
  527. $this->assertEquals('{
  528. "config": {
  529. "github-oauth": {
  530. "github.com": "foo",
  531. "bar": "baz"
  532. }
  533. }
  534. }
  535. ', $manipulator->getContents());
  536. }
  537. public function testRemoveConfigSettingCanRemoveSubKeyInHash()
  538. {
  539. $manipulator = new JsonManipulator('{
  540. "config": {
  541. "github-oauth": {
  542. "github.com": "foo",
  543. "bar": "baz"
  544. }
  545. }
  546. }');
  547. $this->assertTrue($manipulator->removeConfigSetting('github-oauth.bar'));
  548. $this->assertEquals('{
  549. "config": {
  550. "github-oauth": {
  551. "github.com": "foo"
  552. }
  553. }
  554. }
  555. ', $manipulator->getContents());
  556. }
  557. public function testRemoveConfigSettingCanRemoveSubKeyInHashWithSiblings()
  558. {
  559. $manipulator = new JsonManipulator('{
  560. "config": {
  561. "foo": "bar",
  562. "github-oauth": {
  563. "github.com": "foo",
  564. "bar": "baz"
  565. }
  566. }
  567. }');
  568. $this->assertTrue($manipulator->removeConfigSetting('github-oauth.bar'));
  569. $this->assertEquals('{
  570. "config": {
  571. "foo": "bar",
  572. "github-oauth": {
  573. "github.com": "foo"
  574. }
  575. }
  576. }
  577. ', $manipulator->getContents());
  578. }
  579. }