スキルツリーの旅:モジュールからテストに分離

6114 ワード

前に言ったように
半月近く奮闘した後、forkのコードを読み取り、再構築、バージョンアップ、調整し、新機能を追加し、テストを追加し、CIを追加し、共有を追加した後、ついにalmost finishになった.
今日はどうやって作ったのかお話しします.

Githubプロジェクト構成


前に作ったLettuceを例にとると、次のようなものが入っています.
  • コード品質(Code Climate)
  • CI状態(Travis CI)
  • 試験カバー率(96%)
  • 自動化テスト(npm test)
  • 文書
  • Web Developerの路線図によると、次のようなものが必要です.
  • バージョン管理
  • 自動配置
  • などなど.

    Skillockモジュール化


    SkillTreeのソースコードでは、大きく3つの部分に分かれています.
  • namespace関数:故名思意
  • CalculatorつまりTalentTreeは、url、アイコン、依存などの解析、生成を主に担当しています.
  • Skillは主にtips部分です.

  • これらはjsにあり、ライブラリにとっては良いことですが、プロジェクトにとってはそうではありません.
    依存ライブラリあり
  • jQuery
  • Knockout

  • 幸いなことにKnockoutはRequireを使うことができます.jsは管理を行い、Require.jsを用いて管理を行う.
     <script type="text/javascript" data-main="app/scripts/main.js" src="app/lib/require.js"></script>
    
    main.jsは次のように構成されています.
    require.config({
      baseUrl: 'app',
      paths:{
        jquery: 'lib/jquery',
        json: 'lib/json',
        text: 'lib/text'
      }
    });
    
    require(['scripts/ko-bindings']);
    
    require(['lib/knockout', 'scripts/TalentTree', 'json!data/web.json'], function(ko, TalentTree, TalentData) {
      'use strict';
      var vm = new TalentTree(TalentData);
      ko.applyBindings(vm);
    });
    

    text、jsonプラグインは主にwebの処理に用いる.json、すなわちjsonでスキルを処理し、異なるクラスが異なるjsファイルに到達する.
    .
    |____Book.js
    |____Doc.js
    |____ko-bindings.js
    |____Link.js
    |____main.js
    |____Skill.js
    |____TalentTree.js
    |____Utils.js
    

    後のおすすめ読書などを加えた.BookもLinkもDocから受け継がれている.
    define(['scripts/Doc'], function(Doc) {
      'use strict';
      function Book(_e) {
        Doc.apply(this, arguments);
      }
      Book.prototype = new Doc();
    
      return Book;
    });
    

    ここでは、後で再構築する内容です.DocクラスはSkillockのクラスの縮図です
    define([], function() {
      'use strict';
      var Doc = function (_e) {
        var e = _e || {};
        var self = this;
    
        self.label = e.label || (e.url || 'Learn more');
        self.url = e.url || 'javascript:void(0)';
      };
    
      return Doc;
    });
    

    あるいはこれはAMDのClassのあるべき姿です.著者らは,thisの暗黙的バインドを考慮してself=thisを用いてこの問題を回避した.最後にReturnはこのオブジェクトを呼び出し、newを1つ必要とします.ほとんどのコードで返されるのはオブジェクトで、Utilsクラスで返されるのは関数です.
    return {
        getSkillsByHash: getSkillsByHash,
        getSkillById: getSkillById,             
        prettyJoin: prettyJoin
    };
    

    もちろん関数もオブジェクトです.

    Skillockテスト


    テストの自動化


    いつもTravis CIを使うことに慣れていたので、引き続きTravis Ciを使って、.travis.ymlは以下のように配置されています.
    language: node_js
    node_js:
      - "0.10"
    
    notifications:
      email: false
    
    branches:
      only:
        - gh-pages
    

    gh-pagesを使用する理由は、pushコードを使用すると、自動的にテスト、導入など、メリットが山積みになるからです.
    次にpackage.jsonにスクリプトを追加する必要があります
    "scripts": {
        "test": "mocha"
      }
    

    これにより、pushコードを押すと、すべてのテストが自動的に実行されます.mochaの主な構成はmocha.optsですので、mocha.optsを構成する必要があります.
    --reporter spec
    --ui bdd
    --growl
    --colors
    test/spec     
    

    最後のtest/specは、指定されたテストのディレクトリです.

    Jshint


    JSLintは、ECMAで定義された言語よりも厳格なコード規則のセットを定義します.これらの符号化の約束は長年の豊富な符号化経験を汲み取り、古いプログラミング原則を趣旨としている:できることはやるべきことを意味しない.JSLintは、あると考えているコードの実践にマークを付けます.また、明らかなエラーを指摘し、JavaScriptのコード習慣を身につけることができます.
    私たちのjsが不合理に書かれている場合、テストに合格できません.
    line 5   col 25   A constructor name should start with an uppercase letter.
    line 21  col 62   Strings must use singlequote.
    

    これは、より規範的なjsを書くことを駆動する方法です.

    Mocha


    Mochaは優れたJSテストフレームワークであり、TDD/BDDをサポートし、shouldと結合している.js/expect/chai/better-assertは、さまざまなスタイルのテスト例を簡単に構築できます.
    最後の効果は次のとおりです.
    Book,Link
      Book Test
        ✓ should return book label & url
      Link Test
        ✓ should return link label & url
    

    テストケース


    Bookのテストを簡単に見てみましょう.
    /* global describe, it */
    
    var requirejs = require("requirejs");
    var assert = require("assert");
    var should = require("should");
    requirejs.config({
      baseUrl: 'app/',
      nodeRequire: require
    });
    
    describe('Book,Link', function () {
      var Book, Link;
      before(function (done) {
        requirejs(['scripts/Book'、], function (Book_Class) {
          Book = Book_Class;
          done();
        });
      });
    
      describe('Book Test', function () {
        it('should return book label & url', function () {
          var book_name = 'Head First HTML CSS';
          var url = 'http://www.phodal.com';
          var books = {
            label: book_name,
            url: url
          };
    
          var _book = new Book(books);
          _book.label.should.equal(book_name);
          _book.url.should.equal(url);
        });
      });
    });
    

    ブラウザ側をrequire.jsで管理し、バックグラウンドでテストを書くときにも依存を管理する必要があります.これは、このテストがこのように行われている理由です.多くの場合、次のテストはこのようなものに似ています.(Jasmineを使うのはもっといいアイデアのようですが、Jasmineに慣れました)
      describe('Book Test', function () {
        it('should return book label & url', function () {
          var book_name = 'Head First HTML CSS';
          var url = 'http://www.phodal.com';
          var books = {
            label: book_name,
            url: url
          };
    
          var _book = new Book(books);
          _book.label.should.equal(book_name);
          _book.url.should.equal(url);
        });
      });
    

    最後の断言は、テストの核心でもあり、テストが役に立つことを保証します.

    終了語(小広告)


    最初に思ったのは自分でスキルツリーを書いてgithubで見るまでhttps://github.com/352Media/skilltreeと、skilltreeに基づいて一つ作ろうと思って、翻訳してみて、機能をつけてみました.最後にパクリを叱られるのを避けず、最後に自分で書いてみましょう.https://github.com/phodal/sherlock.シャーロックというのは、shelflockと呼ぶつもりだったからだ.コナンダルは本の中で書いている.
    人は空っぽの屋根裏のように、いくつかの家具を選択的に入れなければならない.
    D 3に基づく.jsは、Urlを動的に生成できますが、スキルツリーは次のようになります.https://github.com/phodal/awesome-developer
    自分が読んだ本、歩いた道がみんなに助けてくれることを願っています.
    I’m Phodal.