備忘録」カテゴリーアーカイブ

Capybara(Rspec)で指定したセレクタ要素が存在しないことを検証する

以前は以下を参考にして例外を発生させて検証してたが、

Capybaraで要素がないことをテストする方法 | 自転車で通勤しましょ♪ブログ http://319ring.net/blog/archives/2546/

以下で充分検証することができた。例外待ちしない分こちらのほうが高速。

def cant_find(selecter)
  expect(page.all(selecter).empty?).to eq true
end

GUIでgitを使っている人がCUIに乗り換えるための基礎知識

前提

本記事は以下の環境で動作確認しています

要素 バージョン
debian 8.6
git 2.1.4

また、本記事中ではリモートリポジトリとして、私用のGitHubを用いています。リモートリポジトリは以下のものを用いて、空の状態からスタートするものとします。

git@github.com:Sa2Knight/git_test.git

CUIによるメリット

SourceTreeなどのGUIツールを使う場合と、CUIでgitコマンドを叩いて利用する場合では、どちらもメリット・デメリットが存在すると思います。ここでは、CUIを使う場合のメリットにのみ触れますが、デメリットについてはCUIの利用を躊躇ってる方々の考えるとおりだと思います。(コマンド覚える必要があるなど)

※ 以下のメリット・デメリットは私の個人的な考えが多く、実際は異なる可能性もあります。

1. 作業内容を共有しやすい

これはgitに限らずCUI全般に言えることですが、CUI上での作業は全て正確に言語化することができます。ある作業内容を相手に伝えたい場合、実行したコマンドリストを送ることで全て解決します(もちろん付加情報を自然言語で与えることも重要ですが)

対してGUIでは、操作を言語化する際に曖昧な情報になりやすく、誤解を与えやすい問題があります。

2. 定型的な作業を自動化出来る

こちらもCUI全般の話ですが、GUIでの操作と比べたとき、CUIの操作は自動化を行いやすいです。例えば、pullしてaddしてcommitしてといった一連の作業は、GUIだとマウスカーソルをそれなりに動かして、何度かクリックしたりといった定形作業が発生します。(ショートカットキーを使った場合でも)

対してCUIでは、一連の処理を一つのコマンドで実行できるようにすることで、定形作業をまとめて実行することができます。

3. 使い方を検索しやすい

言うまでもなく、バージョン管理システム”git”は、CUIツールです。SourceTreeなどのGUIツールは、GUIでgitを利用できるようにしてくれる後発のソフトウェアです。

そのため、当然ながらgitの使い方について検索した場合に出てくる情報の大半はCUIのコマンドです。もちろんSourceTreeなど、GUIソフトウェア名を検索ワードに含むことでカバーは効きますが、それでもCUIに関する情報量と比べれば雀の涙程度です。

以上より、gitを利用していて何らかの問題が発生した時に、それを検索して解決できる可能性は確実にCUIのほうが早く見つかると言えます。

4. カッコいい

これに尽きます

gitのインストール

ここでは、debianにapt-getを用いてgitをインストールします。他の環境でのインストール方法については適宜ググってください。gitは特別インストールが難しいツールではないので大丈夫だと思います。

$ sudo apt-get install git

gitがインストールされていることを確認する

$ which git
/usr/bin/git
$ git --version
git version 2.11.0

gitの利用

以降では、実際に以下の手順でgitを利用してみます。
1. ローカルリポジトリの作成
2. 空のファイルを作成してコミット
3. リモートリポジトリを登録し、pushする
4. 既存のファイルを編集する
5. 既存のファイルの削除
6. リモートリポジトリの更新をローカルリポジトリに反映

また、本項では以下のコマンドを利用します

コマンド名 内容
git init ローカルリポジトリを作成
git status リポジトリの状態を確認
git remote add リモートリポジトリを追加
git add ファイルをステージング・エリアに移動
git rm ファイルをリポジトリから削除
git diff 直前のコミットと現在のファイルの差分を確認
git commit リポジトリをコミット
git push ローカルリポジトリの更新をリモートリポジトリに反映
git pull リモートリポジトリの更新をローカルリポジトリに反映

1. ローカルリポジトリの作成

以下のコマンドは、作業ディレクトリ直下で実行してください

$ git init
Initialized empty Git repository in /home/vagrant/gittest/.git/

2. 空のファイルを作成してコミット

