Skip to content

Commit

Permalink
Merge pull request #19 from fringers/silent-on-production-flag
Browse files Browse the repository at this point in the history
Silent on production flag
  • Loading branch information
JKrol authored Jun 27, 2020
2 parents 31df763 + 7e7abe1 commit 96ff54a
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 58 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-deprecate",
"version": "0.2.4",
"version": "0.3.0",
"author": "fringers",
"scripts": {
"build": "vue-cli-service build --target lib src/deprecate.ts --mode production",
Expand Down
16 changes: 16 additions & 0 deletions src/components.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Vue from 'vue';
import { printDeprecated } from '@/logger';
import { getComponentOptions } from '@/helpers';

export const checkComponent = (component: Vue) => {
const options = getComponentOptions(component);
if (!options || !options.deprecated) {
return;
}

if (typeof options.deprecated === "string") {
printDeprecated(options.deprecated);
} else {
printDeprecated('Component ' + options.name + ' is deprecated');
}
}
64 changes: 11 additions & 53 deletions src/deprecate.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,23 @@
import Vue, { PluginObject } from 'vue';

function getOptions(component: Vue) {
if (!component.$vnode) {
return;
}

return (component.$vnode.componentOptions?.Ctor as any).options;
}

function checkComponent (component: Vue) {
const options = getOptions(component);
if (!options || !options.deprecated) {
return;
}

if (typeof options.deprecated === "string") {
printDeprecated(options.deprecated);
} else {
printDeprecated('Component ' + options.name + ' is deprecated');
}
}

function checkProps (component: Vue) {
const options = getOptions(component);
if (!options || !options.props || typeof options.props !== 'object') {
return;
}

const propsData = component.$options.propsData as any;
if (!propsData) {
return
}

Object.keys(options.props).forEach(key => {
const value = options.props[key];
if (!propsData[key] || !value.deprecated) {
return;
}

if (typeof value.deprecated === "string") {
printDeprecated(value.deprecated);
} else {
printDeprecated(`Property ${key} in component ${options.name} is deprecated`);
}
}
)
}


function printDeprecated (message: string) {
console.warn(`[DEPRECATED] ${message}`);
}
import { checkComponent } from '@/components';
import { checkProps } from '@/properties';

interface VueDeprecateOptions {
enabledOnProduction?: boolean;
}

const defaultOptions: VueDeprecateOptions = {
enabledOnProduction: false,
}

const VueDeprecate: PluginObject<VueDeprecateOptions> = {
install: function (vue: typeof Vue, options?: VueDeprecateOptions) {
install: function (vue: typeof Vue, options: VueDeprecateOptions = defaultOptions) {
vue.mixin({
created: function () {
if (process.env.NODE_ENV === 'production' && options && !options.enabledOnProduction) {
return;
}

// TODO: fix typings
checkComponent(this as Vue);
checkProps(this as Vue);
Expand Down
9 changes: 9 additions & 0 deletions src/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Vue from 'vue';

export const getComponentOptions = (component: Vue) => {
if (!component.$vnode) {
return;
}

return (component.$vnode.componentOptions?.Ctor as any).options;
}
3 changes: 3 additions & 0 deletions src/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const printDeprecated = (message: string) => {
console.warn(`[DEPRECATED] ${message}`);
}
29 changes: 29 additions & 0 deletions src/properties.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Vue from 'vue';
import { printDeprecated } from '@/logger';
import { getComponentOptions } from '@/helpers';

export const checkProps = (component: Vue) => {
const options = getComponentOptions(component);
if (!options || !options.props || typeof options.props !== 'object') {
return;
}

const propsData = component.$options.propsData as any;
if (!propsData) {
return
}

Object.keys(options.props).forEach(key => {
const value = options.props[key];
if (!propsData[key] || !value.deprecated) {
return;
}

if (typeof value.deprecated === "string") {
printDeprecated(value.deprecated);
} else {
printDeprecated(`Property ${key} in component ${options.name} is deprecated`);
}
}
)
}
2 changes: 1 addition & 1 deletion tests/unit/components.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { shallowMount, createLocalVue, VueClass } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueDeprecate from '@/deprecate';

describe('Components', () => {
Expand Down
133 changes: 133 additions & 0 deletions tests/unit/options.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueDeprecate from '@/deprecate';

describe('Options', () => {

const deprecatedComponent = {
name: 'DeprecatedComponent',
deprecated: true,
props: {
deprecatedProp: { deprecated: true },
},
template: '<div>this is component</div>'
};

// TODO: fix types
function mountWithPluginSpy(component: any, options?: any) {
const installSpy = jest.spyOn(VueDeprecate, 'install');

const localVue = createLocalVue()
localVue.use(VueDeprecate, options);

shallowMount(component, {
localVue,
propsData: {
deprecatedProp: 'some value',
}
});

expect(installSpy).toHaveBeenCalled();
}

describe('enabledOnProduction', () => {
const OLD_ENV = process.env;

beforeEach(() => {
jest.resetModules();
process.env = { ...OLD_ENV };
delete process.env.NODE_ENV;
});

afterEach(() => {
process.env = OLD_ENV;
});

it('log warnings if no options and not production', () => {
const warnMock = jest.fn();
console.warn = warnMock;

mountWithPluginSpy(deprecatedComponent);

expect(warnMock).toHaveBeenCalledTimes(2);
});

it('log warnings if other options and not production', () => {
const warnMock = jest.fn();
console.warn = warnMock;

mountWithPluginSpy(deprecatedComponent, {
someProp: 'value',
});

expect(warnMock).toHaveBeenCalledTimes(2);
});

it('log warnings if enabledOnProduction=true and not production', () => {
const warnMock = jest.fn();
console.warn = warnMock;

mountWithPluginSpy(deprecatedComponent, {
enabledOnProduction: true,
});

expect(warnMock).toHaveBeenCalledTimes(2);
});

it('log warnings if enabledOnProduction=false and not production', () => {
const warnMock = jest.fn();
console.warn = warnMock;

mountWithPluginSpy(deprecatedComponent, {
enabledOnProduction: false,
});

expect(warnMock).toHaveBeenCalledTimes(2);
});

it('no warnings if no options and production', () => {
const warnMock = jest.fn();
console.warn = warnMock;

process.env.NODE_ENV = 'production';
mountWithPluginSpy(deprecatedComponent);

expect(warnMock).not.toHaveBeenCalled();
});

it('no warnings if other options and production', () => {
const warnMock = jest.fn();
console.warn = warnMock;

process.env.NODE_ENV = 'production';
mountWithPluginSpy(deprecatedComponent, {
someProp: 'value',
});

expect(warnMock).not.toHaveBeenCalled();
});

it('log warnings if enabledOnProduction=true and production', () => {
const warnMock = jest.fn();
console.warn = warnMock;

process.env.NODE_ENV = 'production';
mountWithPluginSpy(deprecatedComponent, {
enabledOnProduction: true,
});

expect(warnMock).toHaveBeenCalledTimes(2);
});

it('no warnings if enabledOnProduction=false and production', () => {
const warnMock = jest.fn();
console.warn = warnMock;

process.env.NODE_ENV = 'production';
mountWithPluginSpy(deprecatedComponent, {
enabledOnProduction: false,
});

expect(warnMock).not.toHaveBeenCalled();
});
});
});
4 changes: 2 additions & 2 deletions tests/unit/props.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ describe('Props', () => {
deprecatedProp: 'value'
});

expect(warnMock).toHaveBeenCalledTimes(1)
expect(warnMock).toHaveBeenCalledTimes(1);
expect(warnMock.mock.calls[0][0]).toContain('[DEPRECATED]');
expect(warnMock.mock.calls[0][0]).toContain(componentWithObjectProps.name);
expect(warnMock.mock.calls[0][0]).toContain('deprecatedProp');
Expand All @@ -142,7 +142,7 @@ describe('Props', () => {
deprecatedPropWithDefaultVal: true,
});

expect(warnMock).toHaveBeenCalledTimes(1)
expect(warnMock).toHaveBeenCalledTimes(1);
expect(warnMock.mock.calls[0][0]).toContain('[DEPRECATED]');
expect(warnMock.mock.calls[0][0]).toContain(componentWithObjectProps.name);
expect(warnMock.mock.calls[0][0]).toContain('deprecatedPropWithDefaultVal');
Expand Down
4 changes: 3 additions & 1 deletion types/deprecate.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import Vue, { PluginObject } from 'vue';

export declare interface VueDeprecateOptions {}

interface VueDeprecate extends PluginObject<VueDeprecateOptions> {}
interface VueDeprecate extends PluginObject<VueDeprecateOptions> {
enabledOnProduction?: boolean;
}

declare const VueDeprecate: VueDeprecate

Expand Down

0 comments on commit 96ff54a

Please sign in to comment.