├── logo.png
├── preview.gif
├── test
├── conditions
│ ├── simple-config
│ │ └── gue.json
│ ├── wrong-template
│ │ └── gue.json
│ ├── right-template
│ │ ├── gue.json
│ │ └── right.vue
│ └── default-template
│ │ ├── gue.json
│ │ ├── black.vue
│ │ └── white.vue
├── templates
│ ├── myUnitTmp.js
│ └── myVueTmp.vue
├── cleanup.js
└── index.js
├── src
├── config.js
├── utils.js
├── templates
│ ├── sample-component.js
│ └── sample-unit.js
├── bin.js
├── logger.js
└── index.js
├── .travis.yml
├── .gitignore
├── LICENSE
├── package.json
└── README.md
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hosein2398/gue/master/logo.png
--------------------------------------------------------------------------------
/preview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hosein2398/gue/master/preview.gif
--------------------------------------------------------------------------------
/test/conditions/simple-config/gue.json:
--------------------------------------------------------------------------------
1 | {
2 | "componentRoot": "./somewhereYouLike"
3 | }
--------------------------------------------------------------------------------
/test/conditions/wrong-template/gue.json:
--------------------------------------------------------------------------------
1 | {
2 | "componentSource": {
3 | "some" : "./sefsfsf",
4 | "another" : "./nowhere"
5 | }
6 | }
--------------------------------------------------------------------------------
/test/conditions/right-template/gue.json:
--------------------------------------------------------------------------------
1 | {
2 | "componentSource": {
3 | "some" : "./some/sdf.vue",
4 | "right" : "./right.vue"
5 | }
6 | }
--------------------------------------------------------------------------------
/test/conditions/default-template/gue.json:
--------------------------------------------------------------------------------
1 | {
2 | "componentSource": {
3 | "white" : "./white.vue",
4 | "black:default" : "./black.vue"
5 | }
6 | }
--------------------------------------------------------------------------------
/src/config.js:
--------------------------------------------------------------------------------
1 | const JoyCon = require('joycon');
2 |
3 | const joycon = new JoyCon();
4 |
5 | const conf = joycon.loadSync(['gue.json']);
6 |
7 | module.exports = conf;
8 |
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | exports.isObject = obj => obj !== null && obj.constructor.name === 'Object';
2 |
3 | exports.isObjectEmpty = obj => !Object.keys(obj).length;
4 |
5 | exports.findDefault = obj => Object.keys(obj).find(i => i.split(':').length > 1);
6 |
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | os:
3 | - linux
4 | - osx
5 |
6 | cache:
7 | directories:
8 | - node_modules
9 | - $HOME/.npm
10 |
11 | node_js:
12 | - "10"
13 |
14 | services:
15 | - xvfb
16 | before_script:
17 | - npm install
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Node build artifacts
2 | node_modules
3 | npm-debug.log
4 | doc
5 | .nyc_output
6 |
7 | # Local development
8 | *.env
9 | *.dev
10 | .DS_Store
11 |
12 | # Docker
13 | Dockerfile
14 | docker-compose.yml
15 |
16 | # File Manager(dolphin)
17 | .directory
--------------------------------------------------------------------------------
/test/templates/myUnitTmp.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import <%NAME%> from '<%PATH%>'
3 |
4 | describe('custom Gue test file', () => {
5 | it('here is a test', () => {
6 | const defaultData = <%NAME%>.data()
7 | expect(defaultData.gue).toBe('cool!')
8 | })
9 |
10 | })
--------------------------------------------------------------------------------
/test/conditions/right-template/right.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | here is the test component <%NAME%>
4 |
5 |
6 |
7 | export default {
8 | name: "<%NAME%>",
9 | props: [],
10 | mounted() {
11 |
12 | },
13 | data() {
14 | return {
15 | test: null
16 | }
17 | },
18 | methods: {
19 |
20 | },
21 | computed: {
22 |
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/src/templates/sample-component.js:
--------------------------------------------------------------------------------
1 | module.exports = `
2 |
3 |
4 |
5 |
6 |
7 |
8 | export default {
9 | name: "<%NAME%>",
10 | props: [],
11 | mounted() {
12 |
13 | },
14 | data() {
15 | return {
16 |
17 | }
18 | },
19 | methods: {
20 |
21 | },
22 | computed: {
23 |
24 | }
25 | }
26 |
27 |
32 | `;
33 |
--------------------------------------------------------------------------------
/test/conditions/default-template/black.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | here is the test component <%NAME%>
4 |
5 |
6 |
7 | export default {
8 | name: "<%NAME%>",
9 | props: [],
10 | mounted() {
11 |
12 | },
13 | data() {
14 | return {
15 | test: null
16 | }
17 | },
18 | methods: {
19 |
20 | },
21 | computed: {
22 |
23 | }
24 | }
25 |
26 |
28 |
--------------------------------------------------------------------------------
/test/conditions/default-template/white.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | here is the test component <%NAME%>
4 |
5 |
6 |
7 | export default {
8 | name: "<%NAME%>",
9 | props: [],
10 | mounted() {
11 |
12 | },
13 | data() {
14 | return {
15 | test: null
16 | }
17 | },
18 | methods: {
19 |
20 | },
21 | computed: {
22 |
23 | }
24 | }
25 |
26 |
28 |
--------------------------------------------------------------------------------
/test/templates/myVueTmp.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | here is the test component <%NAME%>
4 |
5 |
6 |
7 | export default {
8 | name: "<%NAME%>",
9 | props: [],
10 | mounted() {
11 |
12 | },
13 | data() {
14 | return {
15 | test: null
16 | }
17 | },
18 | methods: {
19 |
20 | },
21 | computed: {
22 |
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/src/templates/sample-unit.js:
--------------------------------------------------------------------------------
1 | module.exports = `
2 | import Vue from 'vue'
3 | import <%NAME%> from '<%PATH%>'
4 |
5 | describe('created method', () => {
6 | it('sets the correct default data', () => {
7 | const defaultData = <%NAME%>.data()
8 | expect(defaultData.message).toBe('hello!')
9 | })
10 |
11 | it('correctly sets the message when created', () => {
12 | const vm = new Vue(<%NAME%>).$mount()
13 | expect(vm.message).toBe('bye!')
14 | })
15 |
16 | })
17 | `;
18 |
--------------------------------------------------------------------------------
/test/cleanup.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const rimraf = require('rimraf');
4 |
5 | const directory = './test';
6 | const files = fs.readdirSync(directory);
7 |
8 | for (const file of files) {
9 | const doNotRemove = [
10 | 'index.js',
11 | '.nyc_output',
12 | 'cleanup.js',
13 | 'gue.json',
14 | 'templates',
15 | 'conditions'
16 | ];
17 | if (doNotRemove.includes(file)) {
18 | continue;
19 | }
20 |
21 | rimraf.sync(path.join(directory, file));
22 | }
23 |
--------------------------------------------------------------------------------
/src/bin.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const program = require('commander');
3 | const logger = require('./logger');
4 | const Gue = require('.');
5 |
6 | program
7 | .arguments(' [direcroty]')
8 | .option('-u, --unit', 'create unit test of the component too')
9 | .option('-t, --template ', 'define which template to use');
10 |
11 | const params = program.parse(process.argv);
12 |
13 | try {
14 | // eslint-disable-next-line no-negated-condition
15 | if (!params.args[0]) {
16 | logger.warn(`
17 | You must supply a name for your component
18 | Usage: gue [directory] [options]`);
19 | } else {
20 | const gue = new Gue(params.args[0], params.args[1], params);
21 | gue.generate();
22 | }
23 | } catch (error) {
24 | logger.error(error);
25 | }
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (C) Hosein Barzegaran
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/logger.js:
--------------------------------------------------------------------------------
1 | const box = require('boxen');
2 | const chalk = require('chalk');
3 | class Logger {
4 | success(name, dir, type) {
5 | console.log(
6 | box(
7 | `${chalk.hex('#45d03c')('✔️')} Created ${chalk.hex('#45d03c')(
8 | name
9 | )} ${type} in ${chalk.hex('#45d03c')(dir)}`,
10 | {
11 | padding: 1
12 | }
13 | )
14 | );
15 | }
16 |
17 | duplicate(name, dir, type) {
18 | console.log(
19 | box(
20 | `${chalk.hex('#e6e600')('💡')} You already have ${chalk.hex('#e6e600')(
21 | name
22 | )} ${type} in ${chalk.hex('#e6e600')(dir)}`,
23 | {padding: 1}
24 | )
25 | );
26 | }
27 |
28 | warn(m) {
29 | console.log(
30 | box(
31 | `${chalk.hex('#e6e600')('💡')} ${m}`,
32 | {padding: 1}
33 | )
34 | );
35 | }
36 |
37 | error(e) {
38 | console.log(
39 | box(`⚠️ ${chalk.red('Oops something went wrong')}`, {padding: 1})
40 | );
41 | console.log(e);
42 | }
43 |
44 | fatal(e) {
45 | console.log(
46 | box(`⚠️ ${chalk.red(e)}`, {padding: 1})
47 | );
48 | throw new Error(e);
49 | }
50 | }
51 |
52 | module.exports = new Logger();
53 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-gue",
3 | "version": "0.2.0",
4 | "description": "Vue component generator",
5 | "repository": {
6 | "url": "https://github.com/hosein2398/gue",
7 | "type": "git"
8 | },
9 | "author": "Hosein2398",
10 | "keywords": [
11 | "vue",
12 | "cli",
13 | "component",
14 | "generate",
15 | "generate component"
16 | ],
17 | "files": [
18 | "src"
19 | ],
20 | "license": "MIT",
21 | "main": "src/index.js",
22 | "scripts": {
23 | "lint": "xo",
24 | "cleanTestDir": "node ./test/cleanup.js",
25 | "pretest": "npm run cleanTestDir",
26 | "test": "cd test && ../node_modules/.bin/tap ./index.js",
27 | "posttest": "npm run cleanTestDir",
28 | "commit": "git-cz"
29 | },
30 | "bin": {
31 | "gue": "src/bin.js"
32 | },
33 | "dependencies": {
34 | "boxen": "^4.1.0",
35 | "chalk": "^2.4.2",
36 | "commander": "^3.0.2",
37 | "joycon": "^2.2.5"
38 | },
39 | "devDependencies": {
40 | "commitizen": "^4.0.3",
41 | "cz-conventional-changelog": "^3.0.2",
42 | "husky": "^3.0.9",
43 | "rimraf": "^3.0.0",
44 | "tap": "^14.7.2",
45 | "xo": "^0.25.3"
46 | },
47 | "xo": {
48 | "space": true,
49 | "rules": {
50 | "no-unused-expressions": [
51 | "error",
52 | {
53 | "allowShortCircuit": true
54 | }
55 | ]
56 | },
57 | "ignore": [
58 | "./test/templates/myUnitTmp.js"
59 | ]
60 | },
61 | "config": {
62 | "commitizen": {
63 | "path": "./node_modules/cz-conventional-changelog"
64 | }
65 | },
66 | "husky": {
67 | "hooks": {
68 | "pre-commit": "npm run lint"
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const fs = require('fs');
3 |
4 | const logger = require('./logger');
5 | const configFile = require('./config');
6 | const cmpTemplate = require('./templates/sample-component');
7 | const unitTemplate = require('./templates/sample-unit');
8 | const {isObject, findDefault, isObjectEmpty} = require('./utils');
9 |
10 | class Gue {
11 | constructor(componentName, distDir, options) {
12 | this.componentName = componentName;
13 | this.options = options;
14 | const config = configFile.data;
15 | this.componentSource = config && config.componentSource ? config.componentSource : '';
16 | this.componentRoot = config && config.componentRoot ? config.componentRoot : '';
17 | this.unitSource = config && config.unitSource ? config.unitSource : '';
18 | this.unitRoot = config && config.unitRoot ? config.unitRoot : './tests/unit/';
19 | this.distDir = distDir ?
20 | distDir :
21 | (this.componentRoot ?
22 | '' :
23 | './src/components');
24 | }
25 |
26 | generate() {
27 | this.writeComponent();
28 | this.options.unit && this.writeUnit();
29 | }
30 |
31 | writeComponent() {
32 | const dir = this.makeComponentDistDir();
33 | const data = this.formatComponent(dir);
34 | // TODO: if there was error in writing this dir should not be created too
35 | this.checkDirStatus(dir);
36 | this.checkFileStatus(dir, 'component') &&
37 | fs.writeFileSync(dir, data) === undefined && // Since this method returns undefined
38 | logger.success(this.componentName, dir, 'component');
39 | }
40 |
41 | writeUnit() {
42 | const dir = this.makeUnitDistDir();
43 | const data = this.formatUnit(dir);
44 | this.checkDirStatus(dir);
45 | this.checkFileStatus(dir, 'test file') &&
46 | fs.writeFileSync(dir, data) === undefined &&
47 | logger.success(this.componentName, dir, 'test file');
48 | }
49 |
50 | formatComponent() {
51 | let data;
52 | if (this.options.template) {
53 | this.checkConfigExist();
54 | if (!isObject(this.componentSource)) {
55 | logger.fatal('When using -t your componentSource must be an object');
56 | }
57 |
58 | if (isObject(this.componentSource)) {
59 | if (!(this.options.template in this.componentSource)) {
60 | logger.fatal(`There is no "${this.options.template}" template in componentSource in gue config file`);
61 | }
62 |
63 | data = fs.readFileSync(this.componentSource[this.options.template], {encoding: 'utf8'});
64 | }
65 | } else if (isObject(this.componentSource)) {
66 | const defaultTemplate = findDefault(this.componentSource);
67 | if (!defaultTemplate) {
68 | logger.fatal('No default component defined in componentSource object');
69 | }
70 |
71 | data = fs.readFileSync(this.componentSource[defaultTemplate], {encoding: 'utf8'});
72 | } else {
73 | data = this.componentSource ?
74 | fs.readFileSync(this.componentSource, {encoding: 'utf8'}) :
75 | cmpTemplate;
76 | }
77 |
78 | const rex = /<%NAME%>/g;
79 | return data.replace(rex, this.componentName);
80 | }
81 |
82 | formatUnit() {
83 | let data = this.unitSource ?
84 | fs.readFileSync(this.unitSource, {encoding: 'utf8'}) :
85 | unitTemplate;
86 | const rexName = /<%NAME%>/g;
87 | const rexPath = /<%PATH%>/g;
88 | // Want first argumet to be directory not a file
89 | const unitPath = path.relative(this.makeUnitDistDir().split('/').slice(0, -1).join('/'), this.makeComponentDistDir());
90 | data = data.replace(rexName, this.componentName);
91 | return data.replace(rexPath, unitPath);
92 | }
93 |
94 | makeComponentDistDir() {
95 | return path.join(
96 | this.componentRoot,
97 | this.distDir,
98 | `${this.componentName}.vue`
99 | );
100 | }
101 |
102 | makeUnitDistDir() {
103 | return path.join(this.unitRoot, `${this.componentName}.js`);
104 | }
105 |
106 | checkDirStatus(direcrories) {
107 | const spilitedDirs = direcrories.split('/');
108 | // Since we don't need .vue in our path
109 | const removeLast = spilitedDirs.slice(0, -1);
110 | const joinedDirs = removeLast.join('/');
111 | const exists = fs.existsSync(joinedDirs);
112 | if (!exists) {
113 | fs.mkdirSync(joinedDirs, {recursive: true});
114 | }
115 | }
116 |
117 | checkFileStatus(dirs, type) {
118 | if (fs.existsSync(dirs)) {
119 | logger.duplicate(this.componentName, dirs, type);
120 | return false;
121 | }
122 |
123 | return true;
124 | }
125 |
126 | checkConfigExist() {
127 | if (isObjectEmpty(configFile)) {
128 | logger.fatal('Could not find any config file in root directory');
129 | }
130 | }
131 |
132 | run() {
133 | this.generate();
134 | }
135 | }
136 |
137 | module.exports = Gue;
138 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Gue [](https://travis-ci.org/hosein2398/gue) [](https://coveralls.io/github/hosein2398/gue?branch=master)
3 |
4 |
5 |
6 | > Vue js component generator
7 |
8 |
9 |
10 |
11 |
12 | ## Demo
13 |
14 |
15 |
16 |
17 |
18 | Features
19 | * 📜 Generate Vue component
20 | * 🧰 Generate test file for the component
21 | * ⚙️ Dynamic path for component
22 | * 📁 Configurable root directory for components and tests
23 | * 📝 Custom templates for components and test
24 | ## Installing
25 | > Note that this package is published under name of `vue-gue`
26 | ```
27 | npm i -g vue-gue
28 | ```
29 |
30 | ## Getting started
31 | Head over to root of your project in terminal, say you want to create a component named `footer`:
32 | ```
33 | gue footer
34 | ```
35 | This will generate `footer` component in `./src/components/footer.vue`
36 | #### Change directory of component
37 | You can define a directory which you want your component to be generated in.
38 | ```
39 | gue tab ./menu
40 | ```
41 | This will generate `tab` component in `./menu/tab.vue`
42 | > Consider behavior of directory parameter when you have a config file and you don't. [details](#usage)
43 | > For a consistent way to change root directory of components see [config](#config-file).
44 |
45 | #### Generate test file
46 | Now if you want a component and also it's corresponding unit test file you can do:
47 | ```
48 | gue footer -u
49 | ```
50 | This will generate `footer` component in `./src/components/footer.vue` and also a test file in `./tests/unit/footer.js`
51 | > To change any of these directories see [config](#config-file)
52 | ## Usage
53 | General usage is like:
54 | ```
55 | $ gue --help
56 |
57 | Usage: gue [direcroty] [options]
58 |
59 | Options:
60 | -u, --unit create unit test of the component too
61 | -t, --template define which template to use
62 | -h, --help output usage information
63 |
64 | ```
65 | * <componentName> is mandatory.
66 | * [directory] is optional, and is a relative path.
67 | If you have a config file this will be a `subdirectory` of your [componentRoot](#options)
68 | If you don't, then this will lead to generation of component in exact `direcroty`
69 | * [options] are optional, available options are `-u` which will generate test file, and `-t` which is used to define which template for components to use.
70 |
71 | ## Config file
72 | Gue accepts a config file to change default settings. In root directory of project make a file `gue.json`, and Gue will automatically recognize and use it.
73 | #### Options
74 | Here are available options for config file:
75 | * `componentRoot`: root directory which components will be generated in. should be relative path.
76 | * `componentSource`: path to custom component template. Or an object to define [multiple templates](#using-multiple-custom-templates).
77 | * `unitRoot`: directory which test will be generated in. should be a relative path.
78 | * `unitSource`: path to custom test file template.
79 |
80 | An example of a config file with all options:
81 | ```json
82 | {
83 | "componentRoot":"./front-end/src/components",
84 | "unitRoot":"./front-end/test",
85 | "componentSource":"./myTemplates/myVueTemplate.vue",
86 | "unitSource":"./myTemplates/myTestTemplate.js"
87 | }
88 | ```
89 | Now if you run gue to create a `clock` component in your project, it'll generate it in `./front-end/src/components/clock.vue`.
90 | If you run following command in the same project:
91 | ```
92 | gue title ./header
93 | ```
94 | Will generate `./front-end/src/components/header/title.vue`
95 |
96 | #### Custom templates
97 | As said you can use custom templates in Gue, define path to them with `componentSource` and `unitSource` so that Gue will use them instead of it's default ones.
98 | ##### Variables
99 | In your component template you can use variable `<%NAME%>` and Gue will replace it with name of component when generating.
100 | And also in test template you use `<%NAME%>` and `<%PATH%>` which will be replaced with path where component is located, relative to path of test file.
101 | Here is an example of custom component template:
102 | ```
103 |
104 |
105 | Hey I'm a component generated with Gue, my name is <%NAME%>
106 |
107 |
108 |
109 | export default {
110 | name: "<%NAME%>",
111 | data() {
112 | return {
113 | someData: "a sample"
114 | }
115 | }
116 |
118 | ```
119 | To see other examples look at [templates folder](https://github.com/hosein2398/gue/tree/master/src/templates).
120 | ##### Using multiple custom templates
121 | You can use multiple custom templates. So `componentSource` can be object (multiple templates) or a string (single template). Multiple templates can be created like:
122 | ```json
123 | {
124 | "componentSource": {
125 | "component" : "./tmps/component.vue",
126 | "page" : "./tmps/page.vue"
127 | }
128 | }
129 | ```
130 | And when using Gue you have to tell it which component template to use:
131 | ```
132 | gue menu -t component
133 | gue setting ./pages -t page
134 | ```
135 | You can define one of your templates as `default` one, so that you don't have to type `-t` every time. Default component can be specified with `:default` postfix:
136 | ```json
137 | {
138 | "componentSource": {
139 | "component:default" : "./tmps/component.vue",
140 | "page" : "./tmps/page.vue"
141 | }
142 | }
143 | ```
144 | Now if you type any command without `-t`, component template will be used.
145 | ```
146 | gue foo
147 | ```
148 | Will use `component` template to generate foo component. No need of `-t component`
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const tap = require('tap');
4 | const Gue = require('../src');
5 | const defaultVueTemplate = require('../src/templates/sample-component');
6 | const defaultUnitTemplate = require('../src/templates/sample-unit');
7 |
8 | const initCwd = process.cwd();
9 |
10 | function getContent(dir) {
11 | return fs.readFileSync(dir, {encoding: 'utf8'});
12 | }
13 |
14 | function formatComponent(name, comp) {
15 | const data = comp;
16 | const rex = /<%NAME%>/g;
17 | return data.replace(rex, name);
18 | }
19 |
20 | function formatTest(name, unitPath, tmp) {
21 | let data = tmp;
22 | const rexName = /<%NAME%>/g;
23 | const rexPath = /<%PATH%>/g;
24 | data = data.replace(rexName, name);
25 | return data.replace(rexPath, unitPath);
26 | }
27 |
28 | /*
29 | * Since we want to test diffrent config files and config files are
30 | * recognized automatically from root dir, we need to change cwd
31 | * every time. And since config file gets resolved only once when
32 | * you require the module(here ./src module) we need to clear cache of
33 | * require so when we change the directory, the module ./src/config gets
34 | * evaluated again and it recognizes config file in new cwd.
35 | */
36 | function cleanCacheAndChageCwd(dir) {
37 | delete require.cache[require.resolve('../src/config')];
38 | delete require.cache[require.resolve('../src')];
39 | process.chdir(path.resolve(initCwd, dir));
40 | }
41 |
42 | const customVueTemplate = getContent('./templates/myVueTmp.vue');
43 | const customUnitTemplate = getContent('./templates/myUnitTmp.js');
44 |
45 | tap.test('Without dir parameter', t => {
46 | const name = 'firstTest';
47 | const dir = './src/components/firstTest.vue';
48 | const gue = new Gue(name, null, {});
49 | gue.run();
50 | t.plan(1);
51 | t.equal(getContent(dir), formatComponent(name, defaultVueTemplate));
52 | });
53 |
54 | tap.test('With directory parameter', t => {
55 | const name = 'secondTest';
56 | const dir = './somewhere/secondTest.vue';
57 | const gue = new Gue(name, './somewhere', {});
58 | gue.run();
59 | t.plan(1);
60 | t.equal(getContent(dir), formatComponent(name, defaultVueTemplate));
61 | });
62 |
63 | tap.test('With test param and without dir parameter', t => {
64 | const name = 'thirdTest';
65 | const dir = './src/components/thirdTest.vue';
66 | const testDir = './tests/unit/thirdTest.js';
67 | const gue = new Gue(name, null, {unit: true});
68 | gue.run();
69 | t.plan(2);
70 | t.equal(getContent(dir), formatComponent(name, defaultVueTemplate));
71 | t.equal(
72 | getContent(testDir),
73 | formatTest(name, '../../src/components/thirdTest.vue', defaultUnitTemplate)
74 | );
75 | });
76 |
77 | tap.test('With test param and with dir parameter', t => {
78 | const name = 'fourthTest';
79 | const dir = './path-to-nowhere/fourthTest.vue';
80 | const testDir = './tests/unit/fourthTest.js';
81 | const gue = new Gue(name, 'path-to-nowhere', {unit: true});
82 | gue.run();
83 | t.plan(2);
84 | t.equal(getContent(dir), formatComponent(name, defaultVueTemplate));
85 | t.equal(
86 | getContent(testDir),
87 | formatTest(name, '../../path-to-nowhere/fourthTest.vue', defaultUnitTemplate)
88 | );
89 | });
90 |
91 | tap.test('Duplicate', t => {
92 | const name = 'firstTest';
93 | const dir = './src/components/firstTest.vue';
94 | const gue = new Gue(name, null, {});
95 | t.plan(1);
96 | t.false(gue.checkFileStatus(dir, 'component'));
97 | });
98 |
99 | tap.test('Custom component file', t => {
100 | const name = 'fifthTest';
101 | const dir = './src/components/fifthTest.vue';
102 | const gue = new Gue(name, null, {});
103 | gue.componentSource = './templates/myVueTmp.vue';
104 | gue.run();
105 | t.plan(1);
106 | t.equal(getContent(dir), formatComponent(name, customVueTemplate));
107 | });
108 |
109 | tap.test('Custom test file', t => {
110 | const name = 'seventhTest';
111 | const testDir = './tests/unit/seventhTest.js';
112 | const gue = new Gue(name, null, {unit: true});
113 | gue.unitSource = './templates/myUnitTmp.js';
114 | gue.run();
115 | t.plan(1);
116 | t.equal(getContent(testDir), formatTest(name, '../../src/components/seventhTest.vue', customUnitTemplate));
117 | });
118 |
119 | tap.test('Custom root dir for component && custom component file && sub directory', t => {
120 | const name = 'eighthTest';
121 | const dir = './custom-root/subdir/eighthTest.vue';
122 | const gue = new Gue(name, 'subdir', {});
123 | gue.componentRoot = './custom-root';
124 | gue.componentSource = './templates/myVueTmp.vue';
125 | gue.run();
126 | t.plan(1);
127 | t.equal(getContent(dir), formatComponent(name, customVueTemplate));
128 | });
129 |
130 | tap.test('Custom root dir for test && custom test file', t => {
131 | const name = 'ninthTest';
132 | const testDir = './custom-unit-root/ninthTest.js';
133 | const gue = new Gue(name, null, {unit: true});
134 | gue.unitRoot = './custom-unit-root';
135 | gue.unitSource = './templates/myUnitTmp.js';
136 | gue.run();
137 | t.plan(1);
138 | t.equal(getContent(testDir), formatTest(name, '../src/components/ninthTest.vue', customUnitTemplate));
139 | });
140 |
141 | tap.test('Should throw when there is -t but componentSource is not object', t => {
142 | cleanCacheAndChageCwd('./conditions/simple-config');
143 | const Gue = require('../src');
144 | const name = 'tenthTest';
145 | const gue = new Gue(name, null, {template: 'foo'});
146 | t.plan(1);
147 | // TODO: check the exact error
148 | t.throw(() => {
149 | gue.generate();
150 | });
151 | });
152 |
153 | tap.test('Should throw when template name is not in config', t => {
154 | cleanCacheAndChageCwd('./conditions/wrong-template');
155 | const Gue = require('../src');
156 | const name = 'eleventhTest';
157 | const gue = new Gue(name, null, {template: 'foo'});
158 | t.plan(1);
159 | // TODO: check the exact error
160 | t.throw(() => {
161 | gue.generate();
162 | });
163 | });
164 |
165 | tap.test('Should work with multiple templates and choose right one', t => {
166 | cleanCacheAndChageCwd('./conditions/right-template');
167 | const Gue = require('../src');
168 | const name = 'twelvethTest';
169 | // Note that we are now in: ./conditions/right-template
170 | const dir = './src/components/twelvethTest.vue';
171 | const cutomTemplateDir = './right.vue';
172 | const gue = new Gue(name, null, {template: 'right'});
173 | gue.run();
174 | t.plan(1);
175 | t.equal(getContent(dir), formatComponent(name, getContent(cutomTemplateDir)));
176 | });
177 |
178 | tap.test('Should throw when componentSource is object but there is not default template(and -t is not passed of course)', t => {
179 | cleanCacheAndChageCwd('./conditions/right-template');
180 | const Gue = require('../src');
181 | const name = 'foo';
182 | const gue = new Gue(name, null, {});
183 | t.plan(1);
184 | t.throw(() => {
185 | gue.generate();
186 | });
187 | });
188 |
189 | tap.test('Should recognize default template when there is no -t', t => {
190 | cleanCacheAndChageCwd('./conditions/default-template');
191 | const Gue = require('../src');
192 | const name = 'iBlack';
193 | // Note that we are now in: ./conditions/default-template
194 | const dir = './src/components/iBlack.vue';
195 | const cutomTemplateDir = './black.vue';
196 | const gue = new Gue(name, null, {});
197 | gue.run();
198 | t.plan(1);
199 | t.equal(getContent(dir), formatComponent(name, getContent(cutomTemplateDir)));
200 | });
201 |
--------------------------------------------------------------------------------