しおしお

IntelliJのあれやこれや

IntelliJ IDEA 2017.3 EAPからのeditor-based REST clientを試す

IntelliJ IDEA 2017.3(今はEAP)から追加されたeditor-based REST clientを試してみたよ。
詳しくは、What’s New in IntelliJ IDEA 2017.3 EAP? | IntelliJ IDEA BlogToolsに書かれてるよ。

試すために作ったサーバ側のコード

GETとPOSTを確認するためだけの簡単な実装で・・・

@RestController
@RequestMapping("/api")
class Api {

    data class Data(val value: String)

    @GetMapping
    fun get(@RequestHeader("X-Hoge") hoge: String): Data = Data("X-Hogeは $hoge でした")

    @PostMapping
    fun post(@RequestBody data: Data): ResponseEntity<Unit> {
        val httpHeaders = HttpHeaders()
        httpHeaders["x-hoge"] = listOf(data.toString())
        return ResponseEntity(httpHeaders, HttpStatus.OK)
    }
}

getを試す

拡張子がhttpだと、editor-based REST clientとして認識されるので、適当なところに拡張子がhttpのファイルを作ってあげる。
プロジェクト配下に置く必要がなければ、blogにあるようにScratch Fileとして作ってあげればよいのかなと。

ファイルの中身はこんな感じにする。

### get
# GETのあとにスペースを開けてURLを指定する。
# HTTP Headerは次の行から列挙する。
GET http://localhost:8080/api
X-Hoge: aaaa

こんな感じに補完もできるので割と良い感じ。
f:id:sioiri:20170916171909g:plain

実行はエディタの横に表示されている実行アイコンから行うと。
f:id:sioiri:20170916170331p:plain

実行結果は、Run Windowに表示されると。
レスポンスボディの内容は、プロジェクトの.idea/httpRequestsの下に自動的に保存されるから、あとから参照もできる。
繰り返し実行した場合、大量に保存されそうだから自分で消さないとダメなのかなー。。。
f:id:sioiri:20170916170603p:plain

postを試す

getと同じように拡張子がhttpなファイルを作る。

こんな感じにヘッダーの後に空行いれて送信するボディを定義すると

POST http://localhost:8080/api
Content-Type: application/json

{
  "value": "fuga"
}

こんな感じにファイルに定義した内容をボディを送るれるみたい。
指定するファイルのパスは相対パスの場合はプロジェクト直下から。

POST http://localhost:8080/api
Content-Type: application/json

< ./input/input.json

実行方法や、結果の参照はgetと同じ感じ。
GUIのREST Clientより繰り返し実行するのは便利かも?

おわり。

GradleからJUnit5のテストを実行する

junit5-gradle-consumerを参考にするとさくっとGradleで実行できるようになる。

build.gradle

JUnit Platform Gradle Pluginを設定して、testRuntimeにjunit-jupiter-engineを追加してあげる必要がる。

buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0'
  }
}

apply plugin: 'org.junit.platform.gradle.plugin'

dependencies {
  testCompile 'org.junit.jupiter:junit-jupiter-api:5.0.0'
  testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.0.0'
}

テストの実行

テストを実行するとこんな感じに結果が表示される。
残念ながらGradleさんのtest reportには対応していないみたいでhtmlは保存されないみたい。
なお、テスト結果のxmlは出力されるので、JUnit4の時と同じようにCIでは結果を集計できる。

➜  junit5-sample ./gradlew clean test

> Task :compileTestKotlin
Using kotlin incremental compilation

> Task :junitPlatformTest

Test run finished after 139 ms
[         5 containers found      ]
[         0 containers skipped    ]
[         5 containers started    ]
[         0 containers aborted    ]
[         5 containers successful ]
[         0 containers failed     ]
[         4 tests found           ]
[         0 tests skipped         ]
[         4 tests started         ]
[         0 tests aborted         ]
[         4 tests successful      ]
[         0 tests failed          ]



BUILD SUCCESSFUL in 1s

おわり。

JUnit5のParameterized Testを試してみる

実験的機能っぽいけど、JUnit5でもParameterized Testsができるみたいなので、お試ししてみたよ。

必要なライブラリを追加

junit-jupiter-apiとParameterized Testをするために必要なjunit-jupiter-paramsを追加してあげる。