適当にファイルを作ります。以下は、”test”と書かれたテキストファイルを作成しています。

$ echo "test" > file1
$ cat file1
test

git statusコマンドを実行すると、リポジトリ内の現在の状態を確認できます

$ git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	file1

nothing added to commit but untracked files present (use "git add" to track)

Untracked filesは、まだリポジトリに追加されていないファイルのことです。コレに対して、git addコマンドを用いて、file1をリポジトリに追加します。

$ git add file1

もう一度git statusを実行すると、file1がリポジトリに追加され、Changes to be comittedの下にfile1が表示されていることが確認できます。この場所をステージング・エリアと呼びます。

 git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

	new file:   file1

$

コミットすることができるのは、ステージング・エリアにあるファイルのみです。つまり、現状の場合file1のみがコミット対象のファイルです。コミットは、git commitコマンドで行うことができます。

$ git commit -m "初めてのコミット"
[master (root-commit) 32cd62b] 初めてのコミット
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 file1

これで初めてのコミットが完了です。-mオプションを指定することで、”初めてのコミット”など、コミットコメントを記述することができます。-mを省略した場合、vimなどのエディタが立ち上がり、コミットメッセージの記述を求められます。

コミットが完了したことを、コミットログを閲覧することで確認することができます。コミットログの閲覧には、git logコマンドを用います。

$ git log
commit 32cd62bb013c5f8fe7021789ebb68d6a618fab9e
Author: Sa2Knight <shingo.sasaki.0529@gmail.com>
Date:   Sun Apr 23 20:15:53 2017 +0900

    初めてのコミット

“初めてのコミット”がコミットログに書き込まれていることが確認できます。

commit 32cd62bb013c5f8fe7021789ebb68d6a618fab9e

は、コミットハッシュと呼び、全てのコミットを一意に識別するための文字列です。

3.リモートリポジトリを登録し、pushする

ここでは、空のリモートリポジトリ

git@github.com:Sa2Knight/git_test.git

を登録し、ローカルリポジトリの内容をpushします。

リモートリポジトリの登録にはgit remote addコマンドを用います。

git remote add origin git@github.com:Sa2Knight/git_test.git

originはリモートリポジトリに付けた名前です。特にこだわりがなく、一つしかリモートリポジトリを使わない場合はoriginにする慣習があるっぽいです。

登録されているリモートリポジトリの一覧は、git remote -vコマンドで確認できます。

$ git remote -v
origin	git@github.com:Sa2Knight/git_test.git (fetch)
origin	git@github.com:Sa2Knight/git_test.git (push)

前項でコミットした内容をリモートリポジトリにpushします。git pushコマンドを用いてpushします。

$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 239 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:Sa2Knight/git_test.git
 * [new branch]      master -> master

masterはリモートリポジトリのブランチ名です。ブランチについて詳しくない方はとりあえずmasterと入れるものと思ってください。

4.既存のファイルを編集する

既存のfile1の内容を、”test”から”test2″に書き換えます。

$ echo "test2" > file1
$ cat file1
test2

リポジトリの状態を確認すると、file1がChanges not staged for commitの欄に表示されていることが確認できます。

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   file1

no changes added to commit (use "git add" and/or "git commit -a")

modifiedと書かれているとおり、ファイルの内容が前回のコミット時から変更されているが、ステージング・エリアに移動していないファイルを表します。

ここで、前回のコミット時と現在でファイルがどう変わったのか、git diffコマンドで確認することができます。

$ git diff file1
diff --git a/file1 b/file1
index 9daeafb..180cf83 100644
--- a/file1
+++ b/file1
@@ -1 +1 @@
-test
+test2

“- test”となっている部分は”test”という行が削除されたことを表し、逆に”+ test2″となっている部分は、”test2″という行が追加されたことを表します。

前項の手順で、ステージングエリアへの移動、コミット、プッシュを行いますが、やることは同じなので割愛します。

5.既存のファイルの削除

先程から利用していたfile1を削除します。

$ rm file1

リポジトリの状態を確認すると、今度はdeleted: file1と表示されています。

$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	deleted:    file1

no changes added to commit (use "git add" and/or "git commit -a")

これは、リポジトリに存在するファイルがディレクトリに存在しない状態を表します。リポジトリからも削除する場合は、git rmコマンドを用いて、ステージング・エリアに移動します。

$ git rm file1
rm 'file1'
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	deleted:    file1

