Skip to content

Commit

Permalink
Create CLI build/test tool, add initial unit tests
Browse files Browse the repository at this point in the history
This CLI tool affords the following advantages:

- More consolidated and controlled build process, using a build config
  JSON file and CLI flags, and keeping all build pipeline logic in one
  place

  This is better than separate Gulp and Webpack config files. Gulp file
  copying often resulted in phantom empty files being copied; this is
  more easily controlled using plain Node code instead of fitting in
  Gulp.

- Use the latest ECMAScript features like async/await without
  transpiling them, which significantly enhances debugging productivity
  on Chrome compared to debugging down-emitted async/await generators

- Stop the build pipeline right after the TypeScript transpiler
  processes the original source files

  For testing, we can skip module bundling and UglifyJS processing for
  faster unit test build times. Our unit tests can also import
  individual source files without requiring the entire SDK to be built
  as a bundle, for truer unit tests.

- Guided build process

- Better compatibility with JavaScript ecosystem

  Having tried other module bundlers like Brunch, Webpack v1, and Gulp,
  each module bundler falls short in some ways.

    - Much of the JavaScript ecosystem isn't friendly to ES2017 features
      like async/await

      - Brunch does not understand ES2016+ features and would not bundle
        async/await code. My locally built SDK would have be transpiled
        to ES6, which was impossible to debug in the browser due to the
        downemitted async functions

    - Less maintained large module bundlers have bugs with undesirable
      workarounds

       - Brunch plugin order depended on the order of dependencies in
         package.json, which would be reset everytime the Yarn package
         manager was run

Other changes:

- Styling has been removed from the web SDK and placed into a separate
  OneSignalSDKStyles.css file

- Add initial pilot unit tests for setDefaultNotificationUrl, setDefaultTitle,
  ensureSdkStylesLoaded, and IndexedDb

- Refactor/rewrite IndexedDb as a more modular instance class

  Testing was difficult when most SDK state was stored in the same
  IndexedDb database. Instantiating a separate IndexedDb database for
  each unit test is a better solution.
  • Loading branch information
Jason Pang committed Mar 14, 2017
1 parent 5518ed7 commit d126f7c
Show file tree
Hide file tree
Showing 93 changed files with 5,705 additions and 7,143 deletions.
3 changes: 0 additions & 3 deletions .babelrc

This file was deleted.

6 changes: 5 additions & 1 deletion .gitignore
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
.idea/
node_modules/
bower_components/
dist/
build/
/config.json

.DS_STORE
*.pem
dist/
yarn-error.log
3 changes: 3 additions & 0 deletions .yarnclean
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@ Gruntfile.js
# misc
*.gz
*.md

# Ignore svgo-loader
!.svgo.yml
7 changes: 4 additions & 3 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