testCompile 'org.junit.jupiter:junit-jupiter-api:5.0.0'
testCompile 'org.junit.jupiter:junit-jupiter-params:5.0.0'

テストコードを書いてみる

ドキュメントを参考に書いてみた。
Testアノテーションは不要で、ParameterizedTestアノテーションを設定してあげるみたい。
テストデータはValueSourceアノテーションに設定する。ValueSourceアノテーションでは一部の型だけが使えるっぽい。
データはメソッドの引数で受け取ってあげると。

@ParameterizedTest
@ValueSource(strings = {"1", "2"})
void sample(final String value) {
  assertEquals(1, value.length());
}

IntelliJ IDEA(2017.3系)で実行

実行できた!IntelliJさんParameterizedTestに対応していい感じに表示してくれてすげー
f:id:sioiri:20170914200518p:plain

ValueSourceで指定できないデータの場合

MethodSourceを使うパターン

MethodSourceアノテーションで指定した名前のstaticなメソッドを作り、そこでデータを作ってコレクションで返してあげる感じみたいです。

companion object {
    @JvmStatic
    fun data() = listOf(
            arrayOf("hoge", 4),
            arrayOf("1", 1)
    )
}

@ParameterizedTest
@MethodSource("data")
fun sample2(input: String, expected: Int) {
    assertEquals(expected, input.length)
}

Kotlinだけどちゃんと動いてていい感じです。
f:id:sioiri:20170914202239p:plain

ArgumentsSourceを使うパターン

ArgumentsSourceアノテーションで指定したクラス(ArgumentsProviderの実装クラス)でパラメータを生成してあげます。

@ParameterizedTest
@ArgumentsSource(MyArgumentsProvider::class)
fun sample3(value: Pair<String, Int>) {
    assertEquals(value.second, value.first.length)
}

// このクラスでパラメータを生成する。
// この例だと、2つのパラメータをが作られます。
class MyArgumentsProvider : ArgumentsProvider {
    override fun provideArguments(context: ExtensionContext?): Stream<out Arguments> =
            Stream.of(Pair("hoge", 4), Pair("abcdefg", 7))
                    .map { Arguments.of(it) }
}

ちゃんと2回実行されてますね。
f:id:sioiri:20170915214102p:plain
おわり。

GradleのcompileOnly知らなかったので使ってみた

Gradle2.12からコンパイル専用のスコープが導入されていたらしいので試してみた。

build.gradleの定義

compileOnlyを使うことで、コンパイル時のみ依存するライブラリを定義できる。
testCompileOnlyを使うと、テストのコンパイルじのみ必要なライブラリを定義できる。

compileOnly 'javax:javaee-api:7.0'

微妙なところ

compileOnlyはtestCompileやtestRuntimeへは引き継がれない。
なので、テストコードから使いたい場合はテスト用のスコープにも追加してあげる必要がある。

一律テスト用のスコープに追加しても問題はないと思うので、これが一番簡単かなと思われる。
compileOnlyを追加した場合にも自動的に追加されるし。

sourceSets.test {
  compileClasspath += configurations.compileOnly
  runtimeClasspath += configurations.compileOnly
}

sphinx-javalinkを使ってSphinxドキュメントからJavadocへのリンクをはってみる

Sphinxで作ったドキュメントから、Javadocへのリンクをはれる拡張のsphinx-javalinkの使い方。
※昔書いた、sphinxからjavadocへのリンク簡単に貼れる拡張 - しおしおのほうが使い方は簡単なんだけど、Java8で作られたドキュメントへのリンクがうまくできない問題があったりする。

インストール

pipを使ってインストールする。

pip install sphinx-javalink

拡張を使えるようにする

conf.pyのextensionsにこの拡張を使えるよう設定を追加する。
下のように、javalinkを追加する。

extensions = ['javalink']

javalinkに対する設定をする

conf.pyにいくつか設定を追加する。javalink_classpathの設定はわりと面倒な感じがある。

# 設定を追加するためのimport
import javalink

# Java8で生成したドキュメントへリンクをはる(デフォルトだと7)
javalink_default_version = 8

# クラスを探すためのライブラリのパスの設定
# javalink.find_rt_jar()と書くと、JAVA_HOMEからrt.jarを探してくれる
# 自分のプロジェクトのライブラリに対してリンクを貼りたい場合は、
# そのプロジェクトのjarのパスかビルド後のクラスファイルが
# 出力されるディレクトリを指定する必要がある。
javalink_classpath = [
    javalink.find_rt_jar(),
    '/home/siosio/junit-4.12.jar'
]

