Generics 周りの挙動の備忘録。 適当な空のクラスをマーカーとして、メソッドの振る舞いを変えられた。
WIP Pull Request Unhighlignter for GitHub が使えなくなったので Tampermonkey の UserScript で再実装した
WIP Pull Request Unhighlignter for GitHub が便利で今まで使っていたけど、昨日突然使えなくなった。
※ 原因はGitHubのCSSセレクタが変わったため。現在は kyanny/chrome-ext-wip-pull-request-unhighlighter-for-github#6 がマージされ動くようになってる。
再実装した
待っていれば直ると思ったけど、予想以上に無いと困ったので最低限の機能を Tampermonkey の UserScript として再実装した。 ついでに、 pjax で画面遷移した時も動くようにした。
本当はプルリク投げた方が良いかなーと思いつつ、CSSセレクタの指定は好みある*1だろうし、テストコードも無かったので面倒で止めた。
*1:個人的にはclass指定よりidの方が壊れにくいと思うけど、本家はclass使っている
Swift の Mirror API を触って、動作を XCTest で確認した
今日やってた勉強内容。
動かし方
$ git clone https://github.com/sinsoku/study.git $ cd study/swift $ bin/run swift build -C PlayGround $ bin/run swift test -C PlayGround
ソースコード
// PlayGround/Sources/PlayGround/SimpleClass.swift class BaseClass { let number: Int = 0 let string: String? = nil } class SimpleClass: BaseClass { }
テストコード
// PlayGround/Tests/PlayGround/SimpleClassTests.swift import XCTest @testable import PlayGround class SimpleClassTests: XCTestCase { func testSimpleClassBehavior() { let obj = SimpleClass() // refs: https://stackoverflow.com/questions/25725033/swift-too-smart-checking-an-objects-type-when-testing-with-xctest XCTAssertTrue((obj as Any) is SimpleClass) XCTAssertTrue((obj as Any) is BaseClass) } // refs: https://github.com/apple/swift/blob/swift-DEVELOPMENT-SNAPSHOT-2016-06-06-a/stdlib/public/core/Mirror.swift#L137 func testReflectionBehavior() { let playGround = Mirror(reflecting: PlayGround()) XCTAssertEqual(playGround.description, "Mirror for PlayGround") XCTAssertEqual(playGround.displayStyle, Mirror.DisplayStyle.struct) XCTAssertTrue(playGround.subjectType == PlayGround.self) let base = Mirror(reflecting: BaseClass()) XCTAssertEqual(base.description, "Mirror for BaseClass") XCTAssertEqual(base.displayStyle, Mirror.DisplayStyle.class) XCTAssertTrue(base.subjectType == BaseClass.self) let simple = Mirror(reflecting: SimpleClass()) XCTAssertEqual(simple.description, "Mirror for SimpleClass") XCTAssertEqual(simple.displayStyle, Mirror.DisplayStyle.class) XCTAssertTrue(simple.subjectType == SimpleClass.self) let parent = simple.superclassMirror XCTAssertEqual(parent?.description, "Mirror for BaseClass") XCTAssertEqual(parent?.displayStyle, Mirror.DisplayStyle.class) XCTAssertTrue(parent?.subjectType == BaseClass.self) let defNumber = base.children.filter { $0.label == "number" }[0] XCTAssertEqual((defNumber.value as! Int), 0) let defString = base.children.filter { $0.label == "string" }[0] // FIXME: the assertion is failed. (XCTAssertNil failed: "nil") // XCTAssertNil(defString.value) XCTAssertEqual(String(defString.value), "nil") } static var allTests : [(String, (SimpleClassTests) -> () throws -> Void)] { return [ ("testSimpleClassBehavior", testSimpleClassBehavior), ("testReflectionBehavior", testReflectionBehavior), ] } }
FIXME について
value の型が Optional<String>
にはなっているっぽいのに、なぜか nil
にはならずにテストが通らなかった。
結局、よく分からないまま・・・。
XCode でも調べてみた
class Foo { let number: Int? = nil } let m = Mirror(reflecting: Foo()) let defNumber = m.children.filter { $0.label == "number" }[0] defNumber.value == nil // Playground execution failed: MyPlayground.playground:1:17: error: value of type 'Any' (aka 'protocol<>') can never be nil, comparison isn't allowed // defNumber.value == nil //~~~~~~~~~~~~~~~ ^
エラーでるけど、結局 value
の返す値が何なのかが不明・・・。
参考にしたページ
XCode を使わず Swift で TDD しながら FizzBuzz を書いてみた
この前作った Swift の環境 で勉強として FizzBuzz を書いてみた。
パッケージの作り方
$ mkdir FizzBuzz $ cd FizzBuzz $ swift package init
コード
// Sources/app/FizzBuzz.swift class FizzBuzz { let num : Int init(num : Int) { self.num = num } func toString() -> String { switch self.num { case let n where n % 15 == 0: return "FizzBuzz" case let n where n % 3 == 0: return "Fizz" case let n where n % 5 == 0: return "Buzz" default: return String(self.num) } } }
// Tests/app/FizzBuzzTests.swift import XCTest @testable import app class FizzBuzzTests: XCTestCase { func testThree() { let fizzBuzz = FizzBuzz(num: 3) XCTAssertEqual(fizzBuzz.toString(), "Fizz") } func testFive() { let fizzBuzz = FizzBuzz(num: 5) XCTAssertEqual(fizzBuzz.toString(), "Buzz") } func testFifteen() { let fizzBuzz = FizzBuzz(num: 15) XCTAssertEqual(fizzBuzz.toString(), "FizzBuzz") } func testOther() { let fizzBuzz = FizzBuzz(num: 1) XCTAssertEqual(fizzBuzz.toString(), "1") } static var allTests : [(String, (FizzBuzzTests) -> () throws -> Void)] { return [ ("testThree", testThree), ("testFive", testFive), ("testFifteen", testFifteen), ("testOther", testOther) ] } }
テストの実行方法
$ swift build $ swift test
Travis CI で npm package の自動リリースに挑戦したら失敗したので、 package を deprecate した話
Travis CI で npm package を自動リリースできるっぽいので、設定してみた。
そして、失敗したので deprecate した話。
参考ページ
npm Releasing
https://docs.travis-ci.com/user/deployment/npm
やったこと
clairvoyance の npm publish を自動化してみようと、上記のページを参考に設定してみた。
# .travis.yml deploy: provider: npm email: sinsoku.listy@gmail.com on: tags: true
npm の api token は npm login
を実行すると、 ~/.npmrc
に追記されるので、それを travis
コマンドで設定する。
$ travis encrypt YOUR_API_KEY --add deploy.api_key
あとは git tag
でタグを作成し、 git push origin v0.4.1
でプッシュすると自動的に publish された。
リリース失敗
新しいバージョンである v0.4.1 が自動的に publish されたが、パッケージが壊れていた。
原因は gulp build
した後のファイルがパッケージに含まれていないため。
修正&再リリース
このあたり を読むと、 .npmignore
がない場合、デフォルトでは .gitignore
を参照するっぽい。というわけで、 .npmignore
を用意した。
coverage/ maps/ node_modules/ src/ test/
そして、新たに v0.4.2
のタグを作ってプッシュしたところ、動くようになった。
npm-deprecate
公開してしまった v0.4.1
は deprecate
にしておいた。
$ npm deprecate clairvoyance@0.4.1 "v0.4.1 does not work, please upgrade to v0.4.2."
ちゃんとインストールするときに WARNING が出るようになってた。
$ npm i clairvoyance@0.4.1 npm WARN deprecated clairvoyance@0.4.1: v0.4.1 does not work, please upgrade to v0.4.2.
Swift の勉強する環境を docker を使って構築する
docker で勉強する環境を作ってみた。
準備
リポジトリと README を見てもらえば分かるけど、下記のような bin/run
のスクリプトを用意する。
#!/bin/sh if [ -n "$*" ] then docker run -v $(pwd):/app -w /app swiftdocker/swift $* else docker run --privileged -it swiftdocker/swift swift fi
使い方
REPL で試したい場合は bin/run
を実行する。
$ bin/run Welcome to Swift version 3.0-dev (LLVM 8fcf602916, Clang cf0a734990, Swift 000d413a62). Type :help for assistance. 1>
終了するときは :exit
を入力する。
*.swift
を実行したいときは bin/run swift sample/hello.swift
のように実行する。
$ bin/run swift sample/hello.swift Hello, World!
Mac で docker-machine の IP を localdocker にしておくと捗る
Mac で docker を使うと、docker-machine の IP にアクセスするときが少し面倒です。
これを /etc/hosts
を使って localdocker
でアクセスできるようにしておくと便利って備忘録。
準備
まず、 /etc/hosts
にこんな感じで書いておく。
127.0.0.1 localdocker
次に、下記のようなスクリプトを用意しておく。
- up_localdocker
#!/bin/sh eval $(docker-machine env default) sudo sed -i '' "s/.*localdocker$/$(docker-machine ip default) localdocker/" /etc/hosts
使い方
docker-machine の再起動の後などにスクリプトを実行すれば環境変数や /etc/hosts
が更新される。
$ . up_localdocker
. up_localdocker
と実行すれば IP が更新されます。