object-assign pollyfill (MIT License) Copyright © 2015 Sindre Sorhus (https://github.com/sindresorhus/object-assign)
swivel (MIT License) Copyright © 2015 Nicolas Bevacqua (https://github.com/bevacqua/swivel)
postmessage-plus (MIT License) Copyright © 2015 Taylor Hakes (https://github.com/taylorhakes/postmessage-plus)
object-assign pollyfill (MIT License) Copyright © Sindre Sorhus (https://github.com/sindresorhus/object-assign)
swivel (MIT License) Copyright © Nicolas Bevacqua (https://github.com/bevacqua/swivel)
postmessage-plus (MIT License) Copyright © Taylor Hakes (https://github.com/taylorhakes/postmessage-plus)
emitter-es6 (MIT License) Copyright © Guille Paz (https://github.com/pazguille/emitter-es6)
148 changes: 148 additions & 0 deletions brunch-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
var {
bundlerOutDir,
stylesheetsSrcDir,
stylesheetsBundleName,
typescriptOutDir,
sdkBundleName,
integrationTestsBundleName,
unitTestsBundleName,
isTesting
} = process.env;

const path = require('path');
const fs = require('fs');

var entryPoints = {};

entryPoints[`${typescriptOutDir}/src/entry.js`] = sdkBundleName;

var autoRequire = {};
autoRequire[sdkBundleName] = [`${typescriptOutDir}/src/entry`];

module.exports = {
paths: {
// Build directory output path
public: bundlerOutDir,
// Paths watched by brunch
watched: [typescriptOutDir, stylesheetsSrcDir]
},
files: {
javascripts: {
entryPoints: entryPoints
},
stylesheets: {
joinTo: stylesheetsBundleName
}
},
modules: {
autoRequire: autoRequire
},
/**
* WARNING: For now, Brunch pipeline execution order is defined by the brunch plugins in the package.
*
* This means that, for example, sass-brunch in package.json should come before uglify-js.
*/
plugins: {
on: [
'javascript-brunch',
'sass-brunch',
'jscc-brunch',
'clean-css-brunch',
'uglify-js-brunch'
],
/**
* Replaces $_VAR preprocessor variables for things like $_VERSION and $_DEV.
*
* Source map generation not necessary because we're just replacing very few strings.
*/
jscc: {
/**
* Only pre-process the final bundle.js (one large file vs. many smaller files).
*/
values: {
_DEV: false,
_TEST: false,
_STAGING: false,
_IS_ES6: false,
_VERSION: JSON.stringify(require("./package.json").sdkVersion),
}
},
cleancss: {
keepSpecialComments: 0,
removeEmpty: true
},
uglify: {
sourceMap: true,
compress: {
sequences: true,
properties: true,
dead_code: true,
conditionals: true,
comparisons: true,
evaluate: true,
booleans: true,
loops: true,
unused: true,
hoist_funs: true,
if_return: true,
join_vars: true,
cascade: true,
collapse_vars: true,
drop_console: false,
drop_debugger: false,
warnings: false,
negate_iife: true,
},
mangle: {
enable: true,
except: [
'AlreadySubscribedError',
'InvalidArgumentError',
'InvalidStateError',
'InvalidUuidError',
'NotSubscribedError',
'PermissionMessageDismissedError',
'PushNotSupportedError',
'PushPermissionNotGrantedError'
]
},
output: {
comments: false
}
}
},
overrides: {
development: {
plugins: {
jscc: {
values: {
_DEV: true
}
},
off: ['uglify-js-brunch']
}
},
test: {
plugins: {
jscc: {
values: {
_TEST: true
}
}
}
},
staging: {
plugins: {
jscc: {
values: {
_STAGING: true
}
}
}
},
production: {
optimize: true,
sourceMaps: true
}
}
};
38 changes: 0 additions & 38 deletions config.example.json

This file was deleted.

24 changes: 0 additions & 24 deletions config.json

This file was deleted.

61 changes: 61 additions & 0 deletions config.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
Purpose: Configuration file for OneSignal web SDK build process and tests runner

Description:

The tests execute in a browser environment, but a NodeJS test server runs side by side to facilitate database access
and perform other commands (e.g. possibly mouse clicks in the future) that would not be possible inside of a
browser's sandbox environment.

This configuration file is first requested before the tests begin running.
*/
{
build: {
/*
The intermediate build folder.

WARNING: Silently removed on each build !!!
*/
tempDirectory: "build",
/**
* The directory to output the transpiled TypeScript files to. Overrides tsconfig.json.
*/
typescriptOutDir: "build/javascript",
bundlerOutDir: "build/bundler",
/**
The directory containing all stylesheets that will be watched for changes and bundled together (and minified).
*/
stylesheetsSrcDir: "src/stylesheets",
stylesheetsBundleName: 'OneSignalSDKStyles.css',
/**
The filename of the intermediate bundle. Does not affect the final bundle name because the final bundle name is
always <ENVIRONMENT>-OneSignalSDK.js, except production which is just OneSignalSDK.js.
*/
sdkBundleName: 'OneSignalSDK.js',
integrationTestsBundleName: 'integration-tests.js',
unitTestsBundleName: 'unit-tests.js',
railsProjectRoot: "/home/jpang/code/OneSignal"
},
test: {
server: {
rails_host_http: "localhost:3000",
rails_host_https: "localhost:3001",
// The host to OneSignal's database that contains the HTTP and HTTPS apps for testing
database_host: "localhost:5432",
database_user: "postgres",
database_pass: "",
master_database: "gamethrive_00",
shard_1_database: "gamethrive_80",
},
tests: {
rails_host_http: "ubuntu:3000",
rails_host_https: "ubuntu:3001",
// OneSignal user auth key to create, delete, and list apps
user_auth_key: "NjZmZDM5YmQtNjRiMS00MTk5LTkwY2UtMGRiYTgzNzM2NGM0",
},
chrome_extension: {
// The Chrome extension ID, which stays consistent due to our setting the key property of the extension's manifest.json
extension_id: "engiogdknecmkikekehomfbhnneekmng"
}
}
}
6 changes: 0 additions & 6 deletions gulpfile.babel.future.js

This file was deleted.

Loading

0 comments on commit d126f7c

Please sign in to comment.