Motomichi Works Blog

モトミチワークスブログです。その日学習したことについて書いている日記みたいなものです。

gitその0001-01 git rebase入門 indexと準備

はじめに

シリーズみたいな感じで、実際にコマンドを実行してみながらrebaseの学習をしていきます。

git rebase -igit rebase --interactiveの略です。
rebaseの様々な機能を対話形式で実行していく便利なオプションです。

rebase入門 index

git rebase入門の準備

今後色々な練習をしていくにあたって、準備作業をしました。

GitHubにremoteリポジトリを作成してcloneする

  • rebase_tutorialという名前で、remoteリポジトリをREADME.md付きで作成します
  • git clone してローカルリポジトリを作成します

sample.txtを新たに作成してaddとcommitする

以下の内容でsample.txtを作成します。

1行目

addしてcommitします。

git add sample.txt
git commit -m "1行目を追加"

同様に、sample.txtを編集して、

  • 2行目を追加してaddとcommitします。
  • 3行目を追加してaddとcommitします。

masterブランチのlogとsample.txtの記述内容

以下のコマンドを実行します。

git log --oneline

この段階でmasterブランチのログは以下のような感じです。

97029ec 3行目を追加
407e6f9 2行目を追加
30596dc 1行目を追加
d5d7400 Initial commit

sample.txtの記述内容は以下のような感じです。

1行目
2行目
3行目

masterをpushする

仕事での開発ではmasterに直接pushしないと思いますが、練習なのでpushすることにします。

git push origin master

hogeブランチを作成する

hogeブランチを作成します。

git checkout -b hoge

4~6行目をaddしてcommitする

さきほどと同様に、sample.txtを編集して、

  • 4行目を追加してaddとcommitします。
  • 5行目を追加してaddとcommitします。
  • 6行目を追加してaddとcommitします。

hogeブランチのlogとsample.txtの記述内容

以下のコマンドを実行します。

git log --oneline

この段階でhogeブランチのログは以下のような感じです。

fabb554 6行目を追加
e3e9b30 5行目を追加
356d95e 4行目を追加
97029ec 3行目を追加
407e6f9 2行目を追加
30596dc 1行目を追加
d5d7400 Initial commit

sample.txtの記述内容は以下のような感じです。

1行目
2行目
3行目
4行目
5行目
6行目

hogeブランチをpushする

hogeブランチをpushします。

git push origin hoge

masterにファイルを追加する

まずcheckoutします。

git checkout master

sample_2.txtを新たに以下の内容で作成して追加します。

sample_2.txt 1行目

add, commit, push します。

git add sample_2.txt
git commit -m "sample_2.txt 1行目を追加"
git push origin master

以下のコマンドを実行して、masterブランチのログを見てみます。

git log --oneline

以下のように表示されました。

1a35929 sample_2.txt 1行目を追加
97029ec 3行目を追加
407e6f9 2行目を追加
30596dc 1行目を追加
d5d7400 Initial commit

vagrantその0027 Windows10にvagrant_1.9.7_x86_64.msiでインストールしなおしてvagrant sshまでやってみる

参考にさせて頂いたページ

はじめに

久しぶりにvagrant upしたらエラーが出て起動できませんでしたので、最新版のVirtualBoxVagrantをインストールすることにしました。

今回の環境(インストーラーなど)

以下のとおりインストールしました。

vagrant box add する

以下のコマンドを実行しました。

$ vagrant box add centos/7

以下のように表示されたので、3でenterしました。

1) hyperv
2) libvirt
3) virtualbox
4) vmware_desktop

以下のコマンドでボックスリストを確認しました。

$ vagrant box list

以下のように表示されました。

centos/7             (virtualbox, 1706.02)

ディレクトリを作成してvagrant initする

任意の場所にディレクトリを作成して、vagrant initします。

$ mkdir sample
$ cd sample
$ vagrant init centos/7

vagrant upからsshとかhalt

以下のコマンドを実行します。

$ vagrant up

vagrant up できました。

なんか見慣れないメッセージが出ている

vagrant up したときに以下のように表示されていました。

    default: No guest additions were detected on the base box for this VM! Guest
    default: additions are required for forwarded ports, shared folders, host only
    default: networking, and more. If SSH fails on this machine, please install
    default: the guest additions and repackage the box to continue.

ポートフォワーディングやフォルダ共有などをするには、guest additionsのインストールが必要なようです。

Guest Additionsをインストールする

VagrantのboxのGuest Additionsのアップデート方法 - Qiita

を参考にさせて頂いて、インストールします。

以下のコマンドを実行して、プラグインをインストールします。

$ vagrant plugin install vagrant-vbguest

このプラグインがインストールされた状態で、vagrant reloadを実行するとGuest Additionsがインストールされます。

