Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.4] Refactoring mix method. #19639

Closed
wants to merge 5 commits into from
Closed

Conversation

mathieutu
Copy link
Contributor

Hi folks,
for this 4th PR of the week, I worked on the mix() method!

I totally refactored it in a proper testable service, called by app('mix').
I also fully tested it.

And then, I've managed the Exception thrown when you execute the tests on views where mix() is called, and you don't have installed and launch js stuffs.

We discussed about that in laravel/ideas#634.

So the result is:

  • Without the PR:
    screen shot 2017-06-16 at 19 21 23

  • With the PR:
    screen shot 2017-06-16 at 19 21 57

I haven't made a Facade for that, imo it's enough easy to use like that. We can add one if you want.

I'm waiting for your comments!
Matt'

*/
protected function hmrPath()
{
return new HtmlString("//localhost:8080{$this->path}");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be nice to be able to configure this port and host.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if you can really modify that on laravel-mix.. 🤔 I don't see it in docs.
@JeffreyWay ?

*/
protected function sanitize($path)
{
if ($path && ! starts_with($path, '/')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Str::startsWith instead

Copy link
Contributor Author

@mathieutu mathieutu Jun 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the same just shorter..
But I've no problem with that if you have a good reason 🙂

Copy link
Contributor

@lucasmichot lucasmichot Jun 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Within the framework, we don't use array and string helper, we directly call Str and Arr functions.


class Mix
{
protected $path;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 missing docblocks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right! I missed them...
Thank you!

throw new MixException('The Mix manifest does not exist.');
}

$this->manifest = collect(json_decode(file_get_contents($manifestPath), true));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any point to use a Collection instead of an array?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be able to make a get line 131. A data_get can't be used because of the dot notation (and the extension of files)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then you can use Arr::get instead, no need of a collection

Copy link
Contributor Author

@mathieutu mathieutu Jun 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lucasmichot no you can't use Arr::get here, because it uses "dot" notation, and it will fail with the extension of the assets:

// src/Illuminate/Support/Arr.php:277
foreach (explode('.', $key) as $segment) { // 'foo.css' => ['foo', 'css']

It's why I used a collection, where the get method doesn't use dot notation.

Copy link
Contributor

@lucasmichot lucasmichot Jun 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But a collection is useless:

// getManifest()
$this->manifest = json_decode(file_get_contents($manifestPath), true);

// getPathFromManifest()
if (! array_key_exists($this->path, $manifest = $this->getManifest())) {
    throw new MixException(
        "Unable to locate Mix file: {$this->path}. Please check your ".
        'webpack.mix.js output paths and try again.'
    );
}

return $manifest[$this->path];

Just as it was done in the mix() helper function

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the manifest file cannot be decoded properly? A test on json_last_error() !== JSON_ERROR_NONE should be done and MixException thrown


public function testMixMethodThrowAnExceptionIfMixManifestDoesNotExist()
{
$this->expectException(MixException::class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the rest of the tests, we use docblocks annotation to tests exceptions:

/**
 * @expectedException \Exception
 * @expectedExceptionMessage The exception message
 */

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I'm seeing it. I prefer the other way (more consistent imho), but no problem with that.

@tillkruss tillkruss changed the title Refactoring mix method. [5.4] Refactoring mix method. Jun 16, 2017
@taylorotwell
Copy link
Member

What new functionality is there? What is this fixing?

@m1guelpf
Copy link
Contributor

@taylorotwell See laravel/ideas#634

@mathieutu
Copy link
Contributor Author

@taylorotwell, TL;DR by order of importance:

  • Possibility of disable mix() to avoid exception when you don't give a **** of assets. (see my screens above)
  • Full tested
  • Refactored to his own proper class and not all the logic in one little helper.

});
}

public function tearDown()
Copy link
Contributor

@lucasmichot lucasmichot Jun 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Useless, you don't use Mockery.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right!
Just a bad copy-paste -_-"

*/
protected function getPathFromManifest()
{
return $this->getManifest()->get($this->path, function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use a if statement, instead of passing a closure for the default argument

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this way to do it, imo it's more in the Laravel spirit.
It's just about pretty code, no more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, why would you call value() on the closure ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it comes directly from examples and good practices from Jeffrey and Adam! ^^"
(but as it's just about coding style and I don't really care, I am refactoring that just for you..!)

/**
* Get a sanitized version of a path.
*
* @param string $path
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string|null as you check that it's not null

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, thx.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, actually it can't be null. It's just in case of empty string (the same than before).

*/
public function enable($enabled = true)
{
$this->disable(! $enabled);
Copy link
Contributor

@lucasmichot lucasmichot Jun 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's faster to directly set the property: $this->disabled = ! $enabled;

*
* @return \Illuminate\Support\HtmlString
*
* @throws \Illuminate\View\Mix\MixException
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does not throw any exception

public function registerMix()
{
$this->app->singleton('mix', function () {
return new Mix();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new classes without parameters are declared without the braces: return new Mix;

m::mock(\Illuminate\View\Mix\Mix::class)->shouldReceive('mix')->andReturn('bar')->getMock()
);

$this->assertEquals('bar', mix('foo'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to be stricter and use assertSame as we expect a string.


private function getMix()
{
return new \Illuminate\View\Mix\Mix();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return new \Illuminate\View\Mix\Mix;

@@ -523,40 +523,11 @@ function method_field($method)
* @param string $manifestDirectory
* @return \Illuminate\Support\HtmlString
*
* @throws \Exception
* @throws \Illuminate\View\Mix\MixException
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does not throw any exception.

* @param string $manifestDirectory
* @return \Illuminate\Support\HtmlString
*
* @throws \Illuminate\View\Mix\MixException
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does not throw any exception.

@taylorotwell
Copy link
Member

Re-submit this when all of @lucasmichot's feedback is addressed and I'll take a look. Thanks!

mathieutu added a commit to mathieutu/framework that referenced this pull request Jun 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants