From 8b44688cf5963982980ade9f33643b3070a39f8f Mon Sep 17 00:00:00 2001 From: Thomas Jaede Date: Thu, 27 Feb 2020 12:12:55 -0800 Subject: [PATCH 1/2] Add template for sample applications --- templates/sample.js | 56 +++++++++ .../sample/__name__.info/sample/.editorconfig | 11 ++ .../sample/__name__.info/sample/.gitignore | 37 ++++++ .../sample/__name__.info/sample/LICENSE.md | 3 + .../sample/__name__.info/sample/README.md | 101 ++++++++++++++++ .../apple-touch-icon-120x120-precomposed.png | Bin 0 -> 23593 bytes .../apple-touch-icon-152x152-precomposed.png | Bin 0 -> 32330 bytes .../apple-touch-icon-76x76-precomposed.png | Bin 0 -> 12854 bytes .../icons/apple-touch-icon-precomposed.png | Bin 0 -> 8546 bytes .../sample/assets/icons/apple-touch-icon.png | Bin 0 -> 8546 bytes .../sample/assets/style/style.css | 16 +++ .../__name__.info/sample/core/.gitignore | 0 .../sample/__name__.info/sample/favicon.ico | Bin 0 -> 32988 bytes .../sample/__name__.info/sample/index.html | 39 ++++++ .../sample/__name__.info/sample/manifest.json | 27 +++++ .../sample/__name__.info/sample/package.json | 13 ++ .../sample/ui/main.reel/main.css | 4 + .../sample/ui/main.reel/main.html | 32 +++++ .../__name__.info/sample/ui/main.reel/main.js | 18 +++ test/templates/sample-spec.js | 112 ++++++++++++++++++ 20 files changed, 469 insertions(+) create mode 100644 templates/sample.js create mode 100644 templates/sample/__name__.info/sample/.editorconfig create mode 100644 templates/sample/__name__.info/sample/.gitignore create mode 100644 templates/sample/__name__.info/sample/LICENSE.md create mode 100644 templates/sample/__name__.info/sample/README.md create mode 100755 templates/sample/__name__.info/sample/assets/icons/apple-touch-icon-120x120-precomposed.png create mode 100755 templates/sample/__name__.info/sample/assets/icons/apple-touch-icon-152x152-precomposed.png create mode 100755 templates/sample/__name__.info/sample/assets/icons/apple-touch-icon-76x76-precomposed.png create mode 100755 templates/sample/__name__.info/sample/assets/icons/apple-touch-icon-precomposed.png create mode 100755 templates/sample/__name__.info/sample/assets/icons/apple-touch-icon.png create mode 100644 templates/sample/__name__.info/sample/assets/style/style.css create mode 100644 templates/sample/__name__.info/sample/core/.gitignore create mode 100644 templates/sample/__name__.info/sample/favicon.ico create mode 100644 templates/sample/__name__.info/sample/index.html create mode 100644 templates/sample/__name__.info/sample/manifest.json create mode 100644 templates/sample/__name__.info/sample/package.json create mode 100644 templates/sample/__name__.info/sample/ui/main.reel/main.css create mode 100644 templates/sample/__name__.info/sample/ui/main.reel/main.html create mode 100644 templates/sample/__name__.info/sample/ui/main.reel/main.js create mode 100644 test/templates/sample-spec.js diff --git a/templates/sample.js b/templates/sample.js new file mode 100644 index 0000000..492a04c --- /dev/null +++ b/templates/sample.js @@ -0,0 +1,56 @@ +var TemplateBase = require("../lib/template-base.js").TemplateBase; +var AppTemplate = require("./app").Template; +var ArgumentError = require("../lib/error.js").ArgumentError; +var path = require('path'); + +var _fromDashesToLowerCamel = function(name) { + var s1 = name.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); + s1 = s1[0].toLowerCase() + s1.slice(1); + return s1; +}; + +var _fromDashesToUpperCamel = function(name) { + var s1 = name.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); + s1 = s1[0].toUpperCase() + s1.slice(1); + return s1; +}; + + +exports.Template = Object.create(AppTemplate, { + + commandDescription: { + value: "sample" + }, + + destination: { + value: "ui" + }, + + didSetOptions: { + value: function (options) { + if (!options.packageName) { + options.packageName = path.basename(options.packageHome); + } + if (!options.relativePackageLocation) { + options.relativePackageLocation = path.relative(options.destination, options.packageHome); + } + if (options.name) { + options.originalName = options.name; + options.componentName = _fromDashesToLowerCamel(options.name); + options.applicationName = _fromDashesToUpperCamel(options.name); + } else { + throw new ArgumentError("Required name option missing"); + } + } + }, + + finish: { + value: function(destination) { + var self = this; + return TemplateBase.finish.call(this).then(function() { + console.log("# "+ self.options.name +".info created and installed with dependency mappings"); + }); + } + }, + +}); diff --git a/templates/sample/__name__.info/sample/.editorconfig b/templates/sample/__name__.info/sample/.editorconfig new file mode 100644 index 0000000..10211c7 --- /dev/null +++ b/templates/sample/__name__.info/sample/.editorconfig @@ -0,0 +1,11 @@ +# http://EditorConfig.org + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/templates/sample/__name__.info/sample/.gitignore b/templates/sample/__name__.info/sample/.gitignore new file mode 100644 index 0000000..ea9322c --- /dev/null +++ b/templates/sample/__name__.info/sample/.gitignore @@ -0,0 +1,37 @@ +### General ### +.DS_Store +Thumbs.db +report/ +out/ +temp/ +tmp/ +.tmp +*.tmp +*.tmp.* +log.txt +*.log + +## jsdoc +/doc + +### SublimeText ### +*.sublime-project +*.sublime-workspace + +### Intellij IDE ### +.idea/ +atlassian-ide-plugin.xml + +### VisualStudioCode ### +.vscode/* +.vscode-upload.json + +### TextMate ### +*.tmproj +*.tmproject +tmtags + +### Node ### +npm-debug.log* +.npmignore +node_modules/ \ No newline at end of file diff --git a/templates/sample/__name__.info/sample/LICENSE.md b/templates/sample/__name__.info/sample/LICENSE.md new file mode 100644 index 0000000..e803512 --- /dev/null +++ b/templates/sample/__name__.info/sample/LICENSE.md @@ -0,0 +1,3 @@ +{{#copyright}} +{{{copyright}}} +{{/copyright}} diff --git a/templates/sample/__name__.info/sample/README.md b/templates/sample/__name__.info/sample/README.md new file mode 100644 index 0000000..94f93ac --- /dev/null +++ b/templates/sample/__name__.info/sample/README.md @@ -0,0 +1,101 @@ + +This readme file provides a brief overview of the file and folder structure +included in the default MontageJS project directory. + +>IMPORTANT: Be sure to replace the contents of this readme file with information +about the final application before deploying the application or passing it on to +a client. + +Project Directory +============ + +The default project directory includes the following files and folders: + +* assets/ - Contains global stylesheets and images for the application. +* index.html - Is the entry-point document for the application. +* node_modules/ - Contains the code dependencies required in development. + + Includes Montage, the core framework, and Digit, a mobile-optimized user + interface widget set by default. Since MontageJS uses the CommonJS module + system, you can leverage the npm ecosystem for additional modules. To add + dependencies (e.g., foo), use `npm install foo` in the project directory. + + NOTE: All packages in this directory must be included as dependencies + in package.json. + +* package.json - Describes the application and the dependencies included in + the node_modules directory. +* README.md - The default readme file. +* run-tests.html - Is a page to run Jasmine tests manually in the browser. +* test/ - Contains tests for the application. + + By default, this directory includes all.js, a module that points the test runner + to all jasmine specs. + +* ui/ - Contains the application user interface components. + + By default, this directory contains two components: main.reel (the Main + user interface component) and version.reel (which displays the current + MontageJS version). + +* core/ - Contains the core modules of the application logic. + +In development, you can expand this project directory as necessary; for example, +depending on the project you may want to add the following folders: + +* locale/ - For localized content. +* scripts/ - For JS libraries that do not support the CommonJS exports object + and, therefore, have to be loaded using a ` + + + + + + diff --git a/templates/sample/__name__.info/sample/manifest.json b/templates/sample/__name__.info/sample/manifest.json new file mode 100644 index 0000000..d1c1fe4 --- /dev/null +++ b/templates/sample/__name__.info/sample/manifest.json @@ -0,0 +1,27 @@ +{ + "lang": "en", + "name": "{{name}}", + "short_name": "{{name}}", + "description": "{{description}}", + "start_url": "./?utm_source=homescreen", + "icons": [ + { + "src": "./assets/icons/apple-touch-icon-120x120-precomposed.png", + "sizes": "120x120", + "type": "image/png" + }, + { + "src": "./assets/icons/apple-touch-icon-152x152-precomposed.png", + "sizes": "152x152", + "type": "image/png" + }, + { + "src": "./assets/icons/apple-touch-icon-76x76-precomposed.png", + "sizes": "76x76", + "type": "image/png" + } + ], + "theme_color": "#000", + "background_color": "#fff", + "display": "standalone" +} \ No newline at end of file diff --git a/templates/sample/__name__.info/sample/package.json b/templates/sample/__name__.info/sample/package.json new file mode 100644 index 0000000..aa75f33 --- /dev/null +++ b/templates/sample/__name__.info/sample/package.json @@ -0,0 +1,13 @@ +{ + "name": "{{name}}-sample", + "version": "0.1.0", + "description": "{{description}}", + "mappings": { + "montage": "{{relativePackageLocation}}/../../node_modules/montage", + "{{packageName}}": "{{relativePackageLocation}}/../../" + }, + "exclude": [ + "run-tests.html", + "test" + ] +} diff --git a/templates/sample/__name__.info/sample/ui/main.reel/main.css b/templates/sample/__name__.info/sample/ui/main.reel/main.css new file mode 100644 index 0000000..56edcb7 --- /dev/null +++ b/templates/sample/__name__.info/sample/ui/main.reel/main.css @@ -0,0 +1,4 @@ +{{#copyright}}/* {{{copyright}}} */ + +{{/copyright}} +.Main {} diff --git a/templates/sample/__name__.info/sample/ui/main.reel/main.html b/templates/sample/__name__.info/sample/ui/main.reel/main.html new file mode 100644 index 0000000..b3dcd5b --- /dev/null +++ b/templates/sample/__name__.info/sample/ui/main.reel/main.html @@ -0,0 +1,32 @@ + +{{#copyright}} +{{/copyright}} + + + + Main + + + + + +
+
+
+ + diff --git a/templates/sample/__name__.info/sample/ui/main.reel/main.js b/templates/sample/__name__.info/sample/ui/main.reel/main.js new file mode 100644 index 0000000..8482033 --- /dev/null +++ b/templates/sample/__name__.info/sample/ui/main.reel/main.js @@ -0,0 +1,18 @@ +{{#copyright}}/* {{{copyright}}} */ + +{{/copyright}}/** + * @module ui/main.reel + */ +var Component = require("montage/ui/component").Component; + +/** + * @class Main + * @extends Component + */ +exports.Main = Component.specialize(/** @lends Main# */ { + constructor: { + value: function Main() { + this.super(); + } + } +}); diff --git a/test/templates/sample-spec.js b/test/templates/sample-spec.js new file mode 100644 index 0000000..d6edc89 --- /dev/null +++ b/test/templates/sample-spec.js @@ -0,0 +1,112 @@ +/*global describe,beforeEach,it,expect */ + +var SandboxedModule = require('sandboxed-module'); +var Command = require("commander").Command; + +describe("sample template", function () { + var testCommand; + var Template; + beforeEach(function() { + + Template = SandboxedModule.require('../../templates/app', { + requires: { + '../lib/template-base': { + TemplateBase: { + addOptions: function(command) { + return command; + } + } + } + } + }).Template; + + testCommand = new Command(); + + }); + + it("should have a commandDescription defined on prototype", function () { + expect(Template.commandDescription).toBeDefined(); + }); + + it("should return the command from addOptions", function () { + expect(Object.create(Template).addOptions(testCommand)).toBe(testCommand); + }); + + describe("command", function () { + + it("should have --name option", function () { + var command = Object.create(Template).addOptions(testCommand); + + expect(command.optionFor("-n")).toBeDefined(); + expect(command.optionFor("--name")).toBeDefined(); + }); + + it("should have --copyright option", function () { + var command = Object.create(Template).addOptions(testCommand); + + expect(command.optionFor("-c")).toBeDefined(); + expect(command.optionFor("--copyright")).toBeDefined(); + }); + + }); + describe("option validation", function () { + var template; + var options; + beforeEach(function () { + template = Object.create(Template); + options = {}; + }); + it("should throw an error when no name given", function () { + expect(function () { + template.didSetOptions(options); + }).toThrow("Required name option missing"); + }); + it("should accept name with dashes", function () { + options.name = "my-app"; + template.didSetOptions(options); + expect(options.name).toEqual("my-app"); + }); + it("should accept name with spaces", function () { + options.name = "my app"; + template.didSetOptions(options); + expect(options.name).toEqual("my-app"); + }); + it("should accept camelCased name", function () { + options.name = "MyApp"; + template.didSetOptions(options); + expect(options.name).toEqual("my-app"); + }); + it("should accept camelCased name", function () { + options.name = "MyApp"; + template.didSetOptions(options); + expect(options.name).toEqual("my-app"); + }); + it("should convert spaces to dashes in names", function () { + options.name = "My App"; + template.didSetOptions(options); + expect(options.name).toEqual("my-app"); + }); + it("should convert multiple spaces to dashes in names", function () { + options.name = "My App Has Spaces"; + template.didSetOptions(options); + expect(options.name).toEqual("my-app-has-spaces"); + }); + // by converting accented characters to ascii equivalents in names + it("should respect NPM package name conventions (râțéăü -> rateau)", function () { + options.name = "râțéăü"; + template.didSetOptions(options); + expect(options.name).toEqual("rateau"); + }); + it("should generate description", function () { + options.name = "MyApp"; + template.didSetOptions(options); + expect(options.desc).toEqual("MyApp Application"); + }); + it("should generate description", function () { + options.name = "MyApp"; + options.desc = "Test description"; + template.didSetOptions(options); + expect(options.desc).toEqual("Test description"); + }); + }); +}); From 3edfadc438d9bf83276b586fcd476ebba94e1db1 Mon Sep 17 00:00:00 2001 From: Thomas Jaede Date: Thu, 27 Feb 2020 15:18:26 -0800 Subject: [PATCH 2/2] Remove exclude from package.json --- templates/sample/__name__.info/sample/package.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/templates/sample/__name__.info/sample/package.json b/templates/sample/__name__.info/sample/package.json index aa75f33..83a2093 100644 --- a/templates/sample/__name__.info/sample/package.json +++ b/templates/sample/__name__.info/sample/package.json @@ -5,9 +5,5 @@ "mappings": { "montage": "{{relativePackageLocation}}/../../node_modules/montage", "{{packageName}}": "{{relativePackageLocation}}/../../" - }, - "exclude": [ - "run-tests.html", - "test" - ] + } }