$ vagrant reload

ポートフォワーディングやフォルダ共有ができるようになったみたいです。

少し動かしてみます。

$ vagrant reload
$ vagrant ssh
$ exit
$ vagrant halt

今回はここまで。

package.jsonのあるディレクトリパスを指定してnpmやyarnなどのコマンドを実行する

参考にさせて頂いたページ

はじめに

CircleCIで自動的に実行されるコマンドで、npm installしたいときに調べました。

2022年追記分

npm

npm install --prefix /path/to/project

yarn

yarn --cwd /path/to/project install

例えば package.json の scripts の lint を実行したいときは以下のような感じ

yarn --cwd ./path/to/project lint

2017年に書いた分

npm installをオプションを付けずに実行したい場合

package.jsonにdependenciesやdevDependenciesが既に記述されている場合です。

例えばsome_projectディレクトリの中にpackage.jsonがある場合は以下のコマンドです。

npm --prefix ./some_project install ./some_project

--save-devなどのオプションを付けて実行したい場合

同じくsome_projectディレクトリの中にpackage.jsonがある場合に、jqueryをインストールするには以下のコマンドです。

npm install --prefix ./some_project --save-dev jquery

JSでテストコードを書く その0003-02 package.jsonをリポジトリのrootに配置せずにCircleCI上でユニットテストを実行する

参考にさせて頂いたページ

package.jsonをroot以外のディレクトリに置いてnpm installする方法について

karmaのconfファイルを指定して--single-runする方法について

circle.ymlの書き方について

package.jsonをrootに配置して良い場合

package.jsonリポジトリのrootに配置して良い場合について先日書きました。

はじめに

前回の記事では、リポジトリのrootにpackage.jsonとかkarma.conf.jsとか色々置いていました。

業務など実際のプロジェクトでは、jsのユニットテストを実行するためだけにpackage.jsonやkarma.confなどを色々とrootディレクトリに追加すると散らかるので、jsのユニットテストに関連するファイルは、frontendディレクトリを作成してこの中に収めようと思います。

前提として、前回書いた以下の記事の続きとして書いていきます。

frontendディレクトリを作成してjsのユニットテスト関連ファイルを全て格納する

まずforntendディレクトリを作成します。

次に./gitと.gitignoreとREADME.mdはそのまま残して、テストに関係するファイルを全てfronendディレクトリに格納します。

以下のような構造になります。

practice_circle_ci_karma/
  ├─.gitignore
  ├─.git/
  │  └─(略)
  ├─README.md
  └─frontend
    ├─karma.conf.js
    ├─package.json
    ├─js/
    │  └─application-xxx.js
    ├─node_modules/
    │  └─(略)
    └─spec/
       └─application.spec.js

circle.ymlの作成

リポジトリのrootにcircle.ymlファイルを作成します。

以下のようになります。

practice_circle_ci_karma/
  ├─.gitignore
  ├─.git/
  │  └─(略)
  ├─circle.yml
  ├─README.md
  └─frontend
    ├─karma.conf.js
    ├─package.json
    ├─js/
    │  └─application-xxx.js
    ├─node_modules/
    │  └─(略)
    └─spec/
       └─application.spec.js

circle.ymlの記述内容

dependencies:
  pre:
    - npm --prefix ./frontend install ./frontend

test:
  pre:
    - ./frontend/node_modules/karma/bin/karma start ./frontend/karma.conf.js --single-run

npm --prefix ./frontend install ./frontendで、frontendディレクトリ内のpackage.jsonの記述内容に基づいて、frontend/node_modulesにパッケージがインストールされます。

./frontend/node_modules/karma/bin/karma start ./frontend/karma.conf.js --single-runでfrontend/karma.conf.jsの記述内容に基づいて、karmaによるユニットテストが実行されます。

.gitignoreのnode_modulesを無視する記述を修正する

node_modulesディレクトリもリポジトリのrootに配置しなくなったので、前回の記述を以下のように修正しました。

*/node_modules

リポジトリをpushして、CircleCIのビルドを実行する

pushします。

circle.ymlに記述されたコマンドが実行されて、前回のようにテスト結果が緑になったら成功です。

JSでテストコードを書く その0003-01 karma+mocha+chaiの組み合わせでCircleCI上でユニットテストを実行する

参考にさせて頂いたページ

全体的なこと

karmaのこと

はじめに

Railsで生成されるapplication-xxxxxxxx.jsみたいなのをテストしたい目的があり、テスト対象のファイル名がapplication-xxx.jsですが、色々応用が利くかと思います。

リモートとローカルのリポジトリを作成する

package.jsonを作成していくつかのパッケージをインストールする

  • npm initして、今回はデフォルトのままenterしていって、yesで大丈夫。
  • npm install --save-dev phantomjs karma karma-cli karma-mocha karma-phantomjs-launcher karma-mocha-reporter mocha chai

.gitにnode_modulesディレクトリをpushしないようにする

  • .gitignoreファイルが無かったら作成する。
  • .gitignoreファイルに/node_modulesを追記する。

js/application-xxx.jsを作成する

自分が作っているwebアプリケーションのjsファイルを想定しています。

window.addNumbers = function(a, b) {
  return a + b;
};

spec/application.spec.jsを作成する

自分が作っているwebアプリケーションの関数を検証するためのソースコードです。

describe('addNumbers', function() {
  it('2 つの数値が加算できる', function() {
    chai.assert.strictEqual(window.addNumbers(1, 2), 3);
  });
});

karma.conf.jsを作成する

./node_modules/karma/bin/karma init karma.conf.jsを実行して対話形式で作成するか、手で作成する

module.exports = function(config) {
  config.set({
    frameworks: ['mocha'],
    browsers: ['PhantomJS'],
    files: [
      'js/application*.js',
      'node_modules/chai/chai.js',
      'spec/**/*.spec.js',
    ],
    reporters: ['mocha'],
  });
};

以下のことを設定しています。

  • フレームワークはmocha
  • ブラウザはPhantomJS
  • filesでテスト対象ファイルと、テストで使用するファイルを読み込み
  • reportersでコンソールのテスト結果出力フォーマットを指定

package.jsonのscriptsのtestを編集する

"scripts": {
  "test": "./node_modules/karma/bin/karma start --single-run"
},

コマンドでテストを実行してみる

  • ./node_modules/karma/bin/karma start --single-runユニットテストが実行できます。
  • package.jsonの設定によってnpm run testでも同じように実行できるはずですが、windowsだとエラーが出ました。CircleCIはこのコマンドを自動で実行してくれます。

pushしてCircleCIによるビルドを実行する

リポジトリにpushすることでCircleCIによるビルドが始まります。

CircleCIはnpm installを自動でやってくれるので、package.jsonに書いてあるdevDependenciesが予めインストールしたうえで、npm run testコマンドが実行されます。

ユニットテストが全て成功して、CircleCIのステータスが「SUCCESS」になったら自動テストの設定は成功ですね。

pushする前には./node_modules/karma/bin/karma start --single-runを一度実行して、ローカルでユニットテストが成功してからpushするのが良いですね。

まとめ

今回の最終的なディレクトリ構造

practice_circle_ci_karma/
  ├─.gitignore
  ├─karma.conf.js
  ├─package.json
  ├─README.md
  ├─.git/
  │  └─(略)
  ├─js/
  │  └─application-xxx.js
  ├─node_modules/
  │  └─(略)
  └─spec/
     └─application.spec.js

karma.conf.jsの記述内容

module.exports = function(config) {
  config.set({
    frameworks: ['mocha'],
    browsers: ['PhantomJS'],
    files: [
      'js/application*.js',
      'node_modules/chai/chai.js',
      'spec/**/*.spec.js',
    ],
    reporters: ['mocha'],
  });
};

package.jsonの記述内容

{
  "name": "practice_circle_ci_karma",
  "version": "1.0.0",
  "description": "karmaを導入して、CircleCIで実行するサンプルを作成してみます。",
  "main": "index.js",
  "scripts": {
    "test": "./node_modules/karma/bin/karma start --single-run"
  },
  "repository": {
    "type": "git",
    "url": "xxxxxx/practice_circle_ci_karma.git"
  },
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "xxxxxx/practice_circle_ci_karma/issues"
  },
  "homepage": "xxxxxx/practice_circle_ci_karma#readme",
  "devDependencies": {
    "chai": "^4.0.1",
    "karma": "^1.7.0",
    "karma-cli": "^1.0.1",
    "karma-mocha": "^1.3.0",
    "karma-mocha-reporter": "^2.2.3",
    "karma-phantomjs-launcher": "^1.0.4",
    "mocha": "^3.4.2",
    "phantomjs": "^2.1.7"
  }
}

JSでテストコードを書く その0002-01 mochaとchaiでテストを書いてブラウザでテストを実行する

参考にさせて頂いたページ

日本語の参考ページ

mocha公式

chai公式

はじめに

日本語の情報を読んで書いてみましたが、最新の情報を公式でチェックすると良いでしょう。

jsのテストを手軽に導入する方向で、最も簡易的な方法に着手してみました。

js_testing_0001.htmlを作成して、ブラウザで開くとテストが実行できます。