# Javadocのリンク先を列挙する。
# 列挙しておけば、あとは良さげにリンク先を設定してくれるらしい
javalink_docroots = [
    'https://docs.oracle.com/javase/jp/8/docs/api/',
    'http://junit.org/junit4/javadoc/latest/'
]

rstを書いて・・・

javarefを使って、リンクをはれる。
メソッドに飛ばす場合は、クラスメイトメソッド名を#で区切る。(Javadocの@seeの書き方とかと一緒)

* こんな感じにリンクをはれる →  :javaref:`java.lang.Object`
* メソッドに対しては、こんなかんじになる → :javaref:`java.lang.String#valueOf(java.lang.Object)`
* Javaのライブラリ以外もいける :javaref:`@Test <org.junit.Test>` アノテーションにもとべる

ビルドして・・・

こんな感じに生成される。
f:id:sioiri:20170802124131p:plain

IntelliJ IDEAのjump to colors and fontsが便利過ぎる件

いまいさんのこんなツィート見かけて、かなり便利そうなのでちょっと試してみた。

なにが便利かというと、jump to colors and fontsを使うと、今カーソルがある要素の色設定にダイレクトで飛べるようにる。
これで、File | Settings | Editor | Color Schemeから、頑張って色設定を変えたい要素を探す必要がなくなる感じ。

なお、使えるようになったのは2017.2からだと思われる。

使い方

使い方は、色設定を変えたい要素にカーソルを移動して、Find Actionからjump to colors and fontsを選んであげます。*1
f:id:sioiri:20170727135934p:plain
もし、複数の設定項目がある場合は、下の画像のようにどの設定に行くか聞いてくれるので、かなり親切です。
f:id:sioiri:20170727135937p:plain

微妙に伝わりづらいような気がするけど、使ってみると便利さわかるかなと。

おわり。

*1:デフォルトはショートカットキーも割り当てられていないので、Find Actionからアクションを実行しないとダメ

Gradleのsonarqubeプラグインを使ってみる

Analyzing with SonarQube Scanner for Gradle - Scanners - Doc SonarQubeを使ってGradleなプロジェクトの品質チェックを行う方法。

sonarqubeプラグインを導入する

Gradleのbuildスクリプトに以下を追加する。(バージョンは現時点での最新)

plugins {
  id "org.sonarqube" version "2.5"
}

※sonarqubeプラグインに対する設定値などはこちら→SonarQube properties
なお、Gradleのデフォルト構成のプロジェクトの場合は基本設定は不要。

カバレッジを取得する場合はjacocoプラグインも導入する

カバレッジ情報をsonarqubeに連携する場合には、gradleにjacocoプラグインを追加してあげる。

apply plugin: "jacoco"

sonarqubeの場所をgradle.propertiesに設定する

systemProp.sonar.host.url=http://localhost:9000

sonarqubeタスクを実行する

sonarqubeタスクを実行する。jacoco.reportPathが非推奨と言われるけど、これはsonarqubeプラグインのデフォルト設定なやつなので、次回以降のバージョンアップで解消するのではと思う。

./gradlew clean sonarqube
:clean
:compileJava
:processResources NO-SOURCE
:classes
:compileTestJava
:processTestResources NO-SOURCE
:testClasses
:test
:sonarqube
Property 'sonar.jacoco.reportPath' is deprecated. Please use 'sonar.jacoco.reportPaths' instead.

BUILD SUCCESSFUL

sonarqubeで見てみると

こんな感じに結果が見れる。
f:id:sioiri:20170722065139p:plain

sonarqubeを用意するのにつかったcomposeファイル

postgresql:
  image: postgres
  ports:
    - "5432:5432"
  environment:
    - POSTGRES_USER=sonar
    - POSTGRES_PASSWORD=sonar
    - POSTGRES_DB=sonar
sonarqube:
  image: sonarqube
  ports:
    - "9000:9000"
    - "9092:9092"
  environment:
    - SONARQUBE_JDBC_USERNAME=sonar
    - SONARQUBE_JDBC_PASSWORD=sonar
    - SONARQUBE_JDBC_URL=jdbc:postgresql://postgresql/sonar
  links:
    - postgresql


おわり。