2017年5月3日水曜日

開発環境

メタプログラミングRuby 第2版(Paolo Perrotta (著)、角 征典 (翻訳)、オライリージャパン)の1部(メタプログラミング Ruby)、6章(金曜日: コードを記述するコード)、6.6(クイズ: アトリビュートのチェック (手順 4))を JavaScript で取り組んでみる。

HTML5

<pre id="output0"></pre>
<button id="run0">run</button>
<button id="clear0">clear</button>

<script src="sample2.js"></script>

JavaScript

let btn0 = document.querySelector('#run0'),
    btn1 = document.querySelector('#clear0'),
    pre0 = document.querySelector('#output0'),
    p = (x) => pre0.textContent += x + '\n';

let Class = () => {
    let that = {},
        defineMethod = (name, fn) => {
            that[name] = fn;
        },
        attrChecked = (attribute, validation) => {
            defineMethod(
                'set' + attribute[0].toUpperCase() + attribute.substring(1), 
                (value) => {
                    if (validation(value)) {
                        that[attribute] = value;
                    } else {
                        throw {
                            name: 'Invalid attribute',
                            message: `attribute: ${attribute}, value: ${value}`
                        };
                    }
                }
            );
            defineMethod(
                'get' + attribute[0].toUpperCase() + attribute.substring(1),
                () => that[attribute]
            );
        };

    that.attrChecked = attrChecked;

    return that;
};
let Person = () => {
    let that = Class();

    that.attrChecked('age', (v) => v >= 18);

    return that;
};

let UnitTest = () => {
    let that = {},
        run = () => {            
            Object.keys(that).forEach((key) => {
                that.setUp();
                if (/^test/.test(key)) {
                    p(key);
                    that[key]();
                }
                if (that.tearDown) {
                    that.tearDown();
                }
            });        
        },
        assertEqual = (x, y) => {
            if (x === y) {
                p('ok');
            } else {
                p(`failure - ${x} !== ${y}`);
            }
        },
        assertTrue = (x) => {
            if (x) {
                p('ok');
            } else {
                p(`failure`);
            }
        },
        assertFalse = (x) => {
            if (x) {
                p('failure');
            } else {
                p(`ok`);
            }
        },
        assertThrow = (fn, name) => {
            try {
                fn();
                p('failure');
            } catch (e) {
                if (e.name === name) {
                    p('ok');
                } else {
                    p('failure');
                }
            }
        };

    that.run = run;
    that.assertEqual = assertEqual;
    that.assertTrue = assertTrue;
    that.assertFalse = assertFalse;
    that.assertThrow = assertThrow;

    return that;
};

let TestCheckedAttribute = () => {
    let that = UnitTest(),
        bob;

    that.setUp = () => {
        bob = Person();
    };
    
    that.testAcceptsValidValue = () => {
        bob.setAge(20);
        that.assertEqual(bob.getAge(), 20);
    };
    that.testRefusesInvalidValues = () => {
        that.assertThrow(() => bob.setAge(17), 'Invalid attribute')
    };
    
    return that;
};

let output = () => {
    p('6.6 クイズ: アトリビュートのチェック (手順 4)');
    TestCheckedAttribute().run();
};

btn0.onclick = output;
btn1.onclick = () => pre0.textContent = '';

output();




  








						

0 コメント:

コメントを投稿