Completed
Push — add/changelog-tooling ( 257a85 )
by
unknown
149:15 queued 138:48
created

UtilsTest   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 130
rs 10
c 0
b 0
f 0
wmc 6
lcom 0
cbo 2

4 Methods

Rating   Name   Duplication   Size   Complexity  
A test_error_clear_last() 0 9 1
A testRunCommand() 0 18 2
B provideRunCommand() 0 62 1
A testRunCommand_timeout() 0 12 2
1
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
/**
3
 * Tests for the changelogger utils.
4
 *
5
 * @package automattic/jetpack-changelogger
6
 */
7
8
// phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
9
10
namespace Automattic\Jetpack\Changelogger\Tests;
11
12
use Automattic\Jetpack\Changelogger\Utils;
13
use Symfony\Component\Console\Helper\DebugFormatterHelper;
14
use Symfony\Component\Console\Output\BufferedOutput;
15
use Symfony\Component\Process\Exception\ProcessTimedOutException;
16
use Symfony\Component\Process\ExecutableFinder;
17
use Symfony\Component\Process\Process;
18
use function Wikimedia\quietCall;
19
20
/**
21
 * Tests for the changelogger utils.
22
 *
23
 * @covers \Automattic\Jetpack\Changelogger\Utils
24
 */
25
class UtilsTest extends TestCase {
26
	use \Yoast\PHPUnitPolyfills\Polyfills\ExpectException;
27
28
	/**
29
	 * Test error_clear_last.
30
	 */
31
	public function test_error_clear_last() {
32
		quietCall( 'trigger_error', 'Test', E_USER_NOTICE );
33
		$err = error_get_last();
34
		$this->assertSame( 'Test', $err['message'] );
35
36
		Utils::error_clear_last();
37
		$err = error_get_last();
38
		$this->assertTrue( empty( $err['message'] ) );
39
	}
40
41
	/**
42
	 * Test runCommand.
43
	 *
44
	 * @dataProvider provideRunCommand
45
	 * @param string $cmd Bash command string.
46
	 * @param array  $options Options for `runCommand()`.
47
	 * @param int    $expectExitCode Expected exit code.
48
	 * @param string $expectStdout Expected output from the command.
49
	 * @param string $expectStderr Expected output from the command.
50
	 * @param string $expectOutput Expected output to the console.
51
	 * @param int    $verbosity Output buffer verbosity.
52
	 */
53
	public function testRunCommand( $cmd, $options, $expectExitCode, $expectStdout, $expectStderr, $expectOutput, $verbosity = BufferedOutput::VERBOSITY_DEBUG ) {
54
		$sh = ( new ExecutableFinder() )->find( 'sh' );
55
		if ( ! $sh ) {
56
			$this->markTestSkipped( 'This test requires a Posix shell' );
57
		}
58
59
		$expectOutput = strtr( $expectOutput, array( '{SHELL}' => $sh ) );
60
61
		$output = new BufferedOutput();
62
		$output->setVerbosity( $verbosity );
63
		$helper = new DebugFormatterHelper();
64
		$ret    = Utils::runCommand( array( $sh, '-c', $cmd ), $output, $helper, $options );
65
		$this->assertInstanceOf( Process::class, $ret );
66
		$this->assertSame( $expectExitCode, $ret->getExitCode() );
67
		$this->assertSame( $expectStdout, $ret->getOutput() );
68
		$this->assertSame( $expectStderr, $ret->getErrorOutput() );
69
		$this->assertSame( $expectOutput, $output->fetch() );
70
	}
71
72
	/**
73
	 * Data provider for testRunCommand.
74
	 */
75
	public function provideRunCommand() {
76
		$tmp = sys_get_temp_dir();
77
78
		return array(
79
			'true'                      => array(
80
				'true',
81
				array(),
82
				0,
83
				'',
84
				'',
85
				"  RUN  '{SHELL}' '-c' 'true'\n\n",
86
			),
87
			'false'                     => array(
88
				'false',
89
				array(),
90
				1,
91
				'',
92
				'',
93
				"  RUN  '{SHELL}' '-c' 'false'\n\n",
94
			),
95
			'true, non-debug verbosity' => array(
96
				'true',
97
				array(),
98
				0,
99
				'',
100
				'',
101
				'',
102
				BufferedOutput::VERBOSITY_VERY_VERBOSE,
103
			),
104
			'With cwd'                  => array(
105
				'pwd',
106
				array(
107
					'cwd' => $tmp,
108
				),
109
				0,
110
				"$tmp\n",
111
				'',
112
				"  RUN  '{SHELL}' '-c' 'pwd'\n\n  OUT  $tmp\n  OUT  \n",
113
			),
114
			'With env'                  => array(
115
				'echo "$FOO" >&2',
116
				array(
117
					'env' => array( 'FOO' => 'FOOBAR' ),
118
				),
119
				0,
120
				'',
121
				"FOOBAR\n",
122
				"  RUN  '{SHELL}' '-c' 'echo \"\$FOO\" >&2'\n\n  ERR  FOOBAR\n  ERR  \n",
123
			),
124
			'With input'                => array(
125
				'while IFS= read X; do echo "{{$X}}"; done',
126
				array(
127
					'input' => "A\nB\nC\n",
128
				),
129
				0,
130
				"{{A}}\n{{B}}\n{{C}}\n",
131
				'',
132
				'',
133
				BufferedOutput::VERBOSITY_NORMAL,
134
			),
135
		);
136
	}
137
138
	/**
139
	 * Test runCommand with a timeout.
140
	 */
141
	public function testRunCommand_timeout() {
142
		$sleep = ( new ExecutableFinder() )->find( 'sleep' );
143
		if ( ! $sleep ) {
144
			$this->markTestSkipped( 'This test requires a "sleep" command' );
145
		}
146
147
		$output = new BufferedOutput();
148
		$output->setVerbosity( BufferedOutput::VERBOSITY_DEBUG );
149
		$helper = new DebugFormatterHelper();
150
		$this->expectException( ProcessTimedOutException::class );
151
		Utils::runCommand( array( $sleep, '1' ), $output, $helper, array( 'timeout' => 0.1 ) );
152
	}
153
154
}
155