From d7456cc0ea0805a6f0745a899b3abbdd1d7da492 Mon Sep 17 00:00:00 2001 From: Duncan Paterson Date: Tue, 9 Feb 2021 17:01:01 +0100 Subject: [PATCH] chore(test): 2 new test apps for pure gulp fix logic of builder generation for hybrid files make ant call conditional at end see #563 --- generators/app/index.js | 79 ++++++++---- generators/app/templates/builder/gulpfile.js | 115 ++++++++---------- .../{app-empty.js => app-empty-hybrid.js} | 8 +- test/generated-pkg/app-gulp-pure.js | 66 ++++++++++ test/generated-pkg/lib-gulp-pure.js | 79 ++++++++++++ 5 files changed, 253 insertions(+), 94 deletions(-) rename test/generated-pkg/{app-empty.js => app-empty-hybrid.js} (93%) create mode 100644 test/generated-pkg/app-gulp-pure.js create mode 100644 test/generated-pkg/lib-gulp-pure.js diff --git a/generators/app/index.js b/generators/app/index.js index 3adb42dae..f49a4ec96 100644 --- a/generators/app/index.js +++ b/generators/app/index.js @@ -121,7 +121,7 @@ module.exports = class extends Generator { default: 'SNAPSHOT' }, { - type: 'checkbox', + type: 'list', choices: ['ant', 'gulp', 'hybrid'], name: 'builder', message: 'How would you like to build your app?', @@ -324,9 +324,6 @@ module.exports = class extends Generator { store: true }] - // TODO: [yo]: js, css, gulp, funcdoc, - // TODO: TODO: [gulp] line-o we could also extend this module https://github.com/bnjjj/generator-gulpfile-advanced - return this.prompt(prompts).then(props => { // To access props later use this.props.someAnswer; this.props = props @@ -349,7 +346,7 @@ module.exports = class extends Generator { // try to clean invalid xml from streams this.registerTransformStream( stripBom({ - ext: ['xml', 'odd', 'xconf'], + ext: ['xml', 'odd', 'xconf', 'xhtml'], showLog: false })) // minify xml first … @@ -629,6 +626,33 @@ module.exports = class extends Generator { // Prompt based // Builder + // if (this.props.builder !== 'gulp') { + // this.fs.copyTpl( + // this.templatePath('builder/build.xml'), + // this.destinationPath('build.xml'), { + // apptype: this.props.apptype[0], + // builder: this.props.builder, + // desc: this.props.desc, + // docker: this.props.docker, + // dockerfiles: ', Dockerfile, .dockerignore', + // github: this.props.github, + // gitfiles: ', README.md, **/.git*/**', + // title: this.props.title + // }) + // } + + // if (this.props.builder === 'gulp') { + // this.fs.copy( + // this.templatePath('builder/gulpfile.js'), + // this.destinationPath('gulpfile.js') + // ) + // this.npmInstall(['@existdb/gulp-exist', '@existdb/gulp-replace-tmpl', 'del', 'gulp', 'gulp-autoprefixer', 'gulp-concat', 'gulp-cssnano', 'gulp-flatmap', 'gulp-header', 'gulp-muxml', 'gulp-rename', 'gulp-sass', 'gulp-sourcemaps', 'gulp-svgmin', 'gulp-uglify', 'gulp-zip', 'lazypipe'], { 'save-dev': true }) + // Object.assign(pkgJson.scripts, { + // build: 'gulp build', + // deploy: 'gulp install' + // }) + // } + if (this.props.builder !== 'gulp') { this.fs.copyTpl( this.templatePath('builder/build.xml'), @@ -643,25 +667,20 @@ module.exports = class extends Generator { title: this.props.title }) } - - switch (this.props.builder) { - case 'ant': - break - case 'gulp': - this.fs.copyTpl( - this.templatePath('builder/gulpfile.js'), - this.destinationPath('gulpfile.js'), { - apptype: this.props.apptype[1] - } - ) - this.npmInstall(['@existdb/gulp-exist', '@existdb/gulp-replace-tmpl', 'del', 'gulp', 'gulp-autoprefixer', 'gulp-concat', 'gulp-cssnano', 'gulp-flatmap', 'gulp-header', 'gulp-muxml', 'gulp-rename', 'gulp-sass', 'gulp-sourcemaps', 'gulp-svgmin', 'gulp-uglify', 'gulp-zip', 'lazypipe'], { 'save-dev': true }) - Object.assign(pkgJson.scripts, { - build: 'gulp build', - deploy: 'gulp install' - }) - break - default: + if (this.props.builder !== 'ant') { + this.fs.copyTpl( + this.templatePath('builder/gulpfile.js'), + this.destinationPath('gulpfile.js'), { + apptype: this.props.apptype[1] + } + ) + this.npmInstall(['@existdb/gulp-exist', '@existdb/gulp-replace-tmpl', 'del', 'gulp', 'gulp-autoprefixer', 'gulp-concat', 'gulp-cssnano', 'gulp-flatmap', 'gulp-header', 'gulp-muxml', 'gulp-rename', 'gulp-sass', 'gulp-sourcemaps', 'gulp-svgmin', 'gulp-uglify', 'gulp-zip', 'lazypipe'], { 'save-dev': true }) + Object.assign(pkgJson.scripts, { + build: 'gulp build', + deploy: 'gulp install' + }) } + // Pre-install if (this.props.pre) { this.fs.copyTpl( @@ -824,16 +843,22 @@ module.exports = class extends Generator { } end () { - // TODO insert new project layout here? - // #513 could even run cypress here after calling npm i + // TODO insert new project layout here? + // #513 could even run cypress here after calling npm i if (this.props.github) { this.spawnCommandSync('git', ['init']) this.spawnCommandSync('git', ['add', '--all']) this.spawnCommandSync('git', ['commit', '-q', '-m', '\'chore(init): scaffolding by Yeoman\'']) } - // TODO: [gulp] line-o make conditional on selected build tool - this.spawnCommandSync('ant', '-q') + + switch (this.props.builder) { + case 'gulp': + this.spawnCommandSync('gulp') + break + default: + this.spawnCommandSync('ant', '-q') + } console.log(yosay('I believe we\'re done here.')) } diff --git a/generators/app/templates/builder/gulpfile.js b/generators/app/templates/builder/gulpfile.js index 781e25362..53ff996b8 100644 --- a/generators/app/templates/builder/gulpfile.js +++ b/generators/app/templates/builder/gulpfile.js @@ -38,27 +38,16 @@ const paths = { input: 'src/main/img/*.svg', output: 'dist/xar/resources/images/' }, + vendor: { + input: 'node_modules/' + }, + static: { + input: 'src/main/**/*.{html,xq,xquery,xql,xqm}' + } } -// TODO: Hybrid (no src) stick with old layout -// Hybrid -// const paths = { -// input: 'src/main/', -// output: 'dist/xar/', -// scripts: { -// input: 'src/main/js/*', -// // polyfills: '.polyfill.js', -// output: 'dist/xar/resources/scripts/' -// }, -// styles: { -// input: 'src/main/styles/sass/*.{scss,sass}', -// output: 'dist/xar/resources/styles/' -// }, -// svgs: { -// input: 'src/main/img/*.svg', -// output: 'dist/xar/resources/images/' -// }, -// } +// TODO: flexible switch for hybrid (no src) stick with old project layout + /** * Gulp Packages @@ -113,10 +102,10 @@ const serverInfo = existJSON.servers.localhost const target = serverInfo.root const connectionOptions = { - basic_auth: { - user: serverInfo.user, - pass: serverInfo.password - } + basic_auth: { + user: serverInfo.user, + pass: serverInfo.password + } } const existClient = createClient(connectionOptions); @@ -126,7 +115,6 @@ const packageName = () => `${existJSON.package.target}-${pkg.version}.xar` // - xml / xconf / odd should be prettied // - html should be... // - xq / xsl ... ? -const static = 'src/**/*.{xml,html,xq,xquery,xql,xqm,xsl,xconf}' @@ -157,7 +145,7 @@ function watchTemplates() { exports["watch:tmpl"] = watchTemplates /** - * compile SCSS styles and put them into 'build/app/css' + * compile SCSS styles and output css */ function styles() { return src(paths.styles.input) @@ -190,7 +178,7 @@ function watchStyles() { exports["watch:styles"] = watchStyles /** -* minify EcmaSript files and put them into 'build/app/js' +* minify EcmaSript files and put them into output dir */ function minifyEs() { return src(paths.scripts.input) @@ -204,56 +192,61 @@ function watchEs() { } exports["watch:es"] = watchEs -/** - * compile SCSS styles and put them into 'build/app/css' - */ -function styles() { - return src(paths.styles.input) - .pipe(sass().on('error', sass.logError)) - .pipe(dest(paths.styles.output)); -} -exports.styles = styles - -function watchStyles() { - watch(paths.styles.input, series(styles)) -} -exports["watch:styles"] = watchStyles /** -* minify EcmaSript files and put them into 'build/app/js' +* copy html templates, XSL stylesheet, XMLs and XQueries to 'build' */ -function minifyEs() { - return src(paths.scripts.input) - .pipe(uglify()) - .pipe(dest(paths.styles.output)) +function copyStatic() { + return src(paths.static.input).pipe(dest(paths.output)) } -exports.minify = minifyEs +exports.copy = parallel(copyXml, copyVendor, copyStatic) -function watchEs() { - watch(paths.scripts.input, series(minifyEs)) +function watchStatic() { + watch(paths.static.input, series(copyStatic, copyXML, copyVendor)); +} +exports["watch:static"] = watchStatic + +function copyXml() { + return src(paths.input + '**/*.{odd,xq,xquery,xql,xqm,xml,xhtml,xconf,xsl}') + .pipe(muxml({ + stripComments: false, + stripCdata: false, + stripInstruction: false, + saxOptions: { + trim: true, + normalize: true + } + })) + .pipe(dest(paths.output)) } -exports["watch:es"] = watchEs +// TODO #36 flexible /** -* copy html templates, XSL stylesheet, XMLs and XQueries to 'build' +* copy vendored scripts and style into output */ - -// TODO add xml prettiprinting, css nano, etc from docs. probably split into multiple tasks -function copyStatic() { - return src(static).pipe(dest(paths.output)) +<%_ if (apptype !== 'empty') { %> +function copyVendorES() { + return src([paths.vendor.input + 'bootstrap/dist/js/bootstrap.min.*', paths.vendor.input + 'jquery/dist/jquery.min.*']).pipe(dest(paths.scripts.output)) } -exports.copy = copyStatic -function watchStatic() { - watch(static, series(copyStatic)); +function copyVendorStyle() { + return src(paths.vendor.input + 'bootstrap/dist/css/bootstrap.min.*').pipe(dest(paths.styles.output)) } -exports["watch:static"] = watchStatic +exports.copyVendor = parallel(copyVendorES, copyVendorStyle) +function watchVendor() { + watch(paths.vendor.input, series(copyVendorES, copyVendorStyle)) +} +exports["watch:vendor"] = watchVendor +<% } -%> /** * Upload all files in the build folder to existdb. * This function will only upload what was changed * since the last run (see gulp documentation for lastRun). */ + + // Todo: # 563 conditional library package tasks go here + function deploy() { return src(paths.output + '**/*', { base: paths.output, @@ -296,6 +289,7 @@ const watchAll = parallel( watchEs, watchStatic, watchTemplates, + watchVendor, watchBuild ) @@ -308,8 +302,3 @@ exports.install = series(build, xar, installXar) // main task for day to day development exports.default = series(build, deploy, watchAll) - - -// Todo: conditional library package tasks go here - -// \ No newline at end of file diff --git a/test/generated-pkg/app-empty.js b/test/generated-pkg/app-empty-hybrid.js similarity index 93% rename from test/generated-pkg/app-empty.js rename to test/generated-pkg/app-empty-hybrid.js index f176d70cd..31715a955 100644 --- a/test/generated-pkg/app-empty.js +++ b/test/generated-pkg/app-empty-hybrid.js @@ -6,7 +6,7 @@ const fs = require('fs-extra') describe('empty package', function () { this.timeout(15000) - // TODO: #563 [gulp] line-o let's make this the test application for pure gulp build + // TODO: #563 [gulp] line-o let's make this the test application for gulp hibryd build // We should also add a app-lib-gulp.js test package. before(async function () { await helpers.run(path.join(__dirname, '../../generators/app')) @@ -18,16 +18,16 @@ describe('empty package', function () { pre: false, post: false, license: ['MIT', 'MIT', 'https://opensource.org/licenses/MIT'], - builder: 'gulp', + builder: 'hybrid', github: false, atom: false }) - assert.noFile(['modules/app.xql', 'templates/page.html', 'test/cypress/integration/login-ok_spec.js', 'index.html', 'build.xml']) + assert.noFile(['modules/app.xql', 'templates/page.html', 'test/cypress/integration/login-ok_spec.js', 'index.html']) }) describe('empty has', function () { it('recommended files', function (done) { - assert.file(['repo.xml', 'test/mocha/app_spec.js', 'test/xqs/test-runner.xq', 'gulpfile.js']) + assert.file(['repo.xml', 'test/mocha/app_spec.js', 'test/xqs/test-runner.xq', 'gulpfile.js', 'build.xml']) done() }) diff --git a/test/generated-pkg/app-gulp-pure.js b/test/generated-pkg/app-gulp-pure.js new file mode 100644 index 000000000..3df8d6e72 --- /dev/null +++ b/test/generated-pkg/app-gulp-pure.js @@ -0,0 +1,66 @@ +'use strict' +const path = require('path') +const assert = require('yeoman-assert') +const helpers = require('yeoman-test') +const fs = require('fs-extra') + +describe('pure gulp app', function () { + before(async function () { + this.timeout(10000) + await helpers.run(path.join(__dirname, '../../generators/app')) + .withPrompts({ + title: 'foo', + author: 'tester', + email: 'te@st.er', + apptype: ['plain', 'application'], + pre: true, + post: true, + license: ['MIT', 'MIT', 'https://opensource.org/licenses/MIT'], + setperm: false, + builder: 'gulp', + github: false, + ci: 'GitHub Action', + docker: true, + atom: true, + instance: 'http://localhost:8080/exist', + admin: 'admin', + adminpw: 'pw123' + }) + assert.noFile('build.xml') + }) + + describe('gulp app has', function () { + it('recommended files', function (done) { + assert.file(['expath-pkg.xml', 'gulpfile.js']) + done() + }) + + it('atom file with proper uri', function (done) { + assert.fileContent('.existdb.json', 'http://localhost:8080/exist') + done() + }) + + it.skip('working build config', function (done) { + assert.fileContent(['gulpfile.js', 'dist/xar/resources/scripts/']) + done() + }) + + + }) + describe.skip('markup files are well-formed', function () { + return require('../util/app').checkWellFormed() + }) + + describe.skip('app meta-data', function () { + return require('../util/consistency').isConsistent() + }) + + describe.skip('test_suite has …', function () { + return require('../util/meta-test').metaTest() + }) + + after('teardown', function (done) { + fs.emptyDirSync(process.cwd()) + done() + }) +}) diff --git a/test/generated-pkg/lib-gulp-pure.js b/test/generated-pkg/lib-gulp-pure.js new file mode 100644 index 000000000..261551365 --- /dev/null +++ b/test/generated-pkg/lib-gulp-pure.js @@ -0,0 +1,79 @@ +'use strict' +const path = require('path') +const assert = require('yeoman-assert') +const helpers = require('yeoman-test') +const fs = require('fs-extra') + +describe.skip('pure gulp app', function () { + before(async function () { + this.timeout(10000) + await helpers.run(path.join(__dirname, '../../generators/app')) + .withPrompts({ + title: 'foo', + author: 'tester', + email: 'te@st.er', + apptype: ['plain', 'application'], + pre: true, + post: true, + license: ['MIT', 'MIT', 'https://opensource.org/licenses/MIT'], + setperm: false, + builder: 'gulp', + github: false, + ci: 'GitHub Action', + docker: false, + atom: true, + instance: 'http://localhost:8080/exist', + admin: 'admin', + adminpw: 'pw123' + }) + assert.noFile(['build.xml']) + }) + + describe('gulp app has', function () { + it('recommended files', function (done) { + assert.file(['expath-pkg.xml', 'gulfile.js']) + done() + }) + + it('atom file with proper uri', function (done) { + assert.fileContent('.existdb.json', 'http://localhost:8080/exist') + done() + }) + + it('atom file with clearly visible PW', function (done) { + assert.fileContent('.existdb.json', 'pw123') + done() + }) + + it('dockerfile with expanded package name', function (done) { + assert.fileContent('Dockerfile', 'foo-1.0.0.xar') + done() + }) + + it('GitHub Action Workflow', function (done) { + assert.fileContent('.github/workflows/exist.yml', 'cypress') + done() + }) + + it('expanded title on index.html', function (done) { + assert.fileContent('templates/page.html', 'foo') + done() + }) + }) + describe('markup files are well-formed', function () { + return require('../util/app').checkWellFormed() + }) + + describe('app meta-data', function () { + return require('../util/consistency').isConsistent() + }) + + describe('test_suite has …', function () { + return require('../util/meta-test').metaTest() + }) + + after('teardown', function (done) { + fs.emptyDirSync(process.cwd()) + done() + }) +})