describe('Misc Features', function () { var nextTick = require('vue/src/utils').nextTick describe('inline expression', function () { it('should evaluate the correct value', function (done) { var v = new Vue({ template: '{{a + "123" + b}} and {{c}}' }) v.a = 'A' v.b = 'B' v.c = 'C' nextTick(function () { assert.strictEqual(v.$el.textContent, 'A123B and C') done() }) }) }) describe('expression inside attributes', function () { it('should interpolate the attribute', function (done) { var v = new Vue({ attributes: { test: 'one {{msg}} three' }, data: { msg: 'two' } }) assert.strictEqual(v.$el.getAttribute('test'), 'one two three') v.msg = '2' nextTick(function () { assert.strictEqual(v.$el.getAttribute('test'), 'one 2 three') done() }) }) it('should work with filters', function (done) { var v = new Vue({ attributes: { 'class': '{{msg | test}}' }, data: { msg: 'hello' }, filters: { test: function (v) { return v + '-bye' } } }) assert.strictEqual(v.$el.className, 'hello-bye') v.msg = 'ok' nextTick(function () { assert.strictEqual(v.$el.className, 'ok-bye') done() }) }) }) describe('triple mustache', function () { it('should set unescaped HTML', function () { var v = new Vue({ template: '{{{html}}}', data: { html: 'ahi' } }) assert.strictEqual(v.$el.innerHTML, 'ahi') }) }) describe('computed properties', function () { it('should be accessible like a normal attribtue', function () { var b = 2 var v = new Vue({ template: '{{nested.value.a}}', data: { a: 1, }, computed: { test: { $get: function () { return this.a + b }, $set: function (v) { b = v - this.a } }, getOnly: function () { return this.a + 1 } } }) assert.strictEqual(v.test, 3) assert.strictEqual(v.getOnly, 2) v.a = 2 assert.strictEqual(v.test, 4) assert.strictEqual(v.getOnly, 3) b = 3 assert.strictEqual(v.test, 5) v.test = 10 assert.strictEqual(b, 8) }) it('should be bindable in templates, even nested', function (done) { var v = new Vue({ template: '{{nested.value.a}}', data: { a: 1 }, computed: { nested: function () { return { value: { a: this.a + 2 } } } } }) assert.strictEqual(v.$el.textContent, '3') v.a = 2 nextTick(function () { assert.strictEqual(v.$el.textContent, '4') done() }) }) }) describe('setting an object to empty', function () { it('should emit undefined for paths in the old object', function (done) { var v = new Vue({ data: { a: { b: { c: 1 } } } }) var emitted = false v.$watch('a.b.c', function (v) { assert.strictEqual(v, undefined) emitted = true }) v.a = {} nextTick(function () { assert.ok(emitted) done() }) }) }) describe('event delegation', function () { var inCalled = 0, outCalled = 0, innerHandler = function () {} var v = new Vue({ template: '
', methods: { 'in': function (e) { inCalled++ innerHandler(e) }, out: function () { outCalled++ } } }) v.$appendTo('#test') it('should work', function () { var e = mockMouseEvent('click') v.$el.querySelector('.inner').dispatchEvent(e) assert.strictEqual(inCalled, 1) assert.strictEqual(outCalled, 1) }) it('should allow stopPropagation()', function () { innerHandler = function (e) { e.stopPropagation() } var e = mockMouseEvent('click') v.$el.querySelector('.inner').dispatchEvent(e) assert.strictEqual(inCalled, 2) assert.strictEqual(outCalled, 1) }) }) describe('computed filter', function () { it('should process filter with `this` as computed', function (done) { var V = Vue.extend({ template: '
{{n | plus}}
{{n | minus}}
', filters: { plus: function (v) { return v + this.a } } }) V.filter('minus', function (v) { return v - this.a }) var v = new V({ data: { a: 1, n: 1 } }) assert.strictEqual(v.$el.querySelector('.plus').textContent, '2') assert.strictEqual(v.$el.querySelector('.minus').textContent, '0') v.a = 2 nextTick(function () { assert.strictEqual(v.$el.querySelector('.plus').textContent, '3') assert.strictEqual(v.$el.querySelector('.minus').textContent, '-1') done() }) }) }) describe('content insertion points', function () { it('should insert original content', function () { var div = document.createElement('div') div.innerHTML = '

hello!

' var t = new Vue({ el: div, template: '

before

after

' }) assert.strictEqual(t.$el.innerHTML, '

before

hello!

after

') }) it('should respect "select" attributes', function () { var div = document.createElement('div') div.innerHTML = '

hi

ha

hehe

' var t = new Vue({ el: div, template: '

before

' + '' + '' + '' + '

after

' }) assert.strictEqual(t.$el.innerHTML, '

before

' + '

hehe

' + '

ha

hi

' + '

after

' ) }) it('should use fallback content if no rawContent is available', function () { var t = new Vue({ template: 'Hello!' }) assert.strictEqual(t.$el.innerHTML, 'Hello!') }) }) describe('interpolation in directive values', function () { it('should be evaled by the compiler', function () { var t = new Vue({ template: '', data: { field: 'test', test: 'hello' } }) assert.equal(t.$el.childNodes[0].value, 'hello') }) }) describe('attribute names with colons', function () { it('should be parsed properly', function () { var t = new Vue({ template: '', data: { icon: 'test' } }) assert.equal(t.$el.firstChild.getAttribute('xlink:href'), 'test') }) }) })