のえら

技術備忘とかメモとか.間違いはつっこんでいただきたい所存.アフィリエイトはやっていません.

チャレンジ失敗の原因と攻略「猫の品種を認識する Cat Rescue アプリケーションの構築」編

今回はプロジェクト「猫の品種を認識する Cat Rescue アプリケーションの構築」の単元「Lightning アプリケーションとカスタムオブジェクトの作成」から。

trailhead.salesforce.com

カスタムオブジェクトを作成後、セクション「猫と人のレコードを作成する」の手順に沿って、サンプルデータを登録する。

  1. [Cats (猫)] タブを選択して、[New (新規)] をクリックします。
  2. [Cat Name (猫の名前)] に「Elvis」と入力します。
  3. [Save & New (保存 & 新規)] をクリックします。
  4. [Cat Name (猫の名前)] に「Amanda」と入力します。
  5. [Save & New (保存 & 新規)] をクリックします。
  6. [Cat Name (猫の名前)] に「Amanda」と入力します。
  7. [Save (保存)] をクリックします。

ステップを確認すると、以下のメッセージが。

Challenge Not yet complete... here's what's wrong:
Please validate that three cats exist with the names 'Elvis', 'Marissa', and 'Amanda'.

サンプルデータの登録で'Amanda'が2つ登場しているが、1つは'Amanda'ではなく'Marissa'で登録しましょう。

Trailhead は日本語訳が怪しかったり、チャレンジのテキストに誤りがあったり、ちょいちょい本筋とは関係ないところにもハマりどころがあるので、細かいところでも、今後の自分のためにメモしておくことにします。

SQL PowerArchitect を MacOS で使う

概要

プロジェクトで ER 図を見るのに PowerArchitect を使用しているのだけども古いバージョンの Java が必要だったのでメモ

環境

MacOS: High Sierra(10.13.3)

手順

ここからダウンロード、インストールする https://code.google.com/archive/p/power-architect/

開くと、以下のメッセージが表示される。

"PowerArchitect"を開くには、以前のJava SE 6 ランタイムをインストールする必要があります。

→「詳しい情報」をクリックすると Java ランタイムの DL ページに遷移する

MacOS 用 java6 ランタイム https://support.apple.com/kb/DL1572?locale=ja_JP

ページ上部の「ダウンロード」からダウンロード→インストール

f:id:noterr0001:20180322144555p:plain

1ヶ月をミリ秒に換算して使いたい(Java編)

*最大31日としたいので日数は31日固定

1日 = 24時間
1時間 = 60分
1分 = 60秒
1秒 = 1000ミリ秒

31 * 24 * 60 * 60 * 1000

期待している結果は 2678400000 だったがユニットテストを実行してみると -1616567296 になっていた。

よくみると IntelliJ で警告が表示されていることに気がつく。

Numeric overflow expression This inspection checks for expressions which overflow during computation, i.e.: a = 1.0/0.0;

Integer は 2147483647 が最大値なので、オーバーフローを起こしていた。

最大値が収まる Long 型にするため、乗算する際にミリ秒を L で Long 型にして、計算結果を暗黙的にキャストする。

31 * 24 * 60 * 60 * 1000L

rails new でバージョン指定したのに上のバージョンになって困った話

初歩的なミスなのですが。

バージョンを指定して新規プロジェクトするのに、以下のコマンドを実行。

rails _5.0.2_ new sample

(中略)

-> Installing rails 5.0.6

>>5.0.6<<

!?

rails new 実行すると続けて bundle install が走るため Gemfile にデフォルトで記述される 5.0.2「以上」が反映されてしまう。

bundle install をスキップして、バージョンを指定後 bundle install すればOK

rails _5.0.2_ new sample --skip-bundle
cd sample
vi Gemfile

gem 'rails', '~> 5.0.2'

gem 'rails', '= 5.0.2'

にする

bundle install --path=vendor/bundle

macOS Sierra(10.12.6) に rails をインストールした

開発用に MacBook Air を購入したので rails をインストールしたときのメモを残す。
今回は以下のツール・環境で構築した。

homebrew のインストール

homebrew をインストールするのに XCode(Command Line Tools for Xcode) をインストールしなきゃいけないなー、と思っていたら、以下のコマンドを叩いて homebrew をインストールすると、実行途中で Xcode ないやで?インストールする?と聞かれるんですね。

ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
# 確認
brew doctor
rbenv のインストール
brew update
brew install rbenv ruby-build 
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
source ~/.bash_profile
ruby のインストール
# ruby のバージョン確認
rbenv install -l
# 2.4.2をインストール
rbenv install 2.4.2
# 環境全体で使用するバージョンを設定
rbenv global 2.4.2
# インストールの確認
ruby -v
rails のインストール
gem install rails

デフォルトでインストールされたもの