mocha.js mocha.css chai.jsをダウンロードする

  • とりあえずjs_testingフォルダを作りました。
  • js_testingフォルダの中でnpm initします。今回はデフォルトのままenterしていって、yesで良いです。
  • mocha.js mocha.css chai.jsの3つが欲しいのでnpm install --save-dev mocha chaiでダウンロードします。
  • これらはのちほどhtmlファイルの中で読み込みます。

js_testing/js/application.js を作成する

自分が作っているwebアプリケーションのjsを想定しています。
記述内容は例として以下の通りです。

window.addNumbers = function(a, b) {
  return a + b;
};

js_testing/spec/add_numbers.spec.js を作成する

上記したaddNumbers()関数が意図どおり動いているか検証するためのコードを書きます。
例として以下の通りです。
引数1と2を与えると3がreturnされることを検証しています。

describe('addNumbers', function() {
  it('2 つの数値が加算できる', function() {
    chai.assert.strictEqual(window.addNumbers(1, 2), 3);
  });
});

js_testing/js_testing_0001.html を作成する

今回は、ブラウザでこのhtmlファイルを開くとテストの実行結果が表示されます。
例として以下の通りです。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--mochaによるテストの実行結果用cssを読み込み-->
<link rel="stylesheet" href="node_modules/mocha/mocha.css">
<link rel="shortcut icon" href="">
</head>
<body>

<!--mochaによるテストの実行結果が出力されるdiv-->
<div id="mocha">
</div>

<!--mochaとchaiを読み込み-->
<script src="node_modules/chai/chai.js"></script>
<script src="node_modules/mocha/mocha.js"></script>

<script>
//BDDスタイルを使用するので設定
mocha.setup('bdd');
</script>

<!--自分が作っているwebアプリケーションのjsを読み込み-->
<script src="js/application.js"></script>

<!--テストコードを読み込み-->
<script src="spec/add_numbers.spec.js"></script>

<script>
// テストを実行
mocha.run();
</script>

</body>
</html>

テスト結果を見る

上記で作成したjs_testing/js_testing_0001.htmlをブラウザで開くとテストが実行されて、検証結果が表示されます。

検証は成功しました。

関数を壊して再度テストを実行してみる

リファクタリングしてみたら関数が壊れてしまった。という状況を想定します。
returnされる値がリファクタリングする前と変わってしまったことを検知します。

js_testing/js/application.js を以下のように編集します。

window.addNumbers = function(a, b) {
  return (a + b) + '';
};

もう一度テストを実行すると検証が失敗しました。
3ではなく'3'がreturnされている旨が表示されます。

関数を直します。
これでリファクタリングに安心感が出てきそうです。

vuex2.xその0005 namespaced:trueにしたmodule用のオブジェクト構造をひとつ定義して使いまわす

参考にさせて頂いたページ

はじめに

namespaced:trueにプロパティ設定したオブジェクトをstore.registerModule()で複数回登録します。

ひとつのmodule用オブジェクト、ひとつのcomponent用オブジェクトを使いまわしできるようにしてみます。

今回のバージョン

  • Vue.js v2.1.10
  • vuex v2.3.0

サンプルソースコード

以下の通りです。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/style.css">
<link rel="shortcut icon" href="">
</head>
<body>

<div id="app">
  <div>
    <counter :namespace="'firstCounter'" />
  </div>
  <div>
    <counter :namespace="'secondCounter'" />
  </div>
</div>

<script src="js/lodash.js"></script>
<script src="js/vue.js"></script>
<script src="js/vuex.js"></script>
<script>
const components = {};
const store = new Vuex.Store({
  strict: true,
});

/**
 * counter
 */
(function(){
  const counter = {
    strict: true,
    namespaced: true,
    state(){
      return {
        count: 0
      }
    },
    mutations: {
      increment: state => state.count++ ,
      decrement: state => state.count-- ,
    },
    getters: {
      counterState: state => state ,
    }
  };

  store.registerModule('firstCounter', counter);
  store.registerModule('secondCounter', counter);

  components.counter = {
    props: ['namespace'],
    template: `
      <div>
        <div>{{counterState}}</div>
        <button @click="increment">+</button>
        <button @click="decrement">-</button>
      </div>
    `,
    methods: {
      increment() {
        this.$store.commit(this.namespace + '/increment');
      },
      decrement() {
        this.$store.commit(this.namespace + '/decrement');
      }
    },
    computed: {
      counterState() {
        return this.$store.getters[this.namespace + '/counterState'];
      }
    },
  };

})();

/**
 * VueModel
 */
const app = new Vue({
  el: '#app',
  store,
  components,
});
</script>

</body>
</html>
  • もっと上手い方法は無いものかと思いつつ、コミットするときのnamespaceはpropsで渡しています。
  • computedについてはmapState()やmapGetters()などを使って上手く書く方法がわからず、this.$store.gettersを使っています。