Mockery で overload かつ constant を使うために namedMock を直しました(プルリクはしてない

short answer:
github.com

long answer:
PHPUnitでCIとかに便利そうだからという理由だけで、モックフレームワークを使ってみることに。
MockerとPhakeで悩んだのですが、githubからアクティビティでMockeryにしてみました。(あと、githubのアイコンがカッコイイかr
github.com

インストールはcomposer.json

{
    "require-dev": {
        "phpunit/phpunit": "4.8.*",
        "mockery/mockery": "^0.9.5"
    }
}

composer install

とかでいいはずです。(composerはhomebrewで入れたはず
あとはphpunit.xml

<phpunit
    backupGlobals="false"
    backupStaticAttributes="false"
    strict="true"
    verbose="true"
    bootstrap="phpunit_bootstrap.php">
    <testsuites>
        <testsuite name="PHPUnit Test Suite">
            <file>classes/utilities/XXXX_TestDriverTest.php</file>
        </testsuite>
    </testsuites>
    <logging>
        <log type="coverage-clover" target="logs/clover.xml"/>
    </logging>
</phpunit>

してphpunit_bootstrap.php

<?php
/**
 * Created by PhpStorm.
 * User: bhind
 * Date: 2016/10/05
 * Time: 14:57
 */
if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
    define('PHPUNIT_COMPOSER_INSTALL', dirname(__FILE__) . '/vendor/autoload.php');
}
require_once ('vendor/autoload.php');
$_SERVER["SYSTEM_ROOT"] = dirname(__FILE__) . '/../system/';
$_SERVER["WEBAPP_ROOT"] = dirname(__FILE__) . '/../';

$GLOBALS["_Log"] = new cLog(cLog::INFO);
$GLOBALS["_DEBUG"] = true;

とかしておき、[PhpStorm]-[preference]-[Languages & Frameworks]-[PHP]-[PHPUnit]でautoloaderのpath to scriptを設定し、[Run]-[Edit Configuration]からTest Runner options:に -c でphpunit.xmlを指定します。
これで、[Run]からPHPUnitが起動できるはず。

さて、そこから何点かはまりました。

  • なんか常にアプリのログが出て fail

logがdebugログ吐いてたのでlog levelをinfoにしました

  • mockオブジェクトをoverload:をつけて作成しようとするとclass already existsとエラーで弾かれる

qiita.com
テストケースメソッドにアノテーション@runInSeparateProcess
アノテーションつけたらPHPUnitのクラスが見つからないいうからphpunit_bootstrap.php

<?php
if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
    define('PHPUNIT_COMPOSER_INSTALL', dirname(__FILE__) . '/vendor/autoload.php');
}

を追記。
autoloadでないrequireをテストケース内に移動
Mockeryのmockクラスのあとからrequire_onceで呼びに来る本番コードの方をclass_exists($class_name, false)でチェックするように(existsならrequireしない)

上記でほぼほぼ動くようになるのだが、今回のテストケースで最大の難関がCONSTが存在しないエラー…
overloadした本番コード側で返り値OKをみているところで、injectionされたmockにconstがなくてエラーになっていました。
下記をみると、const宣言したstubをnamedMockすればよいみたいにあるけど、、、
github.com
overload:をつけてnamedMockを呼ぶと
PHP Parse error: syntax error, unexpected ':', expecting '{' in /Users/..../vendor/mockery/mockery/library/Mockery/Loader/EvalLoader.php(16) : eval()'d code on line 25
とか言われました。コードを追ってみた結果、どうもMockery::namedMockでMockConfigurationBuilderを作りMockConfigurationBuilder::setNameして一般処理に流してるようなのだけど、その先のContainer::mockをみてみると本来行われるべき接頭辞処理がされてませんでした。なので、冒頭の変更はContainer::mockでやってる接頭辞処理をMockery::namedMockでするようにしただけです(しかもoverloadだけ)
そんなこんなで、テストケース一つにほぼ一日かかりました(´・ω・`)

<?php
class ClassConstantStub
{
    const OK = 0;
}
class XXXX_TestDriverTest extends PHPUnit_Framework_TestCase
    public function setUp() {
    }
    public function tearDown() {
        Mockery::close();
    }
    /**
     * @runInSeparateProcess
     */
    public function test_get_xxxx_code_master_id_from() {
        \Mockery::namedMock('overload:XXXXCodeMasterEntity', 'ClassConstantStub')
            ->shouldReceive('get_id')->andReturn(XXXXCodeMasterEntity::OK)
            ->andSet('xxx_code_master_id', 1)->andReturn(1);
        require_once ('XXXX_TestDriver.php');
        $obj = new XXXX_TestDriver();
        $method = $this->getMethod(get_class($obj), 'get_xxxx_code_master_id_from');
        $args = array('xx_XX');
        $expect = 1;

        $this->assertEquals($expect, $method->invokeArgs($obj,$args));
    }
    protected function getMethod($className, $methodName) {
        $class = new ReflectionClass($className);
        $method = $class->getMethod($methodName);
        $method->setAccessible(true);
        return $method;
    }
}

月物語 つばさライオンを読んで

本編よりもハマってしまった、3月のライオン 12巻の特典コラボ小説、月物語 つばさライオン。

コラボしたのは<化物語>シリーズの西尾維新化物語シリーズはシャフトのアニメってくらいしか知らなかったのだけど、少し調べたらめちゃめちゃおもしろそうでした。

ややネタバレ気味で感想を書くと、内容は、新聞にくるまってた羽川翼を見つけた零くんが、老倉の文通相手との将棋にまつわる謎解きに、地べたにチョークで書きながらつきあわされるというもの。何度も非常識的な状況に、零くんも突っ込みながら謎を解明していく、本編にはない零くんの魅力を感じさせる作品でした。(ミステリでも食っていけるんじゃないの?零くん

謎解きには将棋の知識はほぼほぼいらないものの、感覚、というか感情的な推し量りの部分で活きた感が、逆に絶妙でした、というのが短い感想です。なんのことやらさっぱりでしょうが、詳しくは小説を読んでください。

【ここからネタバレ】

謎解きパートについては、老倉がメールチェス形式で将棋してて受け取った最後の手紙で、とんでもない配置の盤面図という代物。老倉はそれをみてビリッビリに破いたらしいのだけど、それを覚えてる老倉も羽川もおかしいんじゃないかって即思うのですが華麗にスルー(あとで零くんがフォローするけど

先手番の駒だけにしたところは、私も膝を打ちそうになりましたが、そこから九九へは老倉のこと知らないと、と思ったし、数字の並びも将棋からみたらそもそもが不自然、という感覚だったのだけど、それは将棋側とそうでない側を行ったり来たりするプロットを思いついたのかなと思ったり思わなかったり。

3分の2と5分の4と奇数については頓知だなあという感じでしたけど、その後の心理描写は若い頃のなんたるか、という感じで身悶えながら共感してました。(共感性羞恥

羽川の言う「結局伝わらなかったし」という一言がすべてを表していて、とても残酷だけどそういうことなんだなと思った次第。

おもしろかったです。

【ネタバレここまで】

ちなみに!コラボ小説の表紙に描かれている羽海野てんてーによる羽川翼がめちゃめちゃかわいい。両手書きなのは天才=両利きの意味なのかな。

さて、<化物語>シリーズをチェックしようかn

エアー寿司キャンペーン概要

最近、回転寿司屋さんで糖質ダイエット中の女性がシャリを残して食べているという現象が起きているみたいです。
www.j-cast.com
私も糖質ダイエットを実践しているので気持ちはわかるのですが、やはり食べ残しが廃棄されることを考えるとよろしくはないと思ってしまいます。
そこで、はなまるうどんの+100円でサラダうどんのうどんをブロッコリーに変える、というキャンペーンには心打たれました。
www.excite.co.jp
うどん屋さんが糖質ダイエッッターのために、主力のうどんを売らずブロッコリーを売る、というなんともホスピタリティ(とネタ感)あふれるキャンペーンになっています。

そんなノリで回転寿司屋さんも「同金額でシャリ抜き対応!」とかすればバズりそうですけど、二番煎じ感があるなあ、と深夜にご飯食べながら思ったのです。

どうせなら突き抜けたい。そう思ったキャンペーンがこちら。

「エアー寿司キャンペーン」

概要:
シャリ抜きオプションの更に上を行く、ネタまで抜いた新商品
回転寿司の中に、寿司の乗っていない皿をある頻度で流す。
更にはQRコードが貼ってあって、クーポンコード的なのがついたディープリンクで、キャンペーンに対応したアプリにクーポン識別子を突っ込む機能を有する。(これは後の抽選で使う)
ディープリンクからアプリ起動で、Snow的な感じの「VRな寿司」のハッシュタグTweetすることでキャンペーン応募。
抽選でなんかしらのインセンティブ()
(CM等メディア露出には落語家の食べ芸やエアーギターな人とのコラボ的なの

どうかな。弱いかな。

シャリ抜きオプションした回数をアプリに記憶して「あなたはこれだけ炭水化物(糖質)を摂取しなかった!」ランキングとか。。。
寝よ。

TypeScript2.0の型管理とnode.d.tsとtsdとtypingsとnpm @typesとわたし

分かる人にはT/Oです。

ここ数日の連休を使っても、あまりにもTypescript(+node+express)開発が遅々として進まないのを全部Typescriptの型管理のせいだと思うことにしました。
〜 数日前 〜
「よーし、TypeScriptいれちゃうぞー(‾◡◝ )」
「あれ?Webstormでmoduleのとこがエラーだ。」
「おお、型情報ファイルnode.d.tsというのが必要なのか。。。」
github.com
「おお、エラーがなくなったー(‾◡◝ )」
「でもこのrepositoryのファイルが更新されなくなったら新しいライブラリとかどうすんねん。。。ん?TypeScriptの型管理tsd?」
qiita.com
f:id:bhind:20160926002901p:plain
「まあ、いい。tsd入れて、、あれ?対応してないmoduleが多いな。ネットで調べるか。。。ん?」
qiita.com
f:id:bhind:20160926002901p:plain
「まあ、いい。typingsいれて、、、なんかインストールしづらいな。へえnpmソースのとかあるんだ、、、ん?npmソース?」
qiita.com
f:id:bhind:20160926002901p:plain

このあと、めちゃくちゃnpm install --save @types/hogeしまくった。(heroku的にsaveする意味あるんかな?

今の課題: tscが走るたびにティーブレイクするWebstorm
f:id:bhind:20160926003758p:plain

更新: 2016-09-26 1:40
npm @typesしたら解決すると思ったらまたティーブレイクのあとエラーがでたので、tsconfig.jsonのcompilerOptions配下にtypesしていしたら治りました。(なんでじゃ

更新: 2016-09-26 2:13
app.ts書き換えてもjsに反映されないなと思ったら、tsconfig.jsonのパースエラーでてて「typesなんぞしらん」と今頃いわれたので削除したらちゃんと動きましたし。(なんでじゃ

更新: 2016-09-26 3:07
あれだ。tsconfig.jsonでパースエラーになってて、Webstorm上ではそもそもrequireのバリデーションがされなくなっただけっぽいです。色々試そうとコンパイルを手動にしたらWebstormが2回連続で落ちてなんだかもうTypeScriptごと嫌いになりそう。

更新: 2016-09-26 14:40
やだ、今日の日付じゃないの。乗り換えちゃおっかなー(‾◡◝ )
blog.yuhiisk.com

Docomo 歩いてオトクの2万歩の壁

とある関係から、Docomo 歩いてオトクアプリをはじめました。Docomoキャリア向け月額324円のiモードディスクリプション型モデルです。
www.d-healthcare.co.jp

「歩いて」といういうと、まるで歩く歩数に比例してポイントが貰えそうですが、実際には「ツアー」と呼ばれる中にある「お得スポット」というチェックポイントような場所での抽選による3グレードの箱に依存して付与されるポイント数が決定されます。ただ、チェックポイント通過時にはまだ付与されるず、「ツアー」の全規定歩数分あるくとようやくもらえるシステムになっています。


f:id:bhind:20160925195356j:plain

f:id:bhind:20160925195409j:plain



月額324円なのでひと月324ポイント以上稼ぐことで、単純にはもとが取れる計算(浪費した時間などはおいておいて)なわけですが、先日ジョギングあと買い物をしていたら、、、「歩数が上限に到達!」という通知が。なんのことかと開いてみると、どうも1日あたり2万歩を超えるとツアーへの歩数へと換算されなくなるみたいです。10kmジョギングしただけなのに。。。


f:id:bhind:20160925195428j:plain

f:id:bhind:20160925195439j:plain


いろいろ思うことはありましたが、初月が終わったら見直そうとそっ閉じしました。。。〜 完 〜

更新 2016-10-02 16:26
チェックポイントを2個以上通過すると最新より前のポイントは取得できない模様

f:id:bhind:20161002162744j:plain

これは…ポイントに直結することやからちゃんと事前にユーザーに告知せんとあかんて(◞‸◟)(意識して動作確認してたから見逃しはないはず

やろうと思っているゲーム(2016-09-15)

この開発者のゲームがものすごく興味深い。

ただのアセンブラ TIS-100 on Steam

異星人のために工場つくる
Infinifactory on Steam

なんか超古代的プログラミング
SpaceChem on Steam

まあUndertaleもLife is strangeも途中なんすけどね。