Done installing documentation for i18n, thread_safe, tzinfo, concurrent-ruby, activesupport, rack, rack-test, mini_portile2, nokogiri, crass, loofah, rails-html-sanitizer, rails-dom-testing, builder, erubi, actionview, actionpack, activemodel, arel, activerecord, globalid, activejob, mime-types-data, mime-types, mail, actionmailer, nio4r, websocket-extensions, websocket-driver, actioncable, thor, method_source, railties, bundler, sprockets, sprockets-rails, rails after 70 seconds

bundler のインストール
gem install bundler
設定の反映
rbenv rehash
source ~/.bash_profile

# インストールの確認
rails -v
> Rails 5.1.4

Groovyc: unexpected token: } と whereブロック

Spock(Groovy)のテストケースを書いていて、後からwhereブロックを追加したら以下のエラーが出たけど始めなんで怒られているのかわからなかった。

Groovyc: unexpected token: }

書いていたテストはこんな感じ。
API叩いて結果を確認するだけ。

def 'GET: /hoge/list Hogeの一覧を返す'() {
  when:
  // APIリクエスト クロージャ
  def request = {
    // Rest execute
  }
  
  then:
  with(request.call()) {
    it.status == xxx
    it.body == xxx
  }
}

と、シンプルなフィーチャーメソッドを作成して、後から色々なパラメータ与えたくなってwhereを追加した。
パラメータ自体は1種だけ。

def 'GET: /hoge/list Hogeの一覧を返す'() {
  when:
  def request = {
    // Rest execute(params) <-ここにwhereブロックの変数paramsが入る
  }
  
  then:
  with(request.call()) {
    it.status == xxx
    it.body == xxx
  }

  where:
  params || -
  1           || -
  2           || -
  null       || -
}

こんな感じで、データテーブルは1行では認識されないため、最低2列用意しないといけないのはわかっていたので、規約に沿って空白列を追加。
で、追加したところで、前述のエラーメッセージ。
閉じ位置は変えていないのになんでだろ?と思ってよく見直したら、空白列でアンダーバーを記述しなければならない箇所でハイフンを記述していたのでワイルドカードが認識されずにエラーになっていただけという。

正しくはwhereブロックはこうなる。

where:
param || _
1          || _
2          || _
null      || _

ハイフンは変数ではないので当たり前のことなんだけども、ぼーっとしながら書いちゃダメだなと思った。

テーブルデータが1つなら、空白列足すよりパイプ使った方がスッキリするやも。

where:
param << [1, 2, null]


ちなみに、whereブロックを1つだけしか定義しないと以下のエラーメッセージが表示される。めっちゃ丁寧。

Groovyc: where-blocks may only contain parameterizations (e.g. 'salary << [1000, 5000, 9000]; salaryk = salary / 1000')

Rspecの呼び出し回数チェックテストで全件通し実行するとコケていた件

rspecでrake task系のユニットテストで、onceなどのメソッド呼び出し回数チェックを使用していた。
それらのユニットテストをそれ単体で実行すると成功するが、テストを通して全件実行すると失敗する。
検証したところ、spec/lib/tasks/xxx_spec.rb で以下のようにrake taskを呼び出すためにロードしているが、 Rake::Task[task_name].invoke がこのコードを読み込んだ回数分、指定のタスクを実行していた。

before(:all) do
  Rails.application.load_tasks
end

このため、同様のrake task系テストをまとめているディレクトリ配下のユニットテストを通しで実行すると、回数を検証するonceなどを使用しているitブロックで複数回rake叩いた挙動になってしまい、テストに失敗する。

例)
spec/aaa_task_spec.rb

before(:all) do
  Rails.application.load_tasks
end

context 'HogeClass#foo' do
  it { expect(HogeClass).to receive(:foo).once.with(kind_of(RuntimeError)) }
end

spec/bbb_task_spec.rb

before(:all) do
  Rails.application.load_tasks
end

context 'FugaClass#foo' do
  it { expect(FugaClass).to receive(:foo).once.with(kind_of(RuntimeError)) }
end

spec/ccc_task_spec.rb

before(:all) do
  Rails.application.load_tasks
end

context 'HogeClass#foo' do
  it { expect(HogeClass).to receive(:foo).once.with(kind_of(RuntimeError)) }
end

rspec spec/

  • > 1) HogeClass#foo

Failure/Error: expect(HogeClass).to receive(:foo).once.with(kind_of(RuntimeError))

(HogeClass (class)).foo(kind of RuntimeError)
expected: 1 time with arguments: (kind of RuntimeError)
received: 2 times
...

※load_tasksを呼び出す回数ずつ増える

解決策の例

1)各ファイルでのタスク読み込みをやめてspec_helperなどで一回だけ呼ぶようにする
2)タスク読み込みをまとめて行うのではなく、都度Rake.application.rake_requireする

rails_helperにて一回だけ呼ぶように変更