1111
1212
1313/**
14- * Snapshot testing helper .
14+ * Snapshot of a tested value .
1515 */
1616class Snapshot
1717{
18+ /** @var string */
1819 public static $ snapshotDir = 'snapshots ' ;
1920
21+ /** @var string[] */
2022 public static $ updatedSnapshots = [];
2123
24+ /** @var string[] */
25+ private static $ usedNames = [];
2226
23- /**
24- * Compares value with a previously created snapshot.
25- */
26- public static function match ($ value , string $ snapshotName ): void
27- {
28- $ updateSnapshots = (bool ) getenv (Environment::UPDATE_SNAPSHOTS );
29-
30- $ testFile = $ _SERVER ['argv ' ][0 ];
31- $ snapshotFile = self ::getSnapshotFile ($ testFile , $ snapshotName );
27+ /** @var string */
28+ private $ name ;
3229
33- if (!file_exists ($ snapshotFile )) {
34- if (!$ updateSnapshots ) {
35- Assert::fail ("Missing snapshot file ' $ snapshotFile', use --update-snapshots option to generate it. " );
36- }
3730
38- self ::write ($ snapshotFile , $ value );
31+ public function __construct (string $ name )
32+ {
33+ if (!preg_match ('/^[a-zA-Z0-9-_]+$/ ' , $ name )) {
34+ throw new \Exception ("Invalid snapshot name ' $ name'. Only alphanumeric characters, dash and underscore are allowed. " );
3935 }
4036
41- $ snapshot = self ::read ($ snapshotFile );
37+ if (in_array ($ name , self ::$ usedNames , true )) {
38+ throw new \Exception ("Snapshot ' $ name' was already asserted, please use a different name. " );
39+ }
4240
43- try {
44- Assert:: equal ( $ snapshot , $ value , " Snapshot $ snapshotName " );
41+ $ this -> name = self :: $ usedNames [] = $ name ;
42+ }
4543
46- } catch (AssertException $ e ) {
47- if (!$ updateSnapshots ) {
48- throw $ e ;
49- }
5044
51- self ::write ($ snapshotFile , $ value );
52- }
45+ public function exists (): bool
46+ {
47+ return file_exists ($ this ->getSnapshotFile ());
5348 }
5449
5550
56- private static function getSnapshotFile ( string $ testFile , string $ snapshotName ): string
51+ public function read ()
5752 {
58- $ path = self ::$ snapshotDir . DIRECTORY_SEPARATOR . pathinfo ($ testFile , PATHINFO_FILENAME ) . '. ' . $ snapshotName . '.phps ' ;
59- if (!preg_match ('#/|\w:#A ' , self ::$ snapshotDir )) {
60- $ path = dirname ($ testFile ) . DIRECTORY_SEPARATOR . $ path ;
61- }
62- return $ path ;
53+ $ snapshotFile = $ this ->getSnapshotFile ();
54+ set_error_handler (function ($ errno , $ errstr ) use ($ snapshotFile ) {
55+ throw new \Exception ("Unable to read snapshot file ' $ snapshotFile': $ errstr " );
56+ });
57+
58+ $ snapshotContents = include $ snapshotFile ;
59+
60+ restore_error_handler ();
61+ return $ snapshotContents ;
6362 }
6463
6564
66- private static function read ( string $ snapshotFile )
65+ public function canUpdate (): bool
6766 {
68- $ snapshotContents = @file_get_contents ($ snapshotFile );
69- if ($ snapshotContents === false ) {
70- throw new \Exception ("Unable to read snapshot file ' $ snapshotFile'. " );
71- }
72-
73- return eval (substr ($ snapshotContents , strlen ('<?php ' )));
67+ return (bool ) getenv (Environment::UPDATE_SNAPSHOTS );
7468 }
7569
7670
77- private static function write ( string $ snapshotFile , $ value ): void
71+ public function update ( $ value ): void
7872 {
73+ if (!$ this ->canUpdate ()) {
74+ throw new \Exception ('Cannot update snapshot. Please run tests again with --update-snapshots. ' );
75+ }
76+
77+ $ snapshotFile = $ this ->getSnapshotFile ();
7978 $ snapshotDirectory = dirname ($ snapshotFile );
8079 if (!is_dir ($ snapshotDirectory ) && !mkdir ($ snapshotDirectory )) {
8180 throw new \Exception ("Unable to create snapshot directory ' $ snapshotDirectory'. " );
@@ -88,4 +87,15 @@ private static function write(string $snapshotFile, $value): void
8887
8988 self ::$ updatedSnapshots [] = $ snapshotFile ;
9089 }
90+
91+
92+ private function getSnapshotFile (): string
93+ {
94+ $ testFile = $ _SERVER ['argv ' ][0 ];
95+ $ path = self ::$ snapshotDir . DIRECTORY_SEPARATOR . pathinfo ($ testFile , PATHINFO_FILENAME ) . '. ' . $ this ->name . '.phps ' ;
96+ if (!preg_match ('#/|\w:#A ' , self ::$ snapshotDir )) {
97+ $ path = dirname ($ testFile ) . DIRECTORY_SEPARATOR . $ path ;
98+ }
99+ return $ path ;
100+ }
91101}
0 commit comments