あとはコミット、プッシュを行うだけです。

6. リモートリポジトリの更新をローカルリポジトリに反映

今度は、リモートリポジトリ側が誰かによって更新されたとします。ここでは、リモートリポジトリにfile2というファイルが追加されたことを想定して、git pullコマンドを用いてpullします。

$ git pull origin master
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:Sa2Knight/git_test
 * branch            master     -> FETCH_HEAD
   9cc3229..0d3c678  master     -> origin/master
Updating 9cc3229..0d3c678
Fast-forward
 file2 | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 file2

pull後、追加されたfile2が存在することが確認できます。

$ ls file2
file2

その他のコマンド

以下のコマンドは本記事では使用しませんでしたが、覚えると非常に役立つコマンドです。興味があればどんどん調べて使ってみてください。コマンドは私が使うもののみで、実際は他にもう少しあります。

コマンド名 内容
git checkout ファイルを直前のコミット時の状態に戻す
git stash ファイルの変更状態を一時的に保存する
git reset リポジトリの状態を特定のコミット時に戻す
git branch リポジトリのブランチに関する操作を行う
git merge 複数のブランチを統合する
git rebase 複数のコミットを統合する

AngularJSの専門用語整理その2

まさかの続き(前回)

digestサイクル

  • AngularJSがデータ双方向バインディングを実現するために、UIとモデルの差異を検証するサイクル

式(Expressions)

  • Angular式とか呼ばれてる
  • {{ 式 }} の形式でビューで展開できるJavaScriptの式っぽいもの
  • JavaScriptっぽいだけで別物
  • 全ての評価はデフォルトでスコープのプロパティに対して行われるので
  • undefinedをオブジェクトとして参照できる(無論結果は全てundefined)
  • フィルタが使える

$parse

  • Angular式を関数に変換するサービス
  • 対象のスコープを指定して関数を実行できる
    var getter = $parse('user.name');
    var context = {user:{name:'sasaki'}};
    console.log(getter(context)); // sasaki
    

$watch

  • 特定のオブジェクトやプロパティの変更を監視し、変更後に任意の処理を行わせるサービス
    $scope.hoge = 'foo';
    $scope.$watch('hoge' , function(oldValue, newValue) {
      console.log('hogeの内容が' + oldValue + 'から' + newValue + 'に変わりました');
    });
    
  • 関数を指定して、その戻り値の変化も検知できる
    $scope.$watch(function() {
      return $location.path();
    }, function() {
      console.log('パスが変わりました');
    });
    
  • watchはdigestサイクルの中で定期的に行われる

$apply

  • UIとモデルの値を同期させるサービス
  • digestサイクルの中で呼び出されるが、手動で呼び出すことも可能
  • 特にjQueryなどによってUIの値を直接書き換えた場合など、digestサイクルで検知できない場合に手動で同期させる必要がある

$inject

  • AngularJSにおける依存性注入のためのサービス
    コンストラクタ’My’に対して、依存するオブジェクト$scopeを注入してコントローラを作成する

    var My = function(s) {
      s.msg = 'Hello, AngularJS!';
    };
    My.$inject = ['$scope'];
    angular.module('myApp').controller('myController', My);
    

PHPでタイマー制御

【内容】
特定の期間内、処理を変更する。

【用途】
稼働中のサービスでメンテナンスを行う時や、
深夜等の業務時間外に処理を変更したい場合。

//規定期間開始の年月日・時間
$s_time_stamp = mktime(15,0,0,12,30,2016);
//規定期間終了の年月日・時間
$e_time_stamp = mktime(10,0,0,1,4,2017);
//現在時間の取得
$now_time = time();
//2016年12月30日 15時0分0秒~2017年1月4日 10時0分0秒の間、true側の処理を行う
if ($now_time >= $s_time_stamp && $now_time <= $e_time_stamp) {
  //規定期間内の処理

}else{
  //規定期間外の処理

}

ほぼ同じ内容で、トリガーとする日時以降か以前かで処理を分ける場合は下記の通り。

//規定時間を設定(下記の場合は、2017年2月20日 0時0分0秒以降の処理)
$trigger_time_stamp = mktime(0,0,0,2,20,2017);
//現在時間を設定
$now_time = time();
if ($now_time >= $trigger_time_stamp) {
  //規定時間後の処理

}else{
  //規定時間前の処理

}