2015/06/30

08.我喜歡被抱

我自己躺的時候就哭哭,然後媽媽把我抱起來我就偷笑了。

2015/06/29

2015/06/28

06.我是小超人

世界就靠我保護了。

陽光照耀我眼睛。

2015/06/26

PHPUnit

單元測試對程式設計來說是蠻重要的ㄧ件事情,測試寫久了對你實際程式碼撰寫思路也有一定的幫助,簡單介紹一下 PHPUnit 的使用方式。

首先先去官網將 phpunit.phar 裝起來,並確定在 terminal 可以呼叫,在你的 project 裡面使用 composer 將 phpunit/phpunit require 進來,我使用 composer autoload psr-4 功能做 class 的 autoloading,並且將預設的 class 放在 src/ 目錄下,所以目前 composer.json 會長這樣。

{
    "require": {
        "phpunit/phpunit": "^4.7"
    },
    "autoload": {
        "psr-4": {
            "": "src/"
        }
    }
}

執行 composer -o dump-autoload 確保所有的設定 ok,我們來建一個要測試用的檔案,我在 src/ 目錄下建了一個 Chan.php,內容如下。

src/Chan.php
class Chan
{
    public function myName()
    {
        return 'Chan';
    }
}

接下來要建立我們的測試檔案,建立測試檔案命名有一定的規範,假設我是要測試 Chan.php,那我要建立 tests\ChanTest.php,要測試某個 function 的話,function name 要這樣取 public function testMyName,PHPUnit 僅會跑開頭為 test 的 function。

tests/ChanTest.php
class ChanTest extends PHPUnit_Framework_TestCase
{
    public $chan;

    public function __construct()
    {
        $this->chan = new Chan;
    }

    public function testMyName()
    {
        $this->assertEquals('Chan', $this->chan->myName());
    }
}

接下來我們在 terminal 執行 phpunit script

phpunit --bootstrap vendor/autoload.php tests/

--bootstrap 會先跑我們希望他預跑程式,有可能是一些設定之類的,這邊我指向 autoload 的部分,跑完結果是。

PHPUnit 4.7.5 by Sebastian Bergmann and contributors.

.

Time: 375 ms, Memory: 9.25Mb

OK (1 test, 1 assertion)

這表示完全正確,我們故意修改一下 function

public function testMyName()
{
    $this->assertEquals('Phoebe', $this->chan->myName());
}

讓我們在執行一次 PHPUnit script,這次得到

PHPUnit 4.7.5 by Sebastian Bergmann and contributors.

F

Time: 378 ms, Memory: 9.25Mb

There was 1 failure:

1) ChanTest::testMyName
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'Phoebe'
+'Chan'

D:\www\test\tests\ChanTest.php:14

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

PHPUnit 明確的把錯誤的訊息指出來給你,所以修正起來會很方便,我們是否每次檢查都要打這麼多字,當然不用,我們只要預先把 config 寫到 phpunit.xml 裡就可以了,官網的說明在此,依照我們的情況的基礎內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="vendor/autoload.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false"
         syntaxCheck="false">
    <testsuites>
        <testsuite name="Application Test Suite">
            <directory>./tests/</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist>
            <directory suffix=".php">src/</directory>
        </whitelist>
    </filter>
</phpunit>

當然 phpunit.xml 還有非常多的東西可以設定,可以參考一下官方說明取用,測試結果有很多 function 可以用,最常用的應該就是 assertEquals 以及 assertTrue(),其他的情況可以參考這邊搭配使用。

05.我不喜歡換尿布

每次幫我換尿布時我就是要哭。

換完以後一秒鐘就安靜。

媽媽在幫我練習拍嗝。

我今天心情很不錯。

2015/06/25

04.我是獅子王

這是我在月子中心坐騎旁邊的圖案,我以後是獅子王。

我雖然很可愛,可是吃母奶的時候我吃一下就睡著,吃配方奶我就猛吸,壞壞。

2015/06/24

03.我出關了

隔離 24 小時以後,我等等要出關了,爸爸說可以認識新朋友。

這是我的腳趾,一腳五隻。

我有深邃的雙眼皮,別愛上我,你會受傷。

2015/06/23

02.我今天要搬家了

雖然禾馨的阿姨們都對我很好,但天下無不散的筵席,今天我就要前往月子中心了,有緣再會。

禾馨的阿姨怕我曬到太陽,所以給了我一頂小帽子。

到了賀果以後我一樣盡小嬰兒應盡的義務,水~

我媽咪剛開始餵我吃奶,所以乳汁還不太夠,賀果的阿姨怕我餓壞讓我吃了一點配方奶,我知道不是媽媽的錯,媽媽加油,我先偷吃點心。

01.霸氣小布丁

這是我的霸氣寶貝兒子小布丁,乳名小布丁是因為爸爸愛吃布丁,好可愛喔。

有別於一般的新生兒,小布丁出生後就喜歡用眼睛看來看去,一般的新生兒很少這麼愛張開眼睛。

不過愛睡這點是一樣的。

2015/06/09

模擬轉盤遊戲

公司有一個 case 要在網頁模仿轉盤亮燈的功能,陽春的寫法如下。

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Game</title>
    <link rel="stylesheet" href="game.css">
    <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
    <script src="game.js"></script>
</head>
<body>
<button type="button" id="start">start</button>
<ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>
</body>
</html>

CSS

ul {
    margin: 0;
    padding: 0;
    list-style: none;
}
li {
    width: 100px;
    height: 100px;
    border: 2px solid red;
    float: left;
    margin: 2px;
}
.on {
    border: 2px solid pink;
}

JS

$(function() {
    var start = $('#start');
    var lis = $('li');

    start.on('click', function() {
        var rounds = 40 + Math.floor((Math.random() * lis.size()));

        $(this).prop('disabled', true);
        spin(lis.filter(':first'), rounds);
    });

    function spin(li, rounds) {
        var duration = rounds < 5 ? 1000 : 70;

        lis.clearQueue();
        li.delay(duration).queue(function() {
            var next = $(this).next('li');

            lis.removeClass('on');

            if (next.size() === 0) {
                next = lis.filter(':first');
            }

            li.addClass('on');

            if (rounds - 1 >= 0) {
                spin(next, rounds -1);
            } else {
                start.prop('disabled', false);
            }
        });
    }
});

Sample Code