<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

foam.CLASS({
  package: 'graphics',
  name: 'Square',
  properties: [ 'side' ]
});

foam.CLASS({
  package: 'graphics',
  name: 'Circle',
  properties: [ 'radius' ]
});

foam.CLASS({
  name: 'Test',
  methods: [
    {
      name: 'sizeOf',
      code: foam.mmethod({
        Null: function() { return 0; },
//        Int: function() { return 1; },
        String: function(o) { return o.length; },
        "graphics.Square": function(o) { return o.side * o.side; },
        "graphics.Circle": function(o) { return Math.PI * o.radius * o.radius; }
      })
    }
  ]
});

var t = Test.create();
console.log(
  t.sizeOf(null),
//  t.sizeOf(42),
  t.sizeOf('Hello'),
  t.sizeOf(graphics.Square.create({side: 4})),
  t.sizeOf(graphics.Circle.create({radius: 1}))
);

/*
foam.CLASS({
  name: 'Test',
  listeners: [
    {
      name: 'l1',
      code: function() {
        console.log('l1');
      }
    },
    {
      name: 'l2',
      isFramed: true,
      code: function() {
        console.log('l2');
      }
    },
    {
      name: 'l3',
      isMerged: true,
      code: function() {
        console.log('l3');
      }
    },
    {
      name: 'l4',
      isMerged: true,
      mergeDelay: 0,
      code: function() {
        console.log('l4');
      }
    },
    {
      name: 'l5',
      isMerged: true,
      mergeDelay: 1000,
      code: function() {
        console.log('l5');
      }
    },
  ]
});
var t = Test.create();

t.l1();t.l1();t.l1();
t.l2();t.l2();t.l2();
t.l3();t.l3();t.l3();
t.l4();t.l4();t.l4();

for ( var i = 0 ; i < 20 ; i++ )
  setTimeout(function() { t.l5(); }, 100*i);

*/

foam.CLASS({
  name: 'Test2',
  properties: [ 'id', 'fname', 'lname' ]
});

var dao = foam.dao.EasyDAO.create({
  of: 'Test2',
//  daoType: 'MDAO',
  seqNo: true,
  cache: true,
  testData: [
    { fname: 'Madonna' },
    { fname: 'Z', lname: 'Z' },
    { fname: 'A', lname: 'Z' },
    { fname: 'B', lname: 'Z' },
    { fname: 'C', lname: 'Z' },
    { fname: 'A', lname: 'A' },
    { fname: 'B', lname: 'A' },
    { fname: 'C', lname: 'A' },
    { fname: 'A', lname: 'B' },
    { fname: 'B', lname: 'B' },
    { fname: 'C', lname: 'B' },
    { fname: 'A', lname: 'C' },
    { fname: 'B', lname: 'C' },
    { fname: 'C', lname: 'C' }
  ]
});

var e = foam.mlang.Expressions.create();

dao.where(e.EQ(Test2.LNAME, null)).select().then(function (a) {
  console.log('EQ(null)');
  a.a.forEach(function (t) { console.log(t.fname); });
});

dao.where(e.NOT(e.HAS(Test2.LNAME))).select().then(function (a) {
  console.log('NOT(HAS())');
  a.a.forEach(function (t) { console.log(t.fname); });
});

dao.orderBy(Test2.LNAME).select().then(function (a) {
  console.log('by LNAME');
  a.a.forEach(function (t) { console.log(t.fname + ' ' + t.lname); });
});

dao.orderBy(Test2.FNAME).select().then(function (a) {
  console.log('by FNAME');
  a.a.forEach(function (t) { console.log(t.fname + ' ' + t.lname); });
});

dao.orderBy(Test2.LNAME, Test2.FNAME).select().then(function (a) {
  console.log('by LNAME, FNAME');
  a.a.forEach(function (t) { console.log(t.fname + ' ' + t.lname); });
});

// dao.removeAll();

/*
foam.CLASS({
  name: 'Parent',
  properties: [ 'a', 'b' ]
});

foam.CLASS({
  name: 'Child',
  extends: 'Parent',
  properties: [ 'c', 'd' ]
});

var c;
c = Child.create({});
console.log(c.stringify(), c.clone().stringify());

c = Child.create({a:'a', b:'b'});
console.log(c.stringify(), c.clone().stringify());

c = Child.create({c:'c', d:'d'});
console.log(c.stringify(), c.clone().stringify());

c = Child.create({a:'a', b:'b', c:'c', d:'d'});
console.log(c.stringify(), c.clone().stringify());
*/
<commit_msg>Updated mmethod test to define method for model that hasn't been loaded yet.<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

foam.CLASS({
  package: 'graphics',
  name: 'Square',
  properties: [ 'side' ]
});

foam.CLASS({
  name: 'Test',
  methods: [
    {
      name: 'sizeOf',
      code: foam.mmethod({
        Null: function() { return 0; },
//        Int: function() { return 1; },
        String: function(o) { return o.length; },
        "graphics.Square": function(o) { return o.side * o.side; },
        "graphics.Circle": function(o) { return Math.PI * o.radius * o.radius; }
      })
    }
  ]
});

foam.CLASS({
  package: 'graphics',
  name: 'Circle',
  properties: [ 'radius' ]
});

var t = Test.create();
console.log(
  t.sizeOf(null),
//  t.sizeOf(42),
  t.sizeOf('Hello'),
  t.sizeOf(graphics.Square.create({side: 4})),
  t.sizeOf(graphics.Circle.create({radius: 1}))
);

/*
foam.CLASS({
  name: 'Test',
  listeners: [
    {
      name: 'l1',
      code: function() {
        console.log('l1');
      }
    },
    {
      name: 'l2',
      isFramed: true,
      code: function() {
        console.log('l2');
      }
    },
    {
      name: 'l3',
      isMerged: true,
      code: function() {
        console.log('l3');
      }
    },
    {
      name: 'l4',
      isMerged: true,
      mergeDelay: 0,
      code: function() {
        console.log('l4');
      }
    },
    {
      name: 'l5',
      isMerged: true,
      mergeDelay: 1000,
      code: function() {
        console.log('l5');
      }
    },
  ]
});
var t = Test.create();

t.l1();t.l1();t.l1();
t.l2();t.l2();t.l2();
t.l3();t.l3();t.l3();
t.l4();t.l4();t.l4();

for ( var i = 0 ; i < 20 ; i++ )
  setTimeout(function() { t.l5(); }, 100*i);

*/

foam.CLASS({
  name: 'Test2',
  properties: [ 'id', 'fname', 'lname' ]
});

var dao = foam.dao.EasyDAO.create({
  of: 'Test2',
//  daoType: 'MDAO',
  seqNo: true,
  cache: true,
  testData: [
    { fname: 'Madonna' },
    { fname: 'Z', lname: 'Z' },
    { fname: 'A', lname: 'Z' },
    { fname: 'B', lname: 'Z' },
    { fname: 'C', lname: 'Z' },
    { fname: 'A', lname: 'A' },
    { fname: 'B', lname: 'A' },
    { fname: 'C', lname: 'A' },
    { fname: 'A', lname: 'B' },
    { fname: 'B', lname: 'B' },
    { fname: 'C', lname: 'B' },
    { fname: 'A', lname: 'C' },
    { fname: 'B', lname: 'C' },
    { fname: 'C', lname: 'C' }
  ]
});

var e = foam.mlang.Expressions.create();

dao.where(e.EQ(Test2.LNAME, null)).select().then(function (a) {
  console.log('EQ(null)');
  a.a.forEach(function (t) { console.log(t.fname); });
});

dao.where(e.NOT(e.HAS(Test2.LNAME))).select().then(function (a) {
  console.log('NOT(HAS())');
  a.a.forEach(function (t) { console.log(t.fname); });
});

dao.orderBy(Test2.LNAME).select().then(function (a) {
  console.log('by LNAME');
  a.a.forEach(function (t) { console.log(t.fname + ' ' + t.lname); });
});

dao.orderBy(Test2.FNAME).select().then(function (a) {
  console.log('by FNAME');
  a.a.forEach(function (t) { console.log(t.fname + ' ' + t.lname); });
});

dao.orderBy(Test2.LNAME, Test2.FNAME).select().then(function (a) {
  console.log('by LNAME, FNAME');
  a.a.forEach(function (t) { console.log(t.fname + ' ' + t.lname); });
});

// dao.removeAll();

/*
foam.CLASS({
  name: 'Parent',
  properties: [ 'a', 'b' ]
});

foam.CLASS({
  name: 'Child',
  extends: 'Parent',
  properties: [ 'c', 'd' ]
});

var c;
c = Child.create({});
console.log(c.stringify(), c.clone().stringify());

c = Child.create({a:'a', b:'b'});
console.log(c.stringify(), c.clone().stringify());

c = Child.create({c:'c', d:'d'});
console.log(c.stringify(), c.clone().stringify());

c = Child.create({a:'a', b:'b', c:'c', d:'d'});
console.log(c.stringify(), c.clone().stringify());
*/
<|endoftext|>


<commit_before>var chai = require('chai');
var expect = chai.expect;
var morphdom = require('../../lib/index');
var resultTemplate = require('./test-result.marko');

function parseHtml(html) {
    var tmp = document.createElement('body');
    tmp.innerHTML = html;
    return tmp.firstChild;
}

function serializeNode(node) {
    var html = '';

    function serializeElHelper(el, indent) {
        html += indent + '<' + el.tagName;

        var attributes = el.attributes;
        var attributesArray = [];

        for (var i=0; i<attributes.length; i++) {
            var attr = attributes[i];
            if (attr.specified !== false) {
                attributesArray.push(' ' + attr.name + '="' + attr.value + '"');
            }
        }

        attributesArray.sort();

        html += attributesArray.join('');

        html += '>\n';

        var childNodes = el.childNodes;

        if (childNodes && childNodes.length) {
            for (i=0; i<childNodes.length; i++) {
                serializeHelper(childNodes[i], indent + '  ');
            }
        }
    }

    function serializeTextHelper(node, indent) {
        html += indent + JSON.stringify(node.nodeValue) + '\n';
    }

    function serializeHelper(node, indent) {
        if (node.nodeType === 1) {
            serializeElHelper(node, indent);
        } else if (node.nodeType === 3) {
            serializeTextHelper(node, indent);
        } else {
            throw new Error('Unexpected node type');
        }
    }

    serializeHelper(node, '');

    return html;
}

function buildElLookup(node) {
    var map = {};

    function buildMapHelper(node) {
        if (node.nodeType !== 1) {
            return;
        }

        var id = node.getAttribute('id');
        if (id) {
            map[id] = node;
        }

        var curNode = node.firstChild;
        while(curNode) {
            buildMapHelper(curNode);
            curNode = curNode.nextSibling;
        }
    }

    buildMapHelper(node);
    return map;
}

function outerHTML(node) {
    var placeholderEl = document.createElement('span');
    node.parentNode.replaceChild(placeholderEl, node);

    var container = document.createElement('body');
    container.appendChild(node);
    var html = container.innerHTML;

    placeholderEl.parentNode.replaceChild(node, placeholderEl);

    return html;
}

function collectNodes(rootNode) {
    var allNodes = [];

    function buildArrayHelper(node) {
        allNodes.push(node);
        var curNode = node.firstChild;
        while(curNode) {
            buildArrayHelper(curNode);
            curNode = curNode.nextSibling;
        }
    }

    buildArrayHelper(rootNode);
    return allNodes;
}

function isNodeInTree(node, rootNode) {
    if (node == null) {
        throw new Error('Invalid arguments');
    }
    var currentNode = node;

    while (true) {
        if (currentNode == null) {
            return false;
        } else if (currentNode == rootNode) {
            return true;
        }

        currentNode = currentNode.parentNode;
    }

    return false;
}

function runTest(name, autoTest) {
    var fromHtml = autoTest.from;
    var toHtml = autoTest.to;
    var moduleStr = autoTest.module;

    var fromNode = parseHtml(fromHtml);
    var toNode = parseHtml(toHtml);

    var allFromNodes = collectNodes(fromNode);

    var expectedSerialized = serializeNode(toNode);

    var elLookupBefore = buildElLookup(fromNode);

    function onBeforeNodeDiscarded(node) {
        if (node.$onBeforeNodeDiscarded) {
            throw new Error('Duplicate oonBeforeNodeDiscarded for: ' + serializeNode(node));
        }

        node.$onBeforeNodeDiscarded = true;
    }
    function onNodeDiscarded(node) {
        if (node.$onNodeDiscarded) {
            throw new Error('Duplicate onNodeDiscarded for: ' + serializeNode(node));
        }

        node.$onNodeDiscarded = true;
    }

    function onBeforeMorphEl(node) {
        if (node.$onBeforeMorphEl) {
            throw new Error('Duplicate onBeforeMorphEl for: ' + serializeNode(node));
        }

        node.$onBeforeMorphEl = true;
    }

    function onBeforeMorphElChildren(node) {
        if (node.$onBeforeMorphElChildren) {
            throw new Error('Duplicate onBeforeMorphElChildren for: ' + serializeNode(node));
        }

        node.$onBeforeMorphElChildren = true;
    }

    var morphedNode = morphdom(fromNode, toNode, {
        onBeforeNodeDiscarded: onBeforeNodeDiscarded,
        onNodeDiscarded: onNodeDiscarded,
        onBeforeMorphEl: onBeforeMorphEl,
        onBeforeMorphElChildren: onBeforeMorphElChildren
    });

    var elLookupAfter = buildElLookup(morphedNode);

    var resultHtml = resultTemplate.renderSync({
        name: name,
        fromHtml: fromHtml,
        expectedHtml: toHtml,
        actualHtml: outerHTML(morphedNode)
    });

    var containerEl = document.createElement('div');
    containerEl.innerHTML = resultHtml;
    document.getElementById('test-results').appendChild(containerEl);
    // console.log('elLookupBefore: ', elLookupBefore);

    var morphedNodeSerialized = serializeNode(morphedNode);

    expect(morphedNodeSerialized).to.equal(expectedSerialized);

    // console.log('morphedNodeSerialized: ' + morphedNodeSerialized);
    // console.log('expectedSerialized: ' + expectedSerialized);
    // console.log('morphedNode.outerHTML: ' + outerHTML(morphedNode));

    // console.log(morphedNodeSerialized);

    // Make sure any nodes with an ID that were in both the before and
    // after nodes are identical
    Object.keys(elLookupBefore).forEach(function(elId) {
        var afterEl =  elLookupAfter[elId];
        if (afterEl) {
            expect(afterEl).to.equal(elLookupBefore[elId]);
        }
    });

    allFromNodes.forEach(function(node) {
        if (node.$onNodeDiscarded && isNodeInTree(node, morphedNode)) {
            throw new Error('"from" node was reported as being discarded, but it still in the final DOM tree. Node: ' + serializeNode(node));
        }

        if (node.nodeType === 1 && node.$onNodeDiscarded !== true) {
            if (!node.$onBeforeMorphEl) {
                throw new Error('"from" element was not reported as being discarded, but it was not morphed. Node: ' + serializeNode(node));
            }
        }

        // if (isNodeInTree(node, morphedNode)) {
        //     if (node.$testOnFromNodeRemovedFlag) {
        //         throw new Error('onFromNodeRemoved(node) called for node that is in the final DOM tree: ' + node);
        //     }
        // } else {
        //     if (!node.$testOnFromNodeRemovedFlag) {
        //         throw new Error('"from" node was removed but onFromNodeRemoved(node) was not called: ' + node);
        //     }
        // }
    });

    if (moduleStr) {
        var autoTestExports = {};
        var moduleFactory = eval('(function(exports) { ' + moduleStr + ' })');
        moduleFactory(autoTestExports);

        var verify = autoTestExports.verify;
        if (verify) {
            var verifyContext = {
                rootNode:  morphedNode
            };

            verify(verifyContext, expect);
        }
    }
}

function addTests() {
    describe('morphdom' , function() {
        this.timeout(0);

        beforeEach(function() {
        });

        describe('auto tests', function() {
            var autoTests = require('../mocha-phantomjs/generated/auto-tests');

            Object.keys(autoTests).forEach(function(name) {
                var test = autoTests[name];
                var itFunc = test.only ? it.only : it;

                itFunc(name, function() {
                    runTest(name, test);
                });
            });
        });

        it('should transform a simple el', function() {
            var el1 = document.createElement('div');
            el1.className = 'foo';

            var el2 = document.createElement('div');
            el2.className = 'bar';

            morphdom(el1, el2);

            expect(el1.className).to.equal('bar');
        });

        it('should transform an text input el', function() {
            var el1 = document.createElement('input');
            el1.type = 'text';
            el1.value = 'Hello World';

            var el2 = document.createElement('input');
            el2.setAttribute('type', 'text');
            el2.setAttribute('value', 'Hello World 2');

            morphdom(el1, el2);

            expect(el1.value).to.equal('Hello World 2');
        });

        it('should transform a checkbox input el', function() {
            var el1 = document.createElement('input');
            el1.type = 'checkbox';
            el1.setAttribute('checked', '');
            el1.checked = false;

            var el2 = document.createElement('input');
            el2.setAttribute('type', 'text');
            el2.setAttribute('checked', '');

            morphdom(el1, el2);

            expect(el1.checked).to.equal(true);
        });

        it('should transform an incompatible node and maintain the same parent', function() {
            var parentEl = document.createElement('div');

            var el1 = document.createElement('input');
            el1.type = 'text';
            el1.value = 'Hello World';
            parentEl.appendChild(el1);

            var el2 = document.createElement('p');
            var morphedNode = morphdom(el1, el2);

            expect(morphedNode.parentNode).to.equal(parentEl);
        });

        it('should handle the "disabled" attribute correctly', function() {
            var el1 = document.createElement('input');
            el1.disabled = true;

            el1.value = 'Hello World';

            var el2 = document.createElement('input');
            el2.setAttribute('value', 'Hello World 2');

            morphdom(el1, el2);

            expect(el2.disabled).to.equal(false);
        });

        it('should allow morphing to be skipped for a node', function() {
            var el1a = document.createElement('div');
            var el1b = document.createElement('b');
            el1b.setAttribute('class', 'foo');
            el1a.appendChild(el1b);

            var el2a = document.createElement('div');
            var el2b = document.createElement('b');
            el2b.setAttribute('class', 'bar');
            el2a.appendChild(el2b);

            morphdom(el1a, el2a, {
                onBeforeMorphEl: function(el) {
                    if (el.tagName === 'B') {
                        return false;
                    }
                }
            });

            expect(el1a.childNodes[0].className).to.equal('foo');
        });

        it('should allow discarding to be skipped for a node', function() {
            var el1a = document.createElement('div');
            var el1b = document.createElement('b');
            var el1c = document.createElement('span');
            var el1d = document.createElement('a');
            el1a.appendChild(el1b);
            el1a.appendChild(el1c);
            el1a.appendChild(el1d);

            var el2a = document.createElement('div');
            var el2b = document.createElement('a');
            el2a.appendChild(el2b);

            morphdom(el1a, el2a, {
                onBeforeNodeDiscarded: function(el) {
                    if (el.tagName === 'B') {
                        return false;
                    }
                }
            });

            expect(el1a.childNodes[0].tagName).to.equal('B');
            expect(el1a.childNodes[1].tagName).to.equal('A');
        });

        it('should transform a simple el to a target HTML string', function() {
            var el1 = document.createElement('div');
            el1.innerHTML  = '<button>Click Me</button>';

            morphdom(el1, '
<button>Click Me</button>');

            expect(el1.className).to.equal('bar');
            expect(el1.firstChild.tagName).to.equal('BUTTON');
        });

        it('should allow only morphing child nodes', function() {
            var el1 = document.createElement('div');
            el1.className = 'foo';
            el1.innerHTML  = '<button class="hello">A</button>';

            var morphedEl = morphdom(el1, '
<button class="world">B</button>
', {
                childrenOnly: true
            });

            expect(morphedEl).to.equal(el1);

            var button = el1.querySelector('button');

            expect(el1.className).to.equal('foo');
            expect(button.className).to.equal('world');
            expect(button.innerHTML).to.equal('B');
        });

        it('should transform an textarea el', function() {
            var el1 = document.createElement('div');
            el1.innerHTML = '<textarea>foo</textarea>';
            el1.firstChild.value = 'foo2';

            var el2 = document.createElement('div');
            el2.innerHTML = '<textarea>bar</textarea>';

            morphdom(el1, el2);

            expect(el1.firstChild.value).to.equal('bar');
        });

        it('should not change caret position if input value did not change', function() {
            var inputEl = document.createElement('input');
            inputEl.type = 'text';
            inputEl.value = 'HELLO';
            inputEl.id = 'focusInput';
            document.body.appendChild(inputEl);

            inputEl.focus();

            inputEl.setSelectionRange(0, 0);
            expect(inputEl.selectionStart).to.equal(0);

            function update() {
                var newInput = document.createElement('input');
                newInput.type = 'text';
                newInput.id = 'focusInput';
                newInput.value = inputEl.value;
                morphdom(inputEl, newInput);
            }

            inputEl.addEventListener('input', update);

            update();

            expect(inputEl.selectionStart).to.equal(0);
        });

        it('should determine correct matching elements by id', function() {
            var el1 = document.createElement('div');
            el1.innerHTML = '';

            var el2 = document.createElement('div');
            el2.innerHTML = '';

            var span2 = el1.children[1];

            var morphedEl = morphdom(el1, el2);

            expect(morphedEl.children[0]).to.equal(span2);
            expect(morphedEl.children.length).to.equal(1);
        });

        it('should determine correct matching elements by attribute "data-id"', function() {
            var el1 = document.createElement('div');
            el1.innerHTML = '';

            var el2 = document.createElement('div');
            el2.innerHTML = '';

            var span2 = el1.children[1];

            var morphedEl = morphdom(el1, el2, {
                getNodeKey: function(el) {
                    return el.dataset.id;
                }
            });

            expect(morphedEl.children[0]).to.equal(span2);
            expect(morphedEl.children.length).to.equal(1);
        });
    });
}

if (require('../mocha-phantomjs/generated/config').runTests === true) {
    addTests();
}
<commit_msg>New test for ignoring a textarea value<commit_after>var chai = require('chai');
var expect = chai.expect;
var morphdom = require('../../lib/index');
var resultTemplate = require('./test-result.marko');

function parseHtml(html) {
    var tmp = document.createElement('body');
    tmp.innerHTML = html;
    return tmp.firstChild;
}

function serializeNode(node) {
    var html = '';

    function serializeElHelper(el, indent) {
        html += indent + '<' + el.tagName;

        var attributes = el.attributes;
        var attributesArray = [];

        for (var i=0; i<attributes.length; i++) {
            var attr = attributes[i];
            if (attr.specified !== false) {
                attributesArray.push(' ' + attr.name + '="' + attr.value + '"');
            }
        }

        attributesArray.sort();

        html += attributesArray.join('');

        html += '>\n';

        var childNodes = el.childNodes;

        if (childNodes && childNodes.length) {
            for (i=0; i<childNodes.length; i++) {
                serializeHelper(childNodes[i], indent + '  ');
            }
        }
    }

    function serializeTextHelper(node, indent) {
        html += indent + JSON.stringify(node.nodeValue) + '\n';
    }

    function serializeHelper(node, indent) {
        if (node.nodeType === 1) {
            serializeElHelper(node, indent);
        } else if (node.nodeType === 3) {
            serializeTextHelper(node, indent);
        } else {
            throw new Error('Unexpected node type');
        }
    }

    serializeHelper(node, '');

    return html;
}

function buildElLookup(node) {
    var map = {};

    function buildMapHelper(node) {
        if (node.nodeType !== 1) {
            return;
        }

        var id = node.getAttribute('id');
        if (id) {
            map[id] = node;
        }

        var curNode = node.firstChild;
        while(curNode) {
            buildMapHelper(curNode);
            curNode = curNode.nextSibling;
        }
    }

    buildMapHelper(node);
    return map;
}

function outerHTML(node) {
    var placeholderEl = document.createElement('span');
    node.parentNode.replaceChild(placeholderEl, node);

    var container = document.createElement('body');
    container.appendChild(node);
    var html = container.innerHTML;

    placeholderEl.parentNode.replaceChild(node, placeholderEl);

    return html;
}

function collectNodes(rootNode) {
    var allNodes = [];

    function buildArrayHelper(node) {
        allNodes.push(node);
        var curNode = node.firstChild;
        while(curNode) {
            buildArrayHelper(curNode);
            curNode = curNode.nextSibling;
        }
    }

    buildArrayHelper(rootNode);
    return allNodes;
}

function isNodeInTree(node, rootNode) {
    if (node == null) {
        throw new Error('Invalid arguments');
    }
    var currentNode = node;

    while (true) {
        if (currentNode == null) {
            return false;
        } else if (currentNode == rootNode) {
            return true;
        }

        currentNode = currentNode.parentNode;
    }

    return false;
}

function runTest(name, autoTest) {
    var fromHtml = autoTest.from;
    var toHtml = autoTest.to;
    var moduleStr = autoTest.module;

    var fromNode = parseHtml(fromHtml);
    var toNode = parseHtml(toHtml);

    var allFromNodes = collectNodes(fromNode);

    var expectedSerialized = serializeNode(toNode);

    var elLookupBefore = buildElLookup(fromNode);

    function onBeforeNodeDiscarded(node) {
        if (node.$onBeforeNodeDiscarded) {
            throw new Error('Duplicate oonBeforeNodeDiscarded for: ' + serializeNode(node));
        }

        node.$onBeforeNodeDiscarded = true;
    }
    function onNodeDiscarded(node) {
        if (node.$onNodeDiscarded) {
            throw new Error('Duplicate onNodeDiscarded for: ' + serializeNode(node));
        }

        node.$onNodeDiscarded = true;
    }

    function onBeforeMorphEl(node) {
        if (node.$onBeforeMorphEl) {
            throw new Error('Duplicate onBeforeMorphEl for: ' + serializeNode(node));
        }

        node.$onBeforeMorphEl = true;
    }

    function onBeforeMorphElChildren(node) {
        if (node.$onBeforeMorphElChildren) {
            throw new Error('Duplicate onBeforeMorphElChildren for: ' + serializeNode(node));
        }

        node.$onBeforeMorphElChildren = true;
    }

    var morphedNode = morphdom(fromNode, toNode, {
        onBeforeNodeDiscarded: onBeforeNodeDiscarded,
        onNodeDiscarded: onNodeDiscarded,
        onBeforeMorphEl: onBeforeMorphEl,
        onBeforeMorphElChildren: onBeforeMorphElChildren
    });

    var elLookupAfter = buildElLookup(morphedNode);

    var resultHtml = resultTemplate.renderSync({
        name: name,
        fromHtml: fromHtml,
        expectedHtml: toHtml,
        actualHtml: outerHTML(morphedNode)
    });

    var containerEl = document.createElement('div');
    containerEl.innerHTML = resultHtml;
    document.getElementById('test-results').appendChild(containerEl);
    // console.log('elLookupBefore: ', elLookupBefore);

    var morphedNodeSerialized = serializeNode(morphedNode);

    expect(morphedNodeSerialized).to.equal(expectedSerialized);

    // console.log('morphedNodeSerialized: ' + morphedNodeSerialized);
    // console.log('expectedSerialized: ' + expectedSerialized);
    // console.log('morphedNode.outerHTML: ' + outerHTML(morphedNode));

    // console.log(morphedNodeSerialized);

    // Make sure any nodes with an ID that were in both the before and
    // after nodes are identical
    Object.keys(elLookupBefore).forEach(function(elId) {
        var afterEl =  elLookupAfter[elId];
        if (afterEl) {
            expect(afterEl).to.equal(elLookupBefore[elId]);
        }
    });

    allFromNodes.forEach(function(node) {
        if (node.$onNodeDiscarded && isNodeInTree(node, morphedNode)) {
            throw new Error('"from" node was reported as being discarded, but it still in the final DOM tree. Node: ' + serializeNode(node));
        }

        if (node.nodeType === 1 && node.$onNodeDiscarded !== true) {
            if (!node.$onBeforeMorphEl) {
                throw new Error('"from" element was not reported as being discarded, but it was not morphed. Node: ' + serializeNode(node));
            }
        }

        // if (isNodeInTree(node, morphedNode)) {
        //     if (node.$testOnFromNodeRemovedFlag) {
        //         throw new Error('onFromNodeRemoved(node) called for node that is in the final DOM tree: ' + node);
        //     }
        // } else {
        //     if (!node.$testOnFromNodeRemovedFlag) {
        //         throw new Error('"from" node was removed but onFromNodeRemoved(node) was not called: ' + node);
        //     }
        // }
    });

    if (moduleStr) {
        var autoTestExports = {};
        var moduleFactory = eval('(function(exports) { ' + moduleStr + ' })');
        moduleFactory(autoTestExports);

        var verify = autoTestExports.verify;
        if (verify) {
            var verifyContext = {
                rootNode:  morphedNode
            };

            verify(verifyContext, expect);
        }
    }
}

function addTests() {
    describe('morphdom' , function() {
        this.timeout(0);

        beforeEach(function() {
        });

        describe('auto tests', function() {
            var autoTests = require('../mocha-phantomjs/generated/auto-tests');

            Object.keys(autoTests).forEach(function(name) {
                var test = autoTests[name];
                var itFunc = test.only ? it.only : it;

                itFunc(name, function() {
                    runTest(name, test);
                });
            });
        });

        it('should transform a simple el', function() {
            var el1 = document.createElement('div');
            el1.className = 'foo';

            var el2 = document.createElement('div');
            el2.className = 'bar';

            morphdom(el1, el2);

            expect(el1.className).to.equal('bar');
        });

        it('should transform an text input el', function() {
            var el1 = document.createElement('input');
            el1.type = 'text';
            el1.value = 'Hello World';

            var el2 = document.createElement('input');
            el2.setAttribute('type', 'text');
            el2.setAttribute('value', 'Hello World 2');

            morphdom(el1, el2);

            expect(el1.value).to.equal('Hello World 2');
        });

        it('should transform a checkbox input el', function() {
            var el1 = document.createElement('input');
            el1.type = 'checkbox';
            el1.setAttribute('checked', '');
            el1.checked = false;

            var el2 = document.createElement('input');
            el2.setAttribute('type', 'text');
            el2.setAttribute('checked', '');

            morphdom(el1, el2);

            expect(el1.checked).to.equal(true);
        });

        it('should transform an incompatible node and maintain the same parent', function() {
            var parentEl = document.createElement('div');

            var el1 = document.createElement('input');
            el1.type = 'text';
            el1.value = 'Hello World';
            parentEl.appendChild(el1);

            var el2 = document.createElement('p');
            var morphedNode = morphdom(el1, el2);

            expect(morphedNode.parentNode).to.equal(parentEl);
        });

        it('should handle the "disabled" attribute correctly', function() {
            var el1 = document.createElement('input');
            el1.disabled = true;

            el1.value = 'Hello World';

            var el2 = document.createElement('input');
            el2.setAttribute('value', 'Hello World 2');

            morphdom(el1, el2);

            expect(el2.disabled).to.equal(false);
        });

        it('should allow morphing to be skipped for a node', function() {
            var el1a = document.createElement('div');
            var el1b = document.createElement('b');
            el1b.setAttribute('class', 'foo');
            el1a.appendChild(el1b);

            var el2a = document.createElement('div');
            var el2b = document.createElement('b');
            el2b.setAttribute('class', 'bar');
            el2a.appendChild(el2b);

            morphdom(el1a, el2a, {
                onBeforeMorphEl: function(el) {
                    if (el.tagName === 'B') {
                        return false;
                    }
                }
            });

            expect(el1a.childNodes[0].className).to.equal('foo');
        });

        it('should allow discarding to be skipped for a node', function() {
            var el1a = document.createElement('div');
            var el1b = document.createElement('b');
            var el1c = document.createElement('span');
            var el1d = document.createElement('a');
            el1a.appendChild(el1b);
            el1a.appendChild(el1c);
            el1a.appendChild(el1d);

            var el2a = document.createElement('div');
            var el2b = document.createElement('a');
            el2a.appendChild(el2b);

            morphdom(el1a, el2a, {
                onBeforeNodeDiscarded: function(el) {
                    if (el.tagName === 'B') {
                        return false;
                    }
                }
            });

            expect(el1a.childNodes[0].tagName).to.equal('B');
            expect(el1a.childNodes[1].tagName).to.equal('A');
        });

        it('should transform a simple el to a target HTML string', function() {
            var el1 = document.createElement('div');
            el1.innerHTML  = '<button>Click Me</button>';

            morphdom(el1, '
<button>Click Me</button>');

            expect(el1.className).to.equal('bar');
            expect(el1.firstChild.tagName).to.equal('BUTTON');
        });

        it('should allow only morphing child nodes', function() {
            var el1 = document.createElement('div');
            el1.className = 'foo';
            el1.innerHTML  = '<button class="hello">A</button>';

            var morphedEl = morphdom(el1, '
<button class="world">B</button>
', {
                childrenOnly: true
            });

            expect(morphedEl).to.equal(el1);

            var button = el1.querySelector('button');

            expect(el1.className).to.equal('foo');
            expect(button.className).to.equal('world');
            expect(button.innerHTML).to.equal('B');
        });

        it('should transform an textarea el', function() {
            var el1 = document.createElement('div');
            el1.innerHTML = '<textarea>foo</textarea>';
            el1.firstChild.value = 'foo2';

            var el2 = document.createElement('div');
            el2.innerHTML = '<textarea>bar</textarea>';

            morphdom(el1, el2);

            expect(el1.firstChild.value).to.equal('bar');
        });

        it('should not change caret position if input value did not change', function() {
            var inputEl = document.createElement('input');
            inputEl.type = 'text';
            inputEl.value = 'HELLO';
            inputEl.id = 'focusInput';
            document.body.appendChild(inputEl);

            inputEl.focus();

            inputEl.setSelectionRange(0, 0);
            expect(inputEl.selectionStart).to.equal(0);

            function update() {
                var newInput = document.createElement('input');
                newInput.type = 'text';
                newInput.id = 'focusInput';
                newInput.value = inputEl.value;
                morphdom(inputEl, newInput);
            }

            inputEl.addEventListener('input', update);

            update();

            expect(inputEl.selectionStart).to.equal(0);
        });

        it('should determine correct matching elements by id', function() {
            var el1 = document.createElement('div');
            el1.innerHTML = '';

            var el2 = document.createElement('div');
            el2.innerHTML = '';

            var span2 = el1.children[1];

            var morphedEl = morphdom(el1, el2);

            expect(morphedEl.children[0]).to.equal(span2);
            expect(morphedEl.children.length).to.equal(1);
        });

        it('should determine correct matching elements by attribute "data-id"', function() {
            var el1 = document.createElement('div');
            el1.innerHTML = '';

            var el2 = document.createElement('div');
            el2.innerHTML = '';

            var span2 = el1.children[1];

            var morphedEl = morphdom(el1, el2, {
                getNodeKey: function(el) {
                    return el.dataset.id;
                }
            });

            expect(morphedEl.children[0]).to.equal(span2);
            expect(morphedEl.children.length).to.equal(1);
        });

        it('should allow ignoring a textarea value', function() {
            var el1 = document.createElement('div');
            el1.innerHTML = '<textarea>foo</textarea>';
            el1.firstChild.value = 'foo2';

            var el2 = document.createElement('div');
            el2.innerHTML = '<textarea>bar</textarea>';

            morphdom(el1, el2, {
                onBeforeMorphEl: function(fromEl, toEl) {
                    if (fromEl.tagName === 'TEXTAREA' || fromEl.tagName === 'INPUT') {
                        toEl.checked = fromEl.checked;
                        toEl.value = fromEl.value;
                    } else if (fromEl.tagName === 'OPTION') {
                        toEl.selected = fromEl.selected;
                    }
                }
            });

            expect(el1.firstChild.value).to.equal('foo2');
        });
    });
}

if (require('../mocha-phantomjs/generated/config').runTests === true) {
    addTests();
}
<|endoftext|>


<commit_before>'use strict';

const webdriverio = require('webdriverio');
const should = require('should');
const path = require('path');
const fs = require('fs');

const source_root_dir = path.join(__dirname, '..');
const electron_binary_path = (function() {
  if (process.platform === 'darwin') {
    return path.join(source_root_dir, 'node_modules/electron-prebuilt/dist/Electron.app/Contents/MacOS/Electron');
  }
  else {
    const exe_extension = (process.platform === 'win32') ? '.exe' : '';
    return path.join(source_root_dir, 'node_modules/electron-prebuilt/dist/electron' + exe_extension);
  }
})();
const config_file_path = path.join(source_root_dir, 'test_config.json');
const mattermost_url = 'http://example.com/team';

var options = {
  host: 'localhost', // Use localhost as chrome driver server
  port: 9515, // "9515" is the port opened by chrome driver.
  desiredCapabilities: {
    browserName: 'chrome',
    chromeOptions: {
      binary: electron_binary_path, // Path to your Electron binary.
      args: ['app=' + path.join(source_root_dir, 'dist'), '--config-file=' + config_file_path] // Optional, perhaps 'app=' + /path/to/your/app/
    }
  }
};

describe('electron-mattermost', function() {
  this.timeout(10000);

  var chromedriver;
  var client;
  before(function(done) {
    chromedriver = require('child_process').spawn('node_modules/chromedriver/lib/chromedriver/chromedriver', ['--url-base=wd/hub', '--port=9515']);
    client = webdriverio.remote(options);

    fs.unlink(config_file_path, function(err) {
      // waiting for chromedriver
      setTimeout(done, 1000);
    });
  });

  afterEach(function() {
    return client.end();
  });

  after(function() {
    chromedriver.kill();
  });

  it('should show settings.html when there is no config file', function() {
    return client
      .init()
      .pause(1000)
      .getUrl().then(function(url) {
        var p = path.parse(url);
        p.base.should.equal('settings.html');
      })
      .end();
  });

  it('should show index.html when there is config file', function() {
    fs.writeFileSync(config_file_path, JSON.stringify({
      url: mattermost_url
    }));
    return client
      .init()
      .pause(1000)
      .getUrl().then(function(url) {
        var p = path.parse(url);
        p.base.should.equal('index.html');
      })
      .end();
  });

  it('should upgrade v0 config file', function() {
    const settings = require('../src/common/settings');
    fs.writeFileSync(config_file_path, JSON.stringify({
      url: mattermost_url
    }));
    return client
      .init()
      .pause(1000)
      .getUrl().then(function(url) {
        var p = path.parse(url);
        p.base.should.equal('index.html');
      })
      .end().then(function() {
        var str = fs.readFileSync(config_file_path, 'utf8');
        var config = JSON.parse(str);
        config.version.should.equal(settings.version);
      });
  });

  describe('index.html', function() {
    const config = {
      version: 1,
      teams: [{
        name: 'example_1',
        url: mattermost_url + '1'
      }, {
        name: 'example_2',
        url: mattermost_url + '2'
      }]
    };

    beforeEach(function() {
      fs.writeFileSync(config_file_path, JSON.stringify(config));
    });

    it('should NOT show tabs when there is one team', function() {
      fs.writeFileSync(config_file_path, JSON.stringify({
        url: mattermost_url
      }));
      return client
        .init()
        .isExisting('#tabBar').then(function(isExisting) {
          isExisting.should.be.false();
        })
        .end();
    });

    it('should set src of webview from config file', function() {
      return client
        .init()
        .getAttribute('#mattermostView0', 'src').then(function(attribute) {
          attribute.should.equal(config.teams[0].url);
        })
        .getAttribute('#mattermostView1', 'src').then(function(attribute) {
          attribute.should.equal(config.teams[1].url);
        })
        .isExisting('#mattermostView2').then(function(isExisting) {
          isExisting.should.be.false();
        })
        .end();
    });

    it('should set name of tab from config file', function() {
      return client
        .init()
        .getText('#teamTabItem0').then(function(text) {
          text.should.equal(config.teams[0].name);
        })
        .getText('#teamTabItem1').then(function(text) {
          text.should.equal(config.teams[1].name);
        })
        .isExisting('#teamTabItem2').then(function(isExisting) {
          isExisting.should.be.false();
        })
        .end();
    });

    it('should show only the selected team', function() {
      return client
        .init()
        .waitForVisible('#mattermostView0')
        .isVisible('#mattermostView1').then(function(visility) {
          visility.should.be.false();
        })
        .click('#teamTabItem1')
        .waitForVisible('#mattermostView1')
        .isVisible('#mattermostView0').then(function(visility) {
          visility.should.be.false();
        })
        .end();
    });
  });

  describe('settings.html', function() {
    const config = {
      version: 1,
      teams: [{
        name: 'example_1',
        url: mattermost_url
      }, {
        name: 'example_2',
        url: mattermost_url
      }]
    };

    before(function() {
      fs.writeFileSync(config_file_path, JSON.stringify(config));
    });

    it('should show index.thml when Cancel button is clicked', function() {
      return client
        .init()
        .url('file://' + path.join(source_root_dir, 'dist/browser/settings.html'))
        .waitForExist('#btnCancel')
        .click('#btnCancel')
        .pause(1000)
        .getUrl().then(function(url) {
          var url_split = url.split('/');
          url_split[url_split.length - 1].should.equal('index.html');
        })
        .end();
    });

    it('should show index.thml when Save button is clicked', function() {
      return client
        .init()
        .url('file://' + path.join(source_root_dir, 'dist/browser/settings.html'))
        .waitForExist('#btnSave')
        .click('#btnSave')
        .pause(1000)
        .getUrl().then(function(url) {
          var url_split = url.split('/');
          url_split[url_split.length - 1].should.equal('index.html');
        })
        .end();
    });

  });
});
<commit_msg>Add waiting when switching tabs<commit_after>'use strict';

const webdriverio = require('webdriverio');
const should = require('should');
const path = require('path');
const fs = require('fs');

const source_root_dir = path.join(__dirname, '..');
const electron_binary_path = (function() {
  if (process.platform === 'darwin') {
    return path.join(source_root_dir, 'node_modules/electron-prebuilt/dist/Electron.app/Contents/MacOS/Electron');
  }
  else {
    const exe_extension = (process.platform === 'win32') ? '.exe' : '';
    return path.join(source_root_dir, 'node_modules/electron-prebuilt/dist/electron' + exe_extension);
  }
})();
const config_file_path = path.join(source_root_dir, 'test_config.json');
const mattermost_url = 'http://example.com/team';

var options = {
  host: 'localhost', // Use localhost as chrome driver server
  port: 9515, // "9515" is the port opened by chrome driver.
  desiredCapabilities: {
    browserName: 'chrome',
    chromeOptions: {
      binary: electron_binary_path, // Path to your Electron binary.
      args: ['app=' + path.join(source_root_dir, 'dist'), '--config-file=' + config_file_path] // Optional, perhaps 'app=' + /path/to/your/app/
    }
  }
};

describe('electron-mattermost', function() {
  this.timeout(10000);

  var chromedriver;
  var client;
  before(function(done) {
    chromedriver = require('child_process').spawn('node_modules/chromedriver/lib/chromedriver/chromedriver', ['--url-base=wd/hub', '--port=9515']);
    client = webdriverio.remote(options);

    fs.unlink(config_file_path, function(err) {
      // waiting for chromedriver
      setTimeout(done, 1000);
    });
  });

  afterEach(function() {
    return client.end();
  });

  after(function() {
    chromedriver.kill();
  });

  it('should show settings.html when there is no config file', function() {
    return client
      .init()
      .pause(1000)
      .getUrl().then(function(url) {
        var p = path.parse(url);
        p.base.should.equal('settings.html');
      })
      .end();
  });

  it('should show index.html when there is config file', function() {
    fs.writeFileSync(config_file_path, JSON.stringify({
      url: mattermost_url
    }));
    return client
      .init()
      .pause(1000)
      .getUrl().then(function(url) {
        var p = path.parse(url);
        p.base.should.equal('index.html');
      })
      .end();
  });

  it('should upgrade v0 config file', function() {
    const settings = require('../src/common/settings');
    fs.writeFileSync(config_file_path, JSON.stringify({
      url: mattermost_url
    }));
    return client
      .init()
      .pause(1000)
      .getUrl().then(function(url) {
        var p = path.parse(url);
        p.base.should.equal('index.html');
      })
      .end().then(function() {
        var str = fs.readFileSync(config_file_path, 'utf8');
        var config = JSON.parse(str);
        config.version.should.equal(settings.version);
      });
  });

  describe('index.html', function() {
    const config = {
      version: 1,
      teams: [{
        name: 'example_1',
        url: mattermost_url + '1'
      }, {
        name: 'example_2',
        url: mattermost_url + '2'
      }]
    };

    beforeEach(function() {
      fs.writeFileSync(config_file_path, JSON.stringify(config));
    });

    it('should NOT show tabs when there is one team', function() {
      fs.writeFileSync(config_file_path, JSON.stringify({
        url: mattermost_url
      }));
      return client
        .init()
        .isExisting('#tabBar').then(function(isExisting) {
          isExisting.should.be.false();
        })
        .end();
    });

    it('should set src of webview from config file', function() {
      return client
        .init()
        .getAttribute('#mattermostView0', 'src').then(function(attribute) {
          attribute.should.equal(config.teams[0].url);
        })
        .getAttribute('#mattermostView1', 'src').then(function(attribute) {
          attribute.should.equal(config.teams[1].url);
        })
        .isExisting('#mattermostView2').then(function(isExisting) {
          isExisting.should.be.false();
        })
        .end();
    });

    it('should set name of tab from config file', function() {
      return client
        .init()
        .getText('#teamTabItem0').then(function(text) {
          text.should.equal(config.teams[0].name);
        })
        .getText('#teamTabItem1').then(function(text) {
          text.should.equal(config.teams[1].name);
        })
        .isExisting('#teamTabItem2').then(function(isExisting) {
          isExisting.should.be.false();
        })
        .end();
    });

    it('should show only the selected team', function() {
      return client
        .init()
        .pause(1000)
        .waitForVisible('#mattermostView0', 1000)
        .isVisible('#mattermostView1').then(function(visility) {
          visility.should.be.false();
        })
        .click('#teamTabItem1')
        .pause(1000)
        .waitForVisible('#mattermostView1', 1000)
        .isVisible('#mattermostView0').then(function(visility) {
          visility.should.be.false();
        })
        .end();
    });
  });

  describe('settings.html', function() {
    const config = {
      version: 1,
      teams: [{
        name: 'example_1',
        url: mattermost_url
      }, {
        name: 'example_2',
        url: mattermost_url
      }]
    };

    before(function() {
      fs.writeFileSync(config_file_path, JSON.stringify(config));
    });

    it('should show index.thml when Cancel button is clicked', function() {
      return client
        .init()
        .url('file://' + path.join(source_root_dir, 'dist/browser/settings.html'))
        .waitForExist('#btnCancel')
        .click('#btnCancel')
        .pause(1000)
        .getUrl().then(function(url) {
          var url_split = url.split('/');
          url_split[url_split.length - 1].should.equal('index.html');
        })
        .end();
    });

    it('should show index.thml when Save button is clicked', function() {
      return client
        .init()
        .url('file://' + path.join(source_root_dir, 'dist/browser/settings.html'))
        .waitForExist('#btnSave')
        .click('#btnSave')
        .pause(1000)
        .getUrl().then(function(url) {
          var url_split = url.split('/');
          url_split[url_split.length - 1].should.equal('index.html');
        })
        .end();
    });

  });
});
<|endoftext|>


<commit_before>// REFERENCES
// https://github.com/pillarjs/cookies/blob/master/lib/cookies.js
// https://github.com/koajs/session/blob/master/index.js
// https://github.com/koajs/csrf/blob/master/index.js
var Cookie = require('cookies').Cookie
var Keygrip = require('keygrip')
var assert = require('assert')
var csrf = require('csrf')
var _ = require('lodash')

// key - session cookie name
// secrets - array of secrets for Keygrip
module.exports = function buildHeadersHelper ({secrets, key}={}) {
  assert(secrets && key, 'secrets and key are needed')

  var maxAge = 24 * 60 * 60 * 1000
  var keys = new Keygrip(secrets)
  var tokens = csrf()

  return function buildHeaders (session) {
    // _expire and _maxAge are used by koa-session
    session = _.assign({
      _expire: maxAge + Date.now(),
      _maxAge: maxAge,
      secret: tokens.secretSync()
    }, _.cloneDeep(session))

    var value = (new Buffer(JSON.stringify(session))).toString('base64')
    var cookie = new Cookie(key, value, {maxAge})
    var headers = {
      'x-csrf-token': tokens.create(session.secret),
      'cookie': `${cookie.toHeader()};`
    }

    // signed cookie
    cookie.value = keys.sign(cookie.toString())
    cookie.name += '.sig'
    headers.cookie += `${cookie.toHeader()};`

    return headers
  }

}
<commit_msg>Whitespace<commit_after>// REFERENCES
// https://github.com/pillarjs/cookies/blob/master/lib/cookies.js
// https://github.com/koajs/session/blob/master/index.js
// https://github.com/koajs/csrf/blob/master/index.js
var Cookie = require('cookies').Cookie
var Keygrip = require('keygrip')
var assert = require('assert')
var csrf = require('csrf')
var _ = require('lodash')

// key - session cookie name
// secrets - array of secrets for Keygrip
module.exports = function buildHeadersHelper ({secrets, key}={}) {
  assert(secrets && key, 'secrets and key are needed')

  var maxAge = 24 * 60 * 60 * 1000
  var keys = new Keygrip(secrets)
  var tokens = csrf()

  return function buildHeaders (session) {
    // _expire and _maxAge are used by koa-session
    session = _.assign({
      _expire: maxAge + Date.now(),
      _maxAge: maxAge,
      secret: tokens.secretSync()
    }, _.cloneDeep(session))

    var value = (new Buffer(JSON.stringify(session))).toString('base64')
    var cookie = new Cookie(key, value, {maxAge})
    var headers = {
      'x-csrf-token': tokens.create(session.secret),
      'cookie': `${cookie.toHeader()};`
    }

    // signed cookie
    cookie.value = keys.sign(cookie.toString())
    cookie.name += '.sig'
    headers.cookie += `${cookie.toHeader()};`

    return headers
  }
}
<|endoftext|>


<commit_before>
// Required environmental polyfills

if (!Object.assign) {
  Object.assign = require('object-assign');
}

// Integration testes

require('../integration/assignment-resolver-int-test');
require('../integration/caching-resolver-int-test');
require('../integration/constructor-resolver-int-test');
require('../integration/container-int-test');
require('../integration/creator-resolver-int-test');
require('../integration/decorator-resolver-int-test');
require('../integration/factory-method-resolver-int-test');
require('../integration/factory-resolver-int-test');
require('../integration/field-resolver-int-test');
require('../integration/freezing-resolver-int-test');
require('../integration/method-resolver-int-test');
require('../integration/multiple-resolvers-int-test');
require('../integration/optional-deps-int-test');
require('../integration/resolver-inheritance-int-test');

// Unit tests

require('../unit/component-test');
require('../unit/container-test');
require('../unit/dependency-test');
require('../unit/junkie-test');
<commit_msg>Attempting to fix failing build with jshint Missing "use strict" statement errors<commit_after>"use strict";
// Required environmental polyfills

if (!Object.assign) {
  Object.assign = require('object-assign');
}

// Integration testes

require('../integration/assignment-resolver-int-test');
require('../integration/caching-resolver-int-test');
require('../integration/constructor-resolver-int-test');
require('../integration/container-int-test');
require('../integration/creator-resolver-int-test');
require('../integration/decorator-resolver-int-test');
require('../integration/factory-method-resolver-int-test');
require('../integration/factory-resolver-int-test');
require('../integration/field-resolver-int-test');
require('../integration/freezing-resolver-int-test');
require('../integration/method-resolver-int-test');
require('../integration/multiple-resolvers-int-test');
require('../integration/optional-deps-int-test');
require('../integration/resolver-inheritance-int-test');

// Unit tests

require('../unit/component-test');
require('../unit/container-test');
require('../unit/dependency-test');
require('../unit/junkie-test');
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var path = require('path');
var assert = require('assert');
var cp = require('child_process');

function run(args, callback) {
  cp.exec('node ' + JSON.stringify(path.resolve(__dirname + '/../bin/jade.js')) + ' ' + args, {
    cwd: __dirname + '/temp'
  }, callback);
}

try {
  fs.mkdirSync(__dirname + '/temp');
} catch (ex) {
  if (ex.code !== 'EEXIST') {
    throw ex;
  }
}

describe('command line', function () {
  it('jade --no-debug --client --name myTemplate input.jade', function (done) {
    fs.writeFileSync(__dirname + '/temp/input.jade', '.foo bar');
    fs.writeFileSync(__dirname + '/temp/input.js', 'throw new Error("output not written");');
    run('--no-debug --client --name myTemplate input.jade', function (err) {
      if (err) return done(err);
      var template = Function('', fs.readFileSync(__dirname + '/temp/input.js', 'utf8') + ';return myTemplate;')();
      assert(template() === '
bar
');
      done();
    });
  });
  it('jade --no-debug --client --name-after-file input-file.jade', function (done) {
    fs.writeFileSync(__dirname + '/temp/input-file.jade', '.foo bar');
    fs.writeFileSync(__dirname + '/temp/input-file.js', 'throw new Error("output not written");');
    run('--no-debug --client --name-after-file input-file.jade', function (err, stdout, stderr) {
      if (err) return done(err);
      var template = Function('', fs.readFileSync(__dirname + '/temp/input-file.js', 'utf8') + ';return inputFileTemplate;')();
      assert(template() === '
bar
');
      return done();
    });
  });
  it('jade --no-debug --client --name-after-file _InPuTwIthWEiRdNaMME.jade', function (done) {
    fs.writeFileSync(__dirname + '/temp/_InPuTwIthWEiRdNaMME.jade', '.foo bar');
    fs.writeFileSync(__dirname + '/temp/_InPuTwIthWEiRdNaMME.js', 'throw new Error("output not written");');
    run('--no-debug --client --name-after-file _InPuTwIthWEiRdNaMME.jade', function (err, stdout, stderr) {
      if (err) return done(err);
      var template = Function('', fs.readFileSync(__dirname + '/temp/_InPuTwIthWEiRdNaMME.js', 'utf8') + ';return InputwithweirdnammeTemplate;')();
      assert(template() === '
bar
');
      return done();
    });
  });
});

describe('command line watch mode', function () {
  var watchProc;
  var stdout = '';
  after(function() {
    watchProc.kill('SIGINT');
  });
  it('jade --no-debug --client --name-after-file --watch input-file.jade (pass 1)', function (done) {
    fs.writeFileSync(__dirname + '/temp/input-file.jade', '.foo bar');
    fs.writeFileSync(__dirname + '/temp/input-file.js', 'throw new Error("output not written (pass 1)");');
    var args = [__dirname + '/../bin/jade.js', '--no-debug', '--client', '--name-after-file', '--watch', 'input-file.jade']
    watchProc = cp.spawn('node', args,  {
      cwd: __dirname + '/temp'
    });

    watchProc.stdout.setEncoding('utf8');
    watchProc
      .on('error', done)
      .stdout.on('data', function(buf) {
        stdout += buf;
        if (/.*rendered.*/.test(stdout)) {
          stdout = '';
          var template = Function('', fs.readFileSync(__dirname + '/temp/input-file.js', 'utf8') + ';return inputFileTemplate;')();
          assert(template() === '
bar
');

          watchProc.stdout.removeAllListeners('data');
          watchProc.removeAllListeners('error');
          return done();
        }
      });
  });
  it('jade --no-debug --client --name-after-file --watch input-file.jade (pass 2)', function (done) {
    fs.writeFileSync(__dirname + '/temp/input-file.js', 'throw new Error("output not written (pass 2)");');
    fs.writeFileSync(__dirname + '/temp/input-file.jade', '.foo baz');

    watchProc
      .on('error', done)
      .stdout.on('data', function(buf) {
        stdout += buf;
        if (/.*rendered.*/.test(stdout)) {
          stdout = '';
          var template = Function('', fs.readFileSync(__dirname + '/temp/input-file.js', 'utf8') + ';return inputFileTemplate;')();
          assert(template() === '
baz
');

          watchProc.stdout.removeAllListeners('data');
          watchProc.removeAllListeners('error');
          return done();
        }
      });
  });
});
<commit_msg>Allow stdin input in CLI test runner<commit_after>'use strict';

var fs = require('fs');
var path = require('path');
var assert = require('assert');
var cp = require('child_process');

function run(args, stdin, callback) {
  if (arguments.length === 2) {
    callback = stdin;
    stdin    = null;
  }
  cp.exec((stdin || '') + 'node ' + JSON.stringify(path.resolve(__dirname + '/../bin/jade.js')) + ' ' + args, {
    cwd: __dirname + '/temp'
  }, callback);
}

try {
  fs.mkdirSync(__dirname + '/temp');
} catch (ex) {
  if (ex.code !== 'EEXIST') {
    throw ex;
  }
}

describe('command line', function () {
  it('jade --no-debug --client --name myTemplate input.jade', function (done) {
    fs.writeFileSync(__dirname + '/temp/input.jade', '.foo bar');
    fs.writeFileSync(__dirname + '/temp/input.js', 'throw new Error("output not written");');
    run('--no-debug --client --name myTemplate input.jade', function (err) {
      if (err) return done(err);
      var template = Function('', fs.readFileSync(__dirname + '/temp/input.js', 'utf8') + ';return myTemplate;')();
      assert(template() === '
bar
');
      done();
    });
  });
  it('jade --no-debug --client --name-after-file input-file.jade', function (done) {
    fs.writeFileSync(__dirname + '/temp/input-file.jade', '.foo bar');
    fs.writeFileSync(__dirname + '/temp/input-file.js', 'throw new Error("output not written");');
    run('--no-debug --client --name-after-file input-file.jade', function (err, stdout, stderr) {
      if (err) return done(err);
      var template = Function('', fs.readFileSync(__dirname + '/temp/input-file.js', 'utf8') + ';return inputFileTemplate;')();
      assert(template() === '
bar
');
      return done();
    });
  });
  it('jade --no-debug --client --name-after-file _InPuTwIthWEiRdNaMME.jade', function (done) {
    fs.writeFileSync(__dirname + '/temp/_InPuTwIthWEiRdNaMME.jade', '.foo bar');
    fs.writeFileSync(__dirname + '/temp/_InPuTwIthWEiRdNaMME.js', 'throw new Error("output not written");');
    run('--no-debug --client --name-after-file _InPuTwIthWEiRdNaMME.jade', function (err, stdout, stderr) {
      if (err) return done(err);
      var template = Function('', fs.readFileSync(__dirname + '/temp/_InPuTwIthWEiRdNaMME.js', 'utf8') + ';return InputwithweirdnammeTemplate;')();
      assert(template() === '
bar
');
      return done();
    });
  });
});

describe('command line watch mode', function () {
  var watchProc;
  var stdout = '';
  after(function() {
    watchProc.kill('SIGINT');
  });
  it('jade --no-debug --client --name-after-file --watch input-file.jade (pass 1)', function (done) {
    fs.writeFileSync(__dirname + '/temp/input-file.jade', '.foo bar');
    fs.writeFileSync(__dirname + '/temp/input-file.js', 'throw new Error("output not written (pass 1)");');
    var args = [__dirname + '/../bin/jade.js', '--no-debug', '--client', '--name-after-file', '--watch', 'input-file.jade']
    watchProc = cp.spawn('node', args,  {
      cwd: __dirname + '/temp'
    });

    watchProc.stdout.setEncoding('utf8');
    watchProc
      .on('error', done)
      .stdout.on('data', function(buf) {
        stdout += buf;
        if (/.*rendered.*/.test(stdout)) {
          stdout = '';
          var template = Function('', fs.readFileSync(__dirname + '/temp/input-file.js', 'utf8') + ';return inputFileTemplate;')();
          assert(template() === '
bar
');

          watchProc.stdout.removeAllListeners('data');
          watchProc.removeAllListeners('error');
          return done();
        }
      });
  });
  it('jade --no-debug --client --name-after-file --watch input-file.jade (pass 2)', function (done) {
    fs.writeFileSync(__dirname + '/temp/input-file.js', 'throw new Error("output not written (pass 2)");');
    fs.writeFileSync(__dirname + '/temp/input-file.jade', '.foo baz');

    watchProc
      .on('error', done)
      .stdout.on('data', function(buf) {
        stdout += buf;
        if (/.*rendered.*/.test(stdout)) {
          stdout = '';
          var template = Function('', fs.readFileSync(__dirname + '/temp/input-file.js', 'utf8') + ';return inputFileTemplate;')();
          assert(template() === '
baz
');

          watchProc.stdout.removeAllListeners('data');
          watchProc.removeAllListeners('error');
          return done();
        }
      });
  });
});
<|endoftext|>


<commit_before>angular.module('views')
  .controller('loginPOSTExtended',
      ['$rootScope','$scope','$state','$stateParams','$location', 'loginServices','$controller',
       function ($rootScope,$scope,$state,$stateParams,$location, loginServices,$controller) {

          angular.extend(this, $controller('loginPOSTController', {$scope: $scope}));

          var id = $stateParams.id;

          var answers = {};
          function returnAnswers(dataObject, answersObject){
            switch(dataObject.constructor.name.toLowerCase()) {
              case 'array':
                for(var i=0; i<dataObject.length; i++){
                  answersObject[i] = {};
                  returnAnswers(dataObject[i], answersObject[i]);
                }
                break;
            }
            for(key in dataObject){
              if(dataObject[key]){
                if(dataObject[key].answer || dataObject[key].answer == ''){
                  if(dataObject[key].typeRef){
                    dataObject[key].answer = dataObject[key].answer._id;
                  }
                  answersObject[key] = dataObject[key].answer;
                }else{
                  switch(dataObject[key].constructor.name.toLowerCase()) {
                    case 'array':
                      answersObject[key] = [];
                      returnAnswers(dataObject[key], answersObject[key]);
                      break;
                    case 'object':
                      answersObject[key] = {};
                      returnAnswers(dataObject[key], answersObject[key]);
                      break;
                  }
                }
              }
            }
            return answers;
          }
          $scope.submitForm = function(type){
            var data = returnAnswers($scope.directiveData, answers);
            data.grant_type = "password";
            data.client_id = "0";
            loginServices.postlogin(data, id ).then(function(response) {
                      $scope.changeState('main.login.FIND', {id: 1});
                  });
          }
        }
  ]);<commit_msg>don't include extendeds in generated code<commit_after><|endoftext|>


<commit_before>var setup = require('./support/setup');
var uri = setup.uri;

var assert = require('assert');
var request = require('../');

describe('req.set("Content-Type", contentType)', function(){

  it('should work with just the contentType component', function(done){
    request
    .post(uri + '/echo')
    .set('Content-Type', 'application/json')
    .send({ name: 'tobi' })
    .end(function(err, res){
      assert(!err);
      done();
    });
  });

  it('should work with the charset component', function(done){
    request
    .post(uri + '/echo')
    .set('Content-Type', 'application/json; charset=utf-8')
    .send({ name: 'tobi' })
    .end(function(err, res){
      assert(!err);
      done();
    });
  });

});
<commit_msg>Bump timeout<commit_after>var setup = require('./support/setup');
var uri = setup.uri;

var assert = require('assert');
var request = require('../');

describe('req.set("Content-Type", contentType)', function(){
  this.timeout(10000);

  it('should work with just the contentType component', function(done){
    request
    .post(uri + '/echo')
    .set('Content-Type', 'application/json')
    .send({ name: 'tobi' })
    .end(function(err, res){
      assert(!err);
      done();
    });
  });

  it('should work with the charset component', function(done){
    request
    .post(uri + '/echo')
    .set('Content-Type', 'application/json; charset=utf-8')
    .send({ name: 'tobi' })
    .end(function(err, res){
      assert(!err);
      done();
    });
  });

});
<|endoftext|>


<commit_before>// @flow

import * as ls from '../lib/languageclient';
import Convert from '../lib/convert';
import {Point, Range, TextEditor} from 'atom';
import {expect} from 'chai';

let originalPlatform;
const setProcessPlatform = platform => {
  Object.defineProperty(process, 'platform', {value: platform});
};

const createFakeEditor = (path: string, text: ?string): atom$TextEditor => {
  const editor = new TextEditor();
  editor.getBuffer().setPath(path);
  if (text != null) {
    editor.setText(text);
  }
  return editor;
};

describe('Convert', () => {
  beforeEach(() => {
    originalPlatform = process.platform;
  });
  afterEach(() => {
    Object.defineProperty(process, 'platform', {value: originalPlatform});
  });

  describe('pathToUri', () => {
    it('prefixes an absolute path with file://', () => {
      expect(Convert.pathToUri('/a/b/c/d.txt')).equals('file:///a/b/c/d.txt');
    });

    it('prefixes an relative path with file:///', () => {
      expect(Convert.pathToUri('a/b/c/d.txt')).equals('file:///a/b/c/d.txt');
    }); // TODO: Maybe don't do this in the function - should never be called with relative

    it('replaces backslashes with forward slashes', () => {
      expect(Convert.pathToUri('a\\b\\c\\d.txt')).equals('file:///a/b/c/d.txt');
    });

    it('does not encode Windows drive specifiers', () => {
      expect(Convert.pathToUri('d:\\ee\\ff.txt')).equals('file:///d:/ee/ff.txt');
    });

    it('URI encodes special characters', () => {
      expect(Convert.pathToUri('/a/sp ace/do$lar')).equals('file:///a/sp%20ace/do$lar');
    });
  });

  describe('uriToPath', () => {
    it("does not convert http: and https: uri's", () => {
      setProcessPlatform('darwin');
      expect(Convert.uriToPath('http://atom.io/a')).equals('http://atom.io/a');
      expect(Convert.uriToPath('https://atom.io/b')).equals('https://atom.io/b');
    });

    it('converts a file:// path to an absolute path', () => {
      setProcessPlatform('darwin');
      expect(Convert.uriToPath('file:///a/b/c/d.txt')).equals('/a/b/c/d.txt');
    });

    it('converts forward slashes to backslashes on Windows', () => {
      setProcessPlatform('win32');
      expect(Convert.uriToPath('file:///a/b/c/d.txt')).equals('a\\b\\c\\d.txt');
    });

    it('decodes Windows drive specifiers', () => {
      setProcessPlatform('win32');
      expect(Convert.uriToPath('file:///d:/ee/ff.txt')).equals('d:\\ee\\ff.txt');
    });

    it('URI decodes special characters', () => {
      setProcessPlatform('darwin');
      expect(Convert.uriToPath('file:///a/sp%20ace/do$lar')).equals('/a/sp ace/do$lar');
    });

    it('parses URI without double slash in the beginning', () => {
      expect(Convert.uriToPath('file:/a/b/c/d.txt')).equals('/a/b/c/d.txt');
    });
  });

  describe('pointToPosition', () => {
    it('converts an Atom Point to a LSP position', () => {
      const point = {row: 1, column: 2};
      const position = Convert.pointToPosition(point);
      expect(position.line).equals(point.row);
      expect(position.character).equals(point.column);
    });
  });

  describe('positionToPoint', () => {
    it('converts a LSP position to an Atom Point-array', () => {
      const position = {line: 3, character: 4};
      const point = Convert.positionToPoint(position);
      expect(point.row).equals(position.line);
      expect(point.column).equals(position.character);
    });
  });

  describe('lsRangeToAtomRange', () => {
    it('converts a LSP range to an Atom Range-array', () => {
      const lspRange = {
        start: {character: 5, line: 6},
        end: {line: 7, character: 8},
      };
      const atomRange = Convert.lsRangeToAtomRange(lspRange);
      expect(atomRange.start.row).equals(lspRange.start.line);
      expect(atomRange.start.column).equals(lspRange.start.character);
      expect(atomRange.end.row).equals(lspRange.end.line);
      expect(atomRange.end.column).equals(lspRange.end.character);
    });
  });

  describe('atomRangeToLSRange', () => {
    it('converts an Atom range to a LSP Range-array', () => {
      const atomRange = new Range(new Point(9, 10), new Point(11, 12));
      const lspRange = Convert.atomRangeToLSRange(atomRange);
      expect(lspRange.start.line).equals(atomRange.start.row);
      expect(lspRange.start.character).equals(atomRange.start.column);
      expect(lspRange.end.line).equals(atomRange.end.row);
      expect(lspRange.end.character).equals(atomRange.end.column);
    });
  });

  describe('editorToTextDocumentIdentifier', () => {
    it('uses getath which returns a path to create the URI', () => {
      const path = '/c/d/e/f/g/h/i/j.txt';
      const identifier = Convert.editorToTextDocumentIdentifier(createFakeEditor(path));
      expect(identifier.uri).equals('file://' + path);
    });
  });

  describe('editorToTextDocumentPositionParams', () => {
    it('uses the editor cursor position when none specified', () => {
      const path = '/c/d/e/f/g/h/i/j.txt';
      const editor = createFakeEditor(path, 'abc\ndefgh\nijkl');
      editor.setCursorBufferPosition(new Point(1, 2));
      const params = Convert.editorToTextDocumentPositionParams(editor);
      expect(params.textDocument.uri).equals('file://' + path);
      expect(params.position).deep.equals({line: 1, character: 2});
    });

    it('uses the cursor position parameter when specified', () => {
      const path = '/c/d/e/f/g/h/i/j.txt';
      const specifiedPoint = new Point(911, 112);
      const editor = createFakeEditor(path, 'abcdef\nghijkl\nmnopq');
      editor.setCursorBufferPosition(new Point(1, 1));
      const params = Convert.editorToTextDocumentPositionParams(editor, specifiedPoint);
      expect(params.textDocument.uri).equals('file://' + path);
      expect(params.position).deep.equals({line: 911, character: 112});
    });
  });

  describe('grammarScopesToTextEditorScopes', () => {
    it('converts a single grammarScope to an atom-text-editor scope', () => {
      const grammarScopes = ['abc.def'];
      const textEditorScopes = Convert.grammarScopesToTextEditorScopes(grammarScopes);
      expect(textEditorScopes).equals('atom-text-editor[data-grammar="abc def"]');
    });

    it('converts a multiple grammarScopes to a comma-seperated list of atom-text-editor scopes', () => {
      const grammarScopes = ['abc.def', 'ghi.jkl'];
      const textEditorScopes = Convert.grammarScopesToTextEditorScopes(grammarScopes);
      expect(textEditorScopes).equals(
        'atom-text-editor[data-grammar="abc def"], atom-text-editor[data-grammar="ghi jkl"]',
      );
    });

    it('converts grammarScopes containing HTML sensitive characters to escaped sequences', () => {
      const grammarScopes = ['abc<def', 'ghi"jkl'];
      const textEditorScopes = Convert.grammarScopesToTextEditorScopes(grammarScopes);
      expect(textEditorScopes).equals(
        'atom-text-editor[data-grammar="abc<def"], atom-text-editor[data-grammar="ghi"jkl"]',
      );
    });
  });

  describe('encodeHTMLAttribute', () => {
    it('encodes characters that are not safe inside a HTML attribute', () => {
      const stringToEncode = 'a"b\'c&d>e<f';
      const encoded = Convert.encodeHTMLAttribute(stringToEncode);
      expect(encoded).equals('a"b'c&d>e<f');
    });
  });

  describe('atomFileEventToLSFileEvents', () => {
    it('converts a created event', () => {
      const source = {path: '/a/b/c/d.txt', action: 'created'};
      const converted = Convert.atomFileEventToLSFileEvents(source);
      expect(converted[0]).deep.equals({uri: 'file:///a/b/c/d.txt', type: ls.FileChangeType.Created});
    });

    it('converts a modified event', () => {
      const source = {path: '/a/b/c/d.txt', action: 'modified'};
      const converted = Convert.atomFileEventToLSFileEvents(source);
      expect(converted[0]).deep.equals({uri: 'file:///a/b/c/d.txt', type: ls.FileChangeType.Changed});
    });

    it('converts a deleted event', () => {
      const source = {path: '/a/b/c/d.txt', action: 'deleted'};
      const converted = Convert.atomFileEventToLSFileEvents(source);
      expect(converted[0]).deep.equals({uri: 'file:///a/b/c/d.txt', type: ls.FileChangeType.Deleted});
    });

    it('converts a renamed event', () => {
      const source = {path: '/a/b/c/d.txt', oldPath: '/a/z/e.lst', action: 'renamed'};
      const converted = Convert.atomFileEventToLSFileEvents(source);
      expect(converted[0]).deep.equals({uri: 'file:///a/z/e.lst', type: ls.FileChangeType.Deleted});
      expect(converted[1]).deep.equals({uri: 'file:///a/b/c/d.txt', type: ls.FileChangeType.Created});
    });
  });
});
<commit_msg>Set correct platform for the test<commit_after>// @flow

import * as ls from '../lib/languageclient';
import Convert from '../lib/convert';
import {Point, Range, TextEditor} from 'atom';
import {expect} from 'chai';

let originalPlatform;
const setProcessPlatform = platform => {
  Object.defineProperty(process, 'platform', {value: platform});
};

const createFakeEditor = (path: string, text: ?string): atom$TextEditor => {
  const editor = new TextEditor();
  editor.getBuffer().setPath(path);
  if (text != null) {
    editor.setText(text);
  }
  return editor;
};

describe('Convert', () => {
  beforeEach(() => {
    originalPlatform = process.platform;
  });
  afterEach(() => {
    Object.defineProperty(process, 'platform', {value: originalPlatform});
  });

  describe('pathToUri', () => {
    it('prefixes an absolute path with file://', () => {
      expect(Convert.pathToUri('/a/b/c/d.txt')).equals('file:///a/b/c/d.txt');
    });

    it('prefixes an relative path with file:///', () => {
      expect(Convert.pathToUri('a/b/c/d.txt')).equals('file:///a/b/c/d.txt');
    }); // TODO: Maybe don't do this in the function - should never be called with relative

    it('replaces backslashes with forward slashes', () => {
      expect(Convert.pathToUri('a\\b\\c\\d.txt')).equals('file:///a/b/c/d.txt');
    });

    it('does not encode Windows drive specifiers', () => {
      expect(Convert.pathToUri('d:\\ee\\ff.txt')).equals('file:///d:/ee/ff.txt');
    });

    it('URI encodes special characters', () => {
      expect(Convert.pathToUri('/a/sp ace/do$lar')).equals('file:///a/sp%20ace/do$lar');
    });
  });

  describe('uriToPath', () => {
    it("does not convert http: and https: uri's", () => {
      setProcessPlatform('darwin');
      expect(Convert.uriToPath('http://atom.io/a')).equals('http://atom.io/a');
      expect(Convert.uriToPath('https://atom.io/b')).equals('https://atom.io/b');
    });

    it('converts a file:// path to an absolute path', () => {
      setProcessPlatform('darwin');
      expect(Convert.uriToPath('file:///a/b/c/d.txt')).equals('/a/b/c/d.txt');
    });

    it('converts forward slashes to backslashes on Windows', () => {
      setProcessPlatform('win32');
      expect(Convert.uriToPath('file:///a/b/c/d.txt')).equals('a\\b\\c\\d.txt');
    });

    it('decodes Windows drive specifiers', () => {
      setProcessPlatform('win32');
      expect(Convert.uriToPath('file:///d:/ee/ff.txt')).equals('d:\\ee\\ff.txt');
    });

    it('URI decodes special characters', () => {
      setProcessPlatform('darwin');
      expect(Convert.uriToPath('file:///a/sp%20ace/do$lar')).equals('/a/sp ace/do$lar');
    });

    it('parses URI without double slash in the beginning', () => {
      setProcessPlatform('darwin');
      expect(Convert.uriToPath('file:/a/b/c/d.txt')).equals('/a/b/c/d.txt');
    });
  });

  describe('pointToPosition', () => {
    it('converts an Atom Point to a LSP position', () => {
      const point = {row: 1, column: 2};
      const position = Convert.pointToPosition(point);
      expect(position.line).equals(point.row);
      expect(position.character).equals(point.column);
    });
  });

  describe('positionToPoint', () => {
    it('converts a LSP position to an Atom Point-array', () => {
      const position = {line: 3, character: 4};
      const point = Convert.positionToPoint(position);
      expect(point.row).equals(position.line);
      expect(point.column).equals(position.character);
    });
  });

  describe('lsRangeToAtomRange', () => {
    it('converts a LSP range to an Atom Range-array', () => {
      const lspRange = {
        start: {character: 5, line: 6},
        end: {line: 7, character: 8},
      };
      const atomRange = Convert.lsRangeToAtomRange(lspRange);
      expect(atomRange.start.row).equals(lspRange.start.line);
      expect(atomRange.start.column).equals(lspRange.start.character);
      expect(atomRange.end.row).equals(lspRange.end.line);
      expect(atomRange.end.column).equals(lspRange.end.character);
    });
  });

  describe('atomRangeToLSRange', () => {
    it('converts an Atom range to a LSP Range-array', () => {
      const atomRange = new Range(new Point(9, 10), new Point(11, 12));
      const lspRange = Convert.atomRangeToLSRange(atomRange);
      expect(lspRange.start.line).equals(atomRange.start.row);
      expect(lspRange.start.character).equals(atomRange.start.column);
      expect(lspRange.end.line).equals(atomRange.end.row);
      expect(lspRange.end.character).equals(atomRange.end.column);
    });
  });

  describe('editorToTextDocumentIdentifier', () => {
    it('uses getath which returns a path to create the URI', () => {
      const path = '/c/d/e/f/g/h/i/j.txt';
      const identifier = Convert.editorToTextDocumentIdentifier(createFakeEditor(path));
      expect(identifier.uri).equals('file://' + path);
    });
  });

  describe('editorToTextDocumentPositionParams', () => {
    it('uses the editor cursor position when none specified', () => {
      const path = '/c/d/e/f/g/h/i/j.txt';
      const editor = createFakeEditor(path, 'abc\ndefgh\nijkl');
      editor.setCursorBufferPosition(new Point(1, 2));
      const params = Convert.editorToTextDocumentPositionParams(editor);
      expect(params.textDocument.uri).equals('file://' + path);
      expect(params.position).deep.equals({line: 1, character: 2});
    });

    it('uses the cursor position parameter when specified', () => {
      const path = '/c/d/e/f/g/h/i/j.txt';
      const specifiedPoint = new Point(911, 112);
      const editor = createFakeEditor(path, 'abcdef\nghijkl\nmnopq');
      editor.setCursorBufferPosition(new Point(1, 1));
      const params = Convert.editorToTextDocumentPositionParams(editor, specifiedPoint);
      expect(params.textDocument.uri).equals('file://' + path);
      expect(params.position).deep.equals({line: 911, character: 112});
    });
  });

  describe('grammarScopesToTextEditorScopes', () => {
    it('converts a single grammarScope to an atom-text-editor scope', () => {
      const grammarScopes = ['abc.def'];
      const textEditorScopes = Convert.grammarScopesToTextEditorScopes(grammarScopes);
      expect(textEditorScopes).equals('atom-text-editor[data-grammar="abc def"]');
    });

    it('converts a multiple grammarScopes to a comma-seperated list of atom-text-editor scopes', () => {
      const grammarScopes = ['abc.def', 'ghi.jkl'];
      const textEditorScopes = Convert.grammarScopesToTextEditorScopes(grammarScopes);
      expect(textEditorScopes).equals(
        'atom-text-editor[data-grammar="abc def"], atom-text-editor[data-grammar="ghi jkl"]',
      );
    });

    it('converts grammarScopes containing HTML sensitive characters to escaped sequences', () => {
      const grammarScopes = ['abc<def', 'ghi"jkl'];
      const textEditorScopes = Convert.grammarScopesToTextEditorScopes(grammarScopes);
      expect(textEditorScopes).equals(
        'atom-text-editor[data-grammar="abc<def"], atom-text-editor[data-grammar="ghi"jkl"]',
      );
    });
  });

  describe('encodeHTMLAttribute', () => {
    it('encodes characters that are not safe inside a HTML attribute', () => {
      const stringToEncode = 'a"b\'c&d>e<f';
      const encoded = Convert.encodeHTMLAttribute(stringToEncode);
      expect(encoded).equals('a"b'c&d>e<f');
    });
  });

  describe('atomFileEventToLSFileEvents', () => {
    it('converts a created event', () => {
      const source = {path: '/a/b/c/d.txt', action: 'created'};
      const converted = Convert.atomFileEventToLSFileEvents(source);
      expect(converted[0]).deep.equals({uri: 'file:///a/b/c/d.txt', type: ls.FileChangeType.Created});
    });

    it('converts a modified event', () => {
      const source = {path: '/a/b/c/d.txt', action: 'modified'};
      const converted = Convert.atomFileEventToLSFileEvents(source);
      expect(converted[0]).deep.equals({uri: 'file:///a/b/c/d.txt', type: ls.FileChangeType.Changed});
    });

    it('converts a deleted event', () => {
      const source = {path: '/a/b/c/d.txt', action: 'deleted'};
      const converted = Convert.atomFileEventToLSFileEvents(source);
      expect(converted[0]).deep.equals({uri: 'file:///a/b/c/d.txt', type: ls.FileChangeType.Deleted});
    });

    it('converts a renamed event', () => {
      const source = {path: '/a/b/c/d.txt', oldPath: '/a/z/e.lst', action: 'renamed'};
      const converted = Convert.atomFileEventToLSFileEvents(source);
      expect(converted[0]).deep.equals({uri: 'file:///a/z/e.lst', type: ls.FileChangeType.Deleted});
      expect(converted[1]).deep.equals({uri: 'file:///a/b/c/d.txt', type: ls.FileChangeType.Created});
    });
  });
});
<|endoftext|>