diff --git a/src/components/card/card.spec.js b/src/components/card/card.spec.js index 29880d5a486..ca709cb9a06 100644 --- a/src/components/card/card.spec.js +++ b/src/components/card/card.spec.js @@ -1,157 +1,269 @@ -import { loadFixture, testVM } from '../../../tests/utils' +import Card from './card' +import { mount } from '@vue/test-utils' describe('card', () => { - beforeEach(loadFixture(__dirname, 'card')) - testVM() + it('default has expected structure', async () => { + const wrapper = mount(Card) + + // Outer div + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('card') + expect(wrapper.classes().length).toBe(1) + + // Should have one child div.card-body + expect(wrapper.findAll('.card > .card-body').length).toBe(1) + expect(wrapper.findAll('.card-body').length).toBe(1) + expect(wrapper.find('.card-body').is('div')).toBe(true) + expect(wrapper.find('.card-body').classes()).toContain('card-body') + expect(wrapper.find('.card-body').classes().length).toBe(1) + + // Should have no content by default + expect(wrapper.text()).toEqual('') + }) - it("should contain '.card-body' class in the default slot", async () => { - const { - app: { $refs } - } = window + it('should not contain "card-body" if prop no-body set', async () => { + const wrapper = mount(Card, { + propsData: { + noBody: true + } + }) - const refs = ['simple_card', 'standard_card', 'img_card', 'img_overlay_card'] + // Outer div + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('card') + expect(wrapper.classes().length).toBe(1) - refs.forEach(ref => { - const childNodes = [...$refs[ref].childNodes] - const cardBody = childNodes.find(el => el.classList && el.classList.contains('card-body')) + // Should no have a card body + expect(wrapper.findAll('.card-body').length).toBe(0) + // Should have no content by default + expect(wrapper.text()).toEqual('') + }) - expect(cardBody).toBeDefined() + it('renders custom root element when tag prop set', async () => { + const wrapper = mount(Card, { + propsData: { + tag: 'article', + noBody: true + } }) + + // Outer div + expect(wrapper.is('article')).toBe(true) + expect(wrapper.classes()).toContain('card') + expect(wrapper.classes().length).toBe(1) + expect(wrapper.text()).toEqual('') }) - it("should not contain '.card-body' class if no-body specified", async () => { - const { - app: { $refs } - } = window + it('applies variant classes to root element', async () => { + const wrapper = mount(Card, { + propsData: { + noBody: true, + bgVariant: 'info', + borderVariant: 'danger', + textVariant: 'dark' + } + }) - expect($refs.no_body.classList.contains('card-body')).toBe(false) - expect($refs.no_body_default_slot).toEqual($refs.no_body.children[0]) + // Outer div + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('card') + expect(wrapper.classes()).toContain('bg-info') + expect(wrapper.classes()).toContain('border-danger') + expect(wrapper.classes()).toContain('text-dark') + expect(wrapper.classes().length).toBe(4) + expect(wrapper.text()).toEqual('') }) - it('should contain class names', async () => { - const { - app: { $refs } - } = window + it('applies text align class to when align prop set', async () => { + const wrapper = mount(Card, { + propsData: { + noBody: true, + align: 'right' + } + }) - expect($refs.simple_card).toHaveAllClasses(['card', 'bg-success', 'border-success']) - expect($refs.standard_card).toHaveClass('card') - expect($refs.img_card).toHaveClass('card') - expect($refs.img_overlay_card).toHaveAllClasses(['card']) + // Outer div + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('card') + expect(wrapper.classes()).toContain('text-right') + expect(wrapper.classes().length).toBe(2) + expect(wrapper.text()).toEqual('') + }) - const cardBodyEl = [...$refs.img_overlay_card.childNodes].find( - el => el.classList && el.classList.contains('card-body') - ) + it('should have content from default slot', async () => { + const wrapperBody = mount(Card, { + propsData: { + noBody: false + }, + slots: { + default: 'foobar' + } + }) + const wrapperNoBody = mount(Card, { + propsData: { + noBody: true + }, + slots: { + default: 'foobar' + } + }) + + // With body + expect(wrapperBody.is('div')).toBe(true) + expect(wrapperBody.findAll('.card-body').length).toBe(1) + expect(wrapperBody.find('.card-body').text()).toBe('foobar') - expect(cardBodyEl.classList.contains('card-img-overlay')).toBe(true) + // With no body + expect(wrapperNoBody.is('div')).toBe(true) + expect(wrapperNoBody.findAll('.card-body').length).toBe(0) + expect(wrapperNoBody.text()).toBe('foobar') }) - it('should contain text content', async () => { - const { - app: { $refs } - } = window + it('should have class flex-row when img-left set', async () => { + const wrapper = mount(Card, { + propsData: { + noBody: true, + imgLeft: true + } + }) - expect($refs.simple_card.textContent).toContain('Simple Card') - expect($refs.standard_card.textContent).toContain('Last updated 3 mins ago') - expect($refs.img_card.textContent).toContain('This is my opinion :)') - expect($refs.img_overlay_card.textContent).toContain('Overlay cards are cute!') + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('card') + expect(wrapper.classes()).toContain('flex-row') + expect(wrapper.classes().length).toBe(2) }) - it('standard_card should display card header', async () => { - const { app } = window - - const childNodes = [...app.$refs.standard_card.childNodes] - const headerEl = childNodes.find(el => el.classList && el.classList.contains('card-header')) + it('should have class flex-row-reverse when img-right set', async () => { + const wrapper = mount(Card, { + propsData: { + noBody: true, + imgRight: true + } + }) - expect(headerEl).toBeDefined() - expect(headerEl.textContent).toContain(app.headerText) + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('card') + expect(wrapper.classes()).toContain('flex-row-reverse') + expect(wrapper.classes().length).toBe(2) }) - it('standard_card should display card footer', async () => { - const { - app: { $refs } - } = window - - const childNodes = [...$refs.standard_card.childNodes] - const footerEl = childNodes.find(el => el.classList && el.classList.contains('card-footer')) - const footerText = 'Last updated 3 mins ago' + it('should have class flex-row when img-left and img-right set', async () => { + const wrapper = mount(Card, { + propsData: { + noBody: true, + imgLeft: true, + imgRight: true + } + }) - expect(footerEl).toBeDefined() - expect(footerEl.textContent).toContain(footerText) + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('card') + expect(wrapper.classes()).toContain('flex-row') + expect(wrapper.classes()).not.toContain('flex-row-reverse') + expect(wrapper.classes().length).toBe(2) }) - it('should contain with matching src', async () => { - const { app } = window + it('should have header and footer when header and footer props are set', async () => { + const wrapper = mount(Card, { + propsData: { + header: 'foo', + footer: 'bar' + }, + slots: { + default: 'fizzle' + } + }) - const refsWithImg = ['img_card', 'img_overlay_card'] + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('card') - refsWithImg.forEach((ref, i) => { - const node = app.$refs[ref] - const src = app['img' + i] - const childNodes = [...node.childNodes] - const imgEl = childNodes.find(el => el.tagName && el.tagName === 'IMG') + expect(wrapper.findAll('.card-header').length).toBe(1) + expect(wrapper.find('.card-header').text()).toBe('foo') + expect(wrapper.findAll('.card-body').length).toBe(1) + expect(wrapper.find('.card-body').text()).toBe('fizzle') + expect(wrapper.findAll('.card-footer').length).toBe(1) + expect(wrapper.find('.card-footer').text()).toBe('bar') - expect(imgEl).toBeDefined() - expect(imgEl.src).toEqual(src) - }) + // Expected order + expect(wrapper.find('.card-header+.card-body+.card-footer').exists()).toBe(true) }) - it('should add flex-row to a img-left or img-right image', async () => { - const { app } = window - const node = app.$refs['img_card'] - const childNodes = [...node.childNodes] - const imgEl = childNodes.find(el => el.tagName && el.tagName === 'IMG') + it('should have img at top', async () => { + const wrapper = mount(Card, { + propsData: { + imgSrc: '/foo/bar', + imgAlt: 'foobar', + imgTop: true + } + }) - expect(imgEl).toBeDefined() - expect(imgEl.classList).toEqual(expect.objectContaining(/^flex-row/)) - }) + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('card') - it("should use the 'tag' for element tag", async () => { - const { - app: { $refs } - } = window - const $titleCard = $refs.card_group.querySelector('#title-tag-test') - // Card ref -> .card-body -> title el - expect($titleCard).toBeElement('article') - }) + expect(wrapper.findAll('img').length).toBe(1) + const $img = wrapper.find('img') + expect($img.is('img')).toBe(true) + expect($img.attributes('src')).toBe('/foo/bar') + expect($img.attributes('alt')).toBe('foobar') + expect($img.classes()).toContain('card-img-top') + expect($img.classes().length).toBe(1) - it("should use the 'title-tag' for element tag", async () => { - const { - app: { $refs } - } = window - const $titleCard = $refs.card_group.querySelector('#title-tag-test') - // Card ref -> .card-body -> title el - expect($titleCard.children[0].children[0]).toBeElement('h1') + // Expected order + expect(wrapper.find('img + .card-body').exists()).toBe(true) }) - it("should use the 'sub-title-tag' for element tag", async () => { - const { - app: { $refs } - } = window - const $subtitleCard = $refs.card_group.querySelector('#sub-title-tag-test') - // Card ref -> .card-body -> subtitle el - expect($subtitleCard.children[0].children[0]).toBeElement('h2') - }) - - it("CardGroup: should apply '.card-group' class", async () => { - const { - app: { $refs } - } = window + it('should have img at bottom', async () => { + const wrapper = mount(Card, { + propsData: { + imgSrc: '/foo/bar', + imgAlt: 'foobar', + imgBottom: true + } + }) - expect($refs.card_group.classList.contains('card-group')).toBe(true) - }) + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('card') - it("CardGroup: should use the 'tag' for element tag", async () => { - const { - app: { $refs } - } = window + expect(wrapper.findAll('img').length).toBe(1) + const $img = wrapper.find('img') + expect($img.is('img')).toBe(true) + expect($img.attributes('src')).toBe('/foo/bar') + expect($img.attributes('alt')).toBe('foobar') + expect($img.classes()).toContain('card-img-bottom') + expect($img.classes().length).toBe(1) - expect($refs.card_group).toBeElement('section') + // Expected order + expect(wrapper.find('.card-body + img').exists()).toBe(true) }) - it('CardBody should have assigned class', async () => { - const { - app: { $refs } - } = window - expect($refs.body).toHaveClass('card-text') + it('should have img overlay', async () => { + const wrapper = mount(Card, { + propsData: { + imgSrc: '/foo/bar', + imgAlt: 'foobar', + overlay: true + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('card') + expect(wrapper.classes().length).toBe(1) + + expect(wrapper.findAll('img').length).toBe(1) + const $img = wrapper.find('img') + expect($img.is('img')).toBe(true) + expect($img.attributes('src')).toBe('/foo/bar') + expect($img.attributes('alt')).toBe('foobar') + expect($img.classes()).toContain('card-img') + expect($img.classes().length).toBe(1) + + expect(wrapper.findAll('.card-body').length).toBe(1) + const $body = wrapper.find('.card-body') + expect($body.classes()).toContain('card-body') + expect($body.classes()).toContain('card-img-overlay') + expect($body.classes().length).toBe(2) + + // Expected order + expect(wrapper.find('img + .card-body').exists()).toBe(true) }) }) diff --git a/src/components/card/fixtures/card.html b/src/components/card/fixtures/card.html deleted file mode 100644 index 46f68f5ad64..00000000000 --- a/src/components/card/fixtures/card.html +++ /dev/null @@ -1,65 +0,0 @@ -
- - Simple Card - - - - Last updated 3 mins ago - - - - -
No body
-
- - - This is my opinion :) - - - - This is my opinion :) - - - - Overlay cards are cute! - - - - - - - - - -

Custom body

-
-
-
diff --git a/src/components/card/fixtures/card.js b/src/components/card/fixtures/card.js deleted file mode 100644 index b3ccca15f83..00000000000 --- a/src/components/card/fixtures/card.js +++ /dev/null @@ -1,8 +0,0 @@ -window.app = new Vue({ - el: '#app', - data: { - headerText: 'Card header text', - img0: 'http://placeskull.com/200/200/ABABAB/-1/0', - img1: 'http://placeskull.com/200/200/E8117F/-1/0' - } -}) diff --git a/src/components/embed/embed.spec.js b/src/components/embed/embed.spec.js index 4fd4cac0799..5b348cab381 100644 --- a/src/components/embed/embed.spec.js +++ b/src/components/embed/embed.spec.js @@ -1,88 +1,98 @@ -import { loadFixture, testVM } from '../../../tests/utils' +import Embed from './embed' +import { mount } from '@vue/test-utils' describe('embed', () => { - beforeEach(loadFixture(__dirname, 'embed')) - testVM() + it('default should have expected default structure', async () => { + const wrapper = mount(Embed) - it("default should be rendered with outer tag 'div'", async () => { - const { - app: { $refs } - } = window - expect($refs.default).toBeElement('div') - }) + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('embed-responsive') + expect(wrapper.classes()).toContain('embed-responsive-16by9') + expect(wrapper.classes().length).toBe(2) - it("tag should be rendered with outer tag 'aside'", async () => { - const { - app: { $refs } - } = window - expect($refs.tag).toBeElement('aside') + expect(wrapper.findAll('iframe').length).toBe(1) + expect(wrapper.find('iframe').classes()).toContain('embed-responsive-item') + expect(wrapper.find('iframe').classes().length).toBe(1) }) - it("default should be rendered with inner tag 'iframe'", async () => { - const { - app: { $refs } - } = window - expect($refs.default.children[0]).toBeElement('iframe') - }) + it('has custom root element when tag prop set', async () => { + const wrapper = mount(Embed, { + propsData: { + tag: 'aside' + } + }) - it("type should be rendered with inner tag 'video'", async () => { - const { - app: { $refs } - } = window - expect($refs.type.children[0]).toBeElement('video') + expect(wrapper.is('aside')).toBe(true) + expect(wrapper.classes()).toContain('embed-responsive') + expect(wrapper.classes()).toContain('embed-responsive-16by9') + expect(wrapper.classes().length).toBe(2) + expect(wrapper.findAll('iframe').length).toBe(1) }) - it("all should be rendered with default outer class 'embed-responsive'", async () => { - const { - app: { $refs } - } = window - ;['default', 'tag', 'type', 'aspect', 'attributes', 'children'].forEach(ref => { - expect($refs[ref]).toHaveClass('embed-responsive') + it('it renders specified inner element when type set', async () => { + const wrapper = mount(Embed, { + propsData: { + type: 'video' + } }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('embed-responsive') + expect(wrapper.classes()).toContain('embed-responsive-16by9') + expect(wrapper.classes().length).toBe(2) + expect(wrapper.findAll('video').length).toBe(1) + expect(wrapper.find('video').classes()).toContain('embed-responsive-item') + expect(wrapper.find('video').classes().length).toBe(1) }) - it("all should be rendered with default inner class 'embed-responsive-item'", async () => { - const { - app: { $refs } - } = window - ;['default', 'tag', 'type', 'aspect', 'attributes', 'children'].forEach(ref => { - expect($refs[ref].children[0]).toHaveClass('embed-responsive-item') + it('renders specified aspect ratio class', async () => { + const wrapper = mount(Embed, { + propsData: { + aspect: '4by3' + } }) - }) - it("default should be rendered with outer class 'embed-responsive-16by9'", async () => { - const { - app: { $refs } - } = window - expect($refs.default).toHaveClass('embed-responsive-16by9') + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('embed-responsive') + expect(wrapper.classes()).toContain('embed-responsive-4by3') + expect(wrapper.classes().length).toBe(2) }) - it("aspect should be rendered with outer class 'embed-responsive-4by3'", async () => { - const { - app: { $refs } - } = window - expect($refs.aspect).toHaveClass('embed-responsive-4by3') - }) + it('non-prop attributes should rendered on on inner element', async () => { + const wrapper = mount(Embed, { + attrs: { + src: '/foo/bar', + baz: 'buz' + } + }) - it("attributes should have attribute 'foo=bar' on inner tag", async () => { - const { - app: { $refs } - } = window - expect($refs.attributes.children[0].hasAttribute('foo')).toBe(true) - expect($refs.attributes.children[0].getAttribute('foo')).toBe('bar') + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('embed-responsive') + expect(wrapper.findAll('iframe').length).toBe(1) + expect(wrapper.find('iframe').classes()).toContain('embed-responsive-item') + expect(wrapper.find('iframe').attributes('src')).toBeDefined() + expect(wrapper.find('iframe').attributes('src')).toBe('/foo/bar') + expect(wrapper.find('iframe').attributes('baz')).toBeDefined() + expect(wrapper.find('iframe').attributes('baz')).toBe('buz') }) - it("attributes should have attribute 'baz' on inner tag", async () => { - const { - app: { $refs } - } = window - expect($refs.attributes.children[0].hasAttribute('baz')).toBe(true) - }) + it('default slot should be rendered inside inner element', async () => { + const wrapper = mount(Embed, { + propsData: { + type: 'video' + }, + slots: { + default: 'foobar' + } + }) - it('children should be rendered inside inner element', async () => { - const { - app: { $refs } - } = window - expect($refs.children.children[0].children[0]).toBeElement('source') + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('embed-responsive') + expect(wrapper.classes()).toContain('embed-responsive-16by9') + expect(wrapper.classes().length).toBe(2) + expect(wrapper.findAll('video').length).toBe(1) + expect(wrapper.find('video').classes()).toContain('embed-responsive-item') + expect(wrapper.find('video').classes().length).toBe(1) + expect(wrapper.find('video').text()).toBe('foobar') }) }) diff --git a/src/components/embed/fixtures/embed.html b/src/components/embed/fixtures/embed.html deleted file mode 100644 index 9c1c1bba04d..00000000000 --- a/src/components/embed/fixtures/embed.html +++ /dev/null @@ -1,13 +0,0 @@ -
- -
- -
- -
- -
- -
- -
diff --git a/src/components/embed/fixtures/embed.js b/src/components/embed/fixtures/embed.js deleted file mode 100644 index 0bae7b95202..00000000000 --- a/src/components/embed/fixtures/embed.js +++ /dev/null @@ -1,3 +0,0 @@ -window.app = new Vue({ - el: '#app' -})