From e1bba7878490e0c591ab19de0a58301755f95310 Mon Sep 17 00:00:00 2001 From: Alexander Vakrilov Date: Thu, 6 Jul 2017 16:17:53 +0300 Subject: [PATCH] Add CONTRIBUTING.md and update guides (#4511) * Removing legacy files * Dev-setup * CodeConventions revised * CONTRIBUTING.md first draft * Update CreateNewModule.md * Module exapmles * Writing unit tests article * Minor Changes * Organize PR steps --- .github/CONTRIBUTING.md | 151 --- CONTRIBUTING.md | 78 ++ CodingConvention.md | 581 +++------ CreateNewModule.md | 129 +- CrossPlatformModules.csproj | 2328 ----------------------------------- CrossPlatformModules.sln | 31 - DebugV8Heap.md | 23 - DevelopmentWorkflow.md | 70 +- Introduction.md | 51 - README.md | 10 +- RunTests.md | 22 - WritingUnitTests.md | 84 ++ running-tests.md | 59 - source-control.md | 158 --- 14 files changed, 455 insertions(+), 3320 deletions(-) delete mode 100644 .github/CONTRIBUTING.md create mode 100644 CONTRIBUTING.md delete mode 100644 CrossPlatformModules.csproj delete mode 100644 CrossPlatformModules.sln delete mode 100644 DebugV8Heap.md delete mode 100644 Introduction.md delete mode 100644 RunTests.md create mode 100644 WritingUnitTests.md delete mode 100644 running-tests.md delete mode 100644 source-control.md diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md deleted file mode 100644 index 7e171a2ca..000000000 --- a/.github/CONTRIBUTING.md +++ /dev/null @@ -1,151 +0,0 @@ -# Contributing to NativeScript - -## Before You Start - -Anyone wishing to contribute to the NativeScript project MUST read & sign the [NativeScript Contribution License Agreement](http://www.nativescript.org/cla). The NativeScript team cannot accept pull requests from users who have not signed the CLA first. - -## Introduction - -These guidelines are here to facilitate your contribution and streamline the process of getting changes merged into this project and released. Any contributions you can make will help tremendously, even if only in the form of an issue report. Following these guidelines will help to streamline the pull request and change submission process. - -## Reporting Bugs - -1. Always update to the most recent master release; the bug may already be resolved. -2. Search for similar issues in the issues list for this repo; it may already be an identified problem. -3. If this is a bug or problem that is clear, simple, and is unlikely to require any discussion -- it is OK to open an issue on GitHub with a reproduction of the bug including workflows and screenshots. If possible, submit a Pull Request with a failing test, entire application or module. If you'd rather take matters into your own hands, fix the bug yourself (jump down to the "Code Fixes and Enhancements" section). - -## Requesting New Features - -1. Use Github Issues to submit feature requests. -2. First search for a similar request and extend it if applicable. This way it would be easier for the community to track the features. -2. When a brand new feature requested, try to give as many details on your need as possible. We prefer that you explain a need than explain a technical solution for it. That might trigger a nice conversation on finding the best and broadest technical solution to a specific need. - -## Asking for Help - -The NativeScript team does *not* provide guaranteed formal support, except to those customers who have purchased a [commercial license for NativeScript](http://www.telerik.com/support/platform/) (Developer, Professional, Business, etc.) or a support-only package from Telerik.com. Please do not create support requests for this project in the issues list for this repo, as these will be immediately closed and you'll be directed to post your question on a community forum. - - -## Code Fixes and Enhancements - -### 1. Log an Issue - -Before doing anything else, we ask that you file an issue in the Issues list for this project. First, be sure to check the list to ensure that your issue hasn't already been logged. If you're free and clear, file an issue and provide a detailed description of the bug or feature you're interested in. If you're also planning to work on the issue you're creating, let us know so that we can help and provide feedback. To help us investigate your issue and respond in a timely manner, you can provide is with the following details: -- **Overview of the issue**: Provide a short description of the visible symptoms. If applicable, include error messages, screen shots, and stack traces. -- **Motivation for or use case**: Let us know how this particular issue affects your work. -- **Telerik NativeScript version(s)**: List the current version and build number of the CLI interface, the runtime and the modules. You can get these by checking the package.json files of the respective package. Let us know if you have not observed this behavior in earlier versions and if you consider it a regression. -- **System configuration**: Provide us with relevant system configuration information such as operating system, network connection, proxy usage, etc. Let us know if you have been able to reproduce the issue on multiple setups. -- **Steps to reproduce**: If applicable, submit a step-by-step walkthrough of how to reproduce the issue. -- **Related issues**: If you discover a similar issue in our archive, give us a heads up - it might help us identify the culprit. -- **Suggest a fix**: You are welcome to suggest a bug fix or pinpoint the line of code or the commit that you believe has introduced the issue. - -### 2. Fork and Branch - -#### Fork Us, Then Create A Topic Branch For Your Work - -The work you are doing for your pull request should not be done in the master branch of your forked repository. Create a topic branch for your work. This allows you to isolate the work you are doing from other changes that may be happening. - -Github is a smart system, too. If you submit a pull request from a topic branch and we ask you to fix something, pushing a change to your topic branch will automatically update the pull request. - -#### Isolate Your Changes For The Pull Request - -See the previous item on creating a topic branch. - -If you don't use a topic branch, we may ask you to re-do your pull request on a topic branch. If your pull request contains commits or other changes that are not related to the pull request, we will ask you to re-do your pull request. - -#### Branch from "master" - -The "master" branch of the NativeScript repository is for continuous contribution. Always create a branch for your work from the "master" branch. This will facilitate easier pull request management. - -#### Contribute to the Code Base -Before you submit a Pull Request, consider the following guidelines. - -Search GitHub for an open or closed Pull Request that relates to your submission. -Clone the repository. -```bash - git clone git@github.com:NativeScript/NativeScript.git -``` -Initialize the submodules. -```bash - git submodule update --init --recursive -``` -Make your changes in a new git branch. We use the Gitflow branching model so you will have to branch from our master branch. -```bash - git checkout -b my-fix-branch master -``` -Create your patch and include appropriate test cases. -Build your changes locally. -```bash - grunt -``` -Commit your changes and create a descriptive commit message (the commit message is used to generate release notes). -```bash - git commit -a -``` -Push your branch to GitHub. -```bash - git push origin my-fix-branch -``` -In GitHub, send a Pull Request to NativeScript:NativeScript:master. -If we suggest changes, you can modify your branch, rebase, and force a new push to your GitHub repository to update the Pull Request. -```bash - git rebase master -i - git push -f -``` -That's it! Thank you for your contribution! - -When the patch is reviewed and merged, you can safely delete your branch and pull the changes from the main (upstream) repository. - -Delete the remote branch on GitHub. -```bash - git push origin --delete my-fix-branch -``` -Check out the master branch. -```bash - git checkout master -f -``` -Delete the local branch. -```bash - git branch -D my-fix-branch -``` -Update your master branch with the latest upstream version. -```bash - git pull --ff upstream master -``` - -#### Squash your commits - -When you've completed your work on a topic branch, we prefer that you squash your work down into a single commit to make the merge process easier. For information on squashing via an interactive rebase, see [the rebase documentation on GitHub](https://help.github.com/articles/interactive-rebase) - -### 3. Submit a Pull Request - -See [Github's documentation for pull requests](https://help.github.com/articles/using-pull-requests). - -Pull requests are the preferred way to contribute to NativeScript. Any time you can send us a pull request with the changes that you want, we will have an easier time seeing what you are trying to do. But a pull request in itself is not usually sufficient. There needs to be some context and purpose with it, and it should be done against specific branch. - -### Provide A Meaningful Description - -Similar to reporting an issue, it is very important to provide a meaningful description with your pull requests that alter any code. A good format for these descriptions will include four things: - -1. Why: The problem you are facing (in as much detail as is necessary to describe the problem to someone who doesn't know anything about the system you're building) - -2. What: A summary of the proposed solution - -3. How: A description of how this solution solves the problem, in more detail than item #2 - -4. Any additional discussion on possible problems this might introduce, questions that you have related to the changes, etc. - -Without at least the first 2 items in this list, we won't have any clue why you're changing the code. The first thing we'll ask, then, is that you add that information. - -## Code Style - -All code contributed to this project should adhere to a consistent style, so please keep these in mind before you submit your Pull Requests: - -- Tab indentation, size of 4 -- Semicolons are nice. Use them -- Double quotes -- No trailing whitespace -- Declare one variable per var statement -- Declare variables at the top of a scope -- Return early - -For a more detailed guide, check the [Coding Convention](https://github.com/NativeScript/NativeScript/blob/master/CodingConvention.md). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..1a7770f22 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,78 @@ +# Contributing to NativeScript + +:+1: First of all, thank you for taking the time to contribute! :+1: + +Here are some guides on how to do that: + - [Code of Conduct](#coc) + - [Reporting Bugs](#bugs) + - [Requesting New Features](#features) + - [Submitting a PR](#pr) + +## Code of Conduct +Help us keep a healthy and open community. We expect all participants in this project to adhere to the the [NativeScript Code Of Conduct](https://github.com/NativeScript/codeofconduct). + + +## Reporting Bugs + +1. Always update to the most recent master release; the bug may already be resolved. +2. Search for similar issues in the issues list for this repo; it may already be an identified problem. +3. If this is a bug or problem that is clear, simple, and is unlikely to require any discussion -- it is OK to open an issue on GitHub with a reproduction of the bug including workflows and screenshots. If possible, submit a Pull Request with a failing test, entire application or module. If you'd rather take matters into your own hands, fix the bug yourself (jump down to the [Submitting a PR](#pr) section). + +## Requesting Features + +1. Use Github Issues to submit feature requests. +2. First, search for a similar request and extend it if applicable. This way it would be easier for the community to track the features. +3. When requesting a new feature, please provide as much detail as possible about why you need the feature in your apps. We prefer that you explain a need rather than explain a technical solution for it. That might trigger a nice conversation on finding the best and broadest technical solution to a specific need. + +## Submitting a PR + +Before you begin: +* Read and sign the [NativeScript Contribution License Agreement](http://www.nativescript.org/cla). +* Make sure there is an issue for the bug or feature you will be working on. + +Following these steps is the best way to get you code included in the project: + +1. Fork and clone the NativeScript repo: +```bash +git clone https://github.com//NativeScript.git +# Navigate to the newly cloned directory +cd NativeScript +# Add an "upstream" remote pointing to the original {N} repo. +git remote add upstream https://github.com/NativeScript/NativeScript.git +``` + +2. Set up the project (for detailed info check our [development workflow guide](DevelopmentWorkflow.md)): + +```bash +#In the repo root +npm install +npm run setup +``` + +3. Create a branch for your PR +```bash +git checkout -b master +``` + +4. The fun part! Make your code changes. Make sure you: + - Follow the [code conventions guide](CodeConvention.md). + - Write unit tests for your fix or feature. Check out [writing unit tests guide](WritingUnitTests.md). + +5. Before you submit your PR: + - Rebase your changes to the latest master: `git pull --rebase upstream master`. + - Ensure all unit test are green for Android and iOS. Check [running unit tests](DevelopmentWorkflow.md#running-unit-tests). + - Ensure your changes pass tslint validation. (run `npm run tslint` in the root of the repo). + +6. Push your fork. If you have rebased you might have to use force-push your branch: +``` +git push origin --force +``` + +7. [Submit your pull request](https://github.com/NativeScript/NativeScript/compare). Please, fill in the Pull Request template - it will help us better understand the PR and increase the chances of it getting merged quickly. + +It's our turn from there on! We will review the PR and discuss changes you might have to make before merging it! Thanks! + + +### Where to Start + +If you want to contribute, but you are not sure where to start - look for [issues marked with up-for-grabs tag](https://github.com/NativeScript/NativeScript/issues?q=is%3Aopen+is%3Aissue+label%3Aup-for-grabs). diff --git a/CodingConvention.md b/CodingConvention.md index c15be0b69..c9c403626 100644 --- a/CodingConvention.md +++ b/CodingConvention.md @@ -1,31 +1,17 @@ -# TSN-Modules Coding Convention# +# NativeScript Modules Coding Convention ## Linting -*TODO: We should further verify this may work with TypeScript* - -Linting is the process of running a program that will analyse code for potential errors. - -For Visual Studio use this [extension][vsjslint] with JsHint mode. Settings can be imported from [here][jslintsettings] - -For WebStrom set it JsHint in Settings > JavaScript > Code Quality Tools. - -Following rules should be applied. -~~~ {.javascript} -/*jshint bitwise:true, camelcase:true, curly:true, eqeqeq:true, forin:true, noarg:true, noempty:true, nonew:true, undef:true, unused:true, strict:true, indent:4, quotmark:single, node:true */ -~~~ - -[linting]:http://stackoverflow.com/questions/8503559/what-is-linting -[vsjslint]:http://visualstudiogallery.msdn.microsoft.com/1a417c37-4d6f-43ca-b753-6ea6eb5041fd -[jslintsettings]:https://github.com/telerik/everlive/blob/master/CodeConventions/JSLintSettings.xml +We use [TSLint](https://palantir.github.io/tslint/) for linting. Rules are defined in `build/tslint.json`. +Run the tslint form the root of the repo with: +```bash +npm run tslint +``` ## Tabs vs Spaces Use 4 spaces indentation. -+ Visual Studio: Options > Text Editor > JavaScript > Tabs. Indenting: Smart tabs; Tab: Indent Size: 4, Insert Tabs: checked. This is the default Visual Studio set up -+ JetBrains WebStorm: Settings > Code Style > JavaScript > Use tab: unchecked. All other tam settings to 4 - ## Line length @@ -37,32 +23,31 @@ Always use semicolons where it is appropriate. *Right:* -~~~ {.javascript} -var x = 1; -~~~ +```TypeScript +let x = 1; +``` *Wrong:* -~~~ {.javascript} -var x = 1 -~~~ - +```TypeScript +let x = 1 +``` ## Quotes -Use single quotes, unless you are writing JSON. +Use double quotes for strings: *Right:* -~~~ {.javascript} -var foo = 'bar'; -~~~ +```TypeScript +let foo = "bar"; +``` *Wrong:* -~~~ {.javascript} -var foo = "bar"; -~~~ +```TypeScript +let foo = 'bar'; +``` ## Braces @@ -70,20 +55,20 @@ Your opening braces go on the same line as the statement. *Right:* -~~~ {.javascript} +```TypeScript if (true) { - console.log('winning'); + console.log("winning"); } -~~~ +``` *Wrong:* -~~~ {.javascript} +```TypeScript if (true) { - console.log('losing'); + console.log("losing"); } -~~~ +``` Also, notice the use of whitespace before and after the condition statement. @@ -91,70 +76,49 @@ Follow the JavaScript convention of stacking `else/catch` clauses on the same li *Right:* -~~~ {.javascript} +```TypeScript if (i % 2 === 0) { - console.log('even'); + console.log("even"); } else { - console.log('odd'); + console.log("odd"); } -~~~ +``` *Wrong:* -~~~ {.javascript} +```TypeScript if (i % 2 === 0) { - console.log('even'); + console.log("even"); } else { - console.log('odd'); + console.log("odd"); } -~~~ +``` ## Variable declarations -Declare one variable per var statement. Try to put those declarations at the beginning of each scope. - -**NOTE:** Loops DO NOT create new scopes so declare iteration vars outside the loop. +Declare variables with `let` instead of `var`. Use `const` when possible. *Right:* -~~~ {.javascript} -var keys = ['foo', 'bar']; -var values = [23, 42]; -var key; -var object = {}; +```TypeScript +const button = new Button(); -while (items.length) { - key = keys.pop(); - object[key] = values.pop(); -} - -//--------------------------- - -var i; -for (i = 0; i < items.length; i++) { +for (let i = 0; i < items.length; i++) { // do something } -~~~ +``` *Wrong:* -~~~ {.javascript} -var keys = ['foo', 'bar'], - values = [23, 42], - object = {}; - -while (items.length) { - var key = keys.pop(); - object[key] = values.pop(); -} - -//--------------------------- +```TypeScript +var button = new Button(); for (var i = 0; i < items.length; i++) { - // one may assume the "i" var is local for the loop while it is NOT + // do something } -~~~ + +``` ## Variable and property names @@ -164,15 +128,15 @@ uncommon abbreviations should generally be avoided unless it is something well k *Right:* -~~~ {.javascript} -var adminUser = db.query('SELECT * FROM users ...'); -~~~ +```TypeScript +let adminUser = db.query("SELECT * FROM users ..."); +``` *Wrong:* -~~~ {.javascript} -var admin_user = db.query('SELECT * FROM users ...'); -~~~ +```TypeScript +let admin_user = db.query("SELECT * FROM users ..."); +``` [camelcase]: http://en.wikipedia.org/wiki/camelCase#Variations_and_synonyms @@ -182,36 +146,36 @@ Type names should be capitalized using [upper camel case][camelcase]. *Right:* -~~~ {.javascript} -function UserAccount() { - this.field = 'a'; +```TypeScript +class UserAccount() { + this.field = "a"; } -~~~ +``` *Wrong:* -~~~ {.javascript} -function userAccount() { - this.field = 'a'; +```TypeScript +class userAccount() { + this.field = "a"; } -~~~ +``` ## Constants -Constants should be declared with CAPITAL letters. If the constants will be used in more than one module put them in a separate file. Use underscore to name constants with complex wording. +Constants should be declared with CAPITAL letters and `const` keyword. Use underscore to name constants with complex wording. *Right:* -~~~ {.javascript} -var SECOND = 1 * 1000; -var MY_SECOND = SECOND; -~~~ +```TypeScript +const SECOND = 1 * 1000; +const MY_SECOND = SECOND; +``` *Wrong:* -~~~ {.javascript} +```TypeScript var second = 1 * 1000; -~~~ +``` ## Object / Array creation @@ -220,88 +184,68 @@ keys when your interpreter complains: *Right:* -~~~ {.javascript} -var a = ['hello', 'world']; -var b = { - good: 'code', - 'is generally': 'pretty', +```TypeScript +let a = ["hello", "world"]; +let b = { + good: "code", + "is generally": "pretty", }; -~~~ +``` *Wrong:* -~~~ {.javascript} -var a = [ - 'hello', 'world' +```TypeScript +let a = [ + "hello", "world" ]; -var b = {"good": 'code' - , is generally: 'pretty' +let b = {"good": "code" + , is generally: "pretty" }; -~~~ - -## Long Arrays - -*Right:* - -~~~ {.javascript} -var a = [ - “this”, - “is”, - “a”, - “very”, - “long”, - “array”, - “declaration”, - “for”, - “hello”, - “world” + HOW ABOUT THE ENDING commas? -]; -~~~ +``` ## Equality operator -Use the [strict comaprison operators][comparisonoperators]. The triple equality operator helps to maintain data type integrity throughout code. +Use the [strict comparison operators][comparisonoperators]. The triple equality operator helps to maintain data type integrity throughout code. *Right:* -~~~ {.javascript} -var a = 0; -if (a === '') { - console.log('winning'); +```TypeScript +let a = 0; +if (a === "") { + console.log("winning"); } -~~~ +``` *Wrong:* -~~~ {.javascript} -var a = 0; -if (a == '') { - console.log('losing'); +```TypeScript +let a = 0; +if (a == "") { + console.log("losing"); } -~~~ +``` [comparisonoperators]: https://developer.mozilla.org/en/JavaScript/Reference/Operators/Comparison_Operators -## Short-hand oprators +## Short-hand operators Try to avoid short-hand operators except in very simple scenarios. *Right:* -~~~ {.javascript} -var default = x || 50; -var extraLarge = 'xxl'; -var small = 's' -var big = (x > 10) ? extraLarge : small; -~~~ +```TypeScript +let default = x || 50; +let extraLarge = "xxl"; +let small = "s" +let big = (x > 10) ? extraLarge : small; +``` *Wrong:* -~~~ {.javascript} -var default = checkX(x) || getDefaultSize(); -var big = (x > 10) ? checkX(x)?getExtraLarge():getDefaultSize():getSmallValue(); -~~~ - +```TypeScript +let default = checkX(x) || getDefaultSize(); +let big = (x > 10) ? checkX(x) ? getExtraLarge() : getDefaultSize() : getSmallValue(); +``` ## Curly braces @@ -309,94 +253,88 @@ Always use curly braces even in the cases of one line conditional operations. *Right:* -~~~ {.javascript} +```TypeScript if (a) { - return 'winning'; + return "winning"; } -~~~ +``` *Wrong:* -~~~ {.javascript} +```TypeScript if (a) - return 'winning'; + return "winning"; -if (a) return 'winning'; -~~~ +if (a) return "winning"; +``` ## Boolean comparisons -**Do not** directly compare with true, or false. +**Do not** directly compare with `true`, or `false`. *Right:* -~~~ {.javascript} +```TypeScript if(condition) { - console.log('winning'); + console.log("winning"); } if (!condition) { - console.log('winning'); + console.log("winning"); } -~~~ +``` *Wrong:* -~~~ {.javascript} +```TypeScript if(condition === true) { - console.log('losing'); + console.log("losing"); } if(condition !== true) { - console.log('losing'); + console.log("losing"); } if(condition !== false) { - console.log('losing'); + console.log("losing"); } -~~~ +``` ## Boolean conditions format Do not use the **Yoda Conditions** when writing boolean expressions: -> “Yoda Conditions” — the act of using -> if(constant == variable) **instead of** -> if(variable == constant), like if(4 == foo). -> Because it’s like saying “if blue is the sky” or “if tall is the man”. - *Right:* -~~~ {.javascript} -var num; +```TypeScript +let num; if(num >= 0) { - console.log('winning'); + console.log("winning"); } -~~~ +``` *Wrong:* -~~~ {.javascript} -var num; +```TypeScript +let num; if(0 <= num) { - console.log('losing'); + console.log("losing"); } -~~~ +``` **NOTE** It is OK to use constants on the left when comparing for a range. -~~~ {.javascript} +```TypeScript if(0 <= num && num <= 100) { - console.log('winning'); + console.log("winning"); } -~~~ +``` ## Function length - Keep your functions short. A good function fits on a slide that the people in the last row of a big room can comfortably read. So don't count on them having perfect vision and limit yourself to 1/2 of your screen height per function (no screen rotation :). @@ -409,7 +347,7 @@ as possible. In certain routines, once you know the answer, you want to return i *Right:* -~~~ {.javascript} +```TypeScript function getSomething(val) { if (val < 0) { return false; @@ -419,30 +357,30 @@ function getSomething(val) { return false; } - var res1 = doOne(); - var res2 = doTwo(); - var options = { + let res1 = doOne(); + let res2 = doTwo(); + let options = { a: 1, b: 2 }; - var result = doThree(res1, res2, options); + let result = doThree(res1, res2, options); return result; } -~~~ +``` *Wrong:* -~~~ {.javascript} +```TypeScript function getSomething(val) { if (val >= 0) { if (val < 100) { - var res1 = doOne(); - var res2 = doTwo(); - var options = { + let res1 = doOne(); + let res2 = doTwo(); + let options = { a: 1, b: 2 }; - var result = doThree(res1, res2, options); + let result = doThree(res1, res2, options); return result; } else { @@ -453,156 +391,44 @@ function getSomething(val) { return false; } } -~~~ +``` -## Globals -Avoid using globals. If you need to store a varable as a global make sure that this happens during the bootstrapping of the application. If your code uses globals, please either put them in the begininng of the file using the jsHint convention: +## Arrow Functions -~~~ {.javascript} -/* global Logger, Constants, Everlive */ -~~~ -or use the *global* prefix: - -~~~ {.javascript} -global.Logger.log('a'); -~~~ - -## TS Lambdas - -Avoid using TS Lambdas. Exception is when the function is one-line and DOES NOT use the "this" object. +Use arrow functions over anonymous function expressions. Typescript will take care for `this`. *Right:* -~~~ {.javascript} -req.on('end', () => { console.log('winning'); }); - -//------ -var that = this; -req.on("end", function () { - exp1(); - exp2(); - that.doSomething(); -}); - -~~~ - -*Wrong:* - -~~~ {.javascript} +```TypeScript req.on("end", () => { exp1(); exp2(); this.doSomething(); }); -~~~ - -## Nested Closures - -Prefer closures nested NO MORE than 2 levels. Still, this is more a common sense. - -*Right:* - -~~~ {.javascript} -setTimeout(function() { - client.connect(afterConnect); -}, 1000); - -function afterConnect() { - console.log('winning'); -} -~~~ +``` *Wrong:* -~~~ {.javascript} -setTimeout(function() { - client.connect(function() { - console.log('losing'); - }); -}, 1000); -~~~ - -## Promises - -Wrap every asyncronous method in promises rather than callbacks. - -*Right:* - -~~~ {.javascript} -function doAsync(arg) { - var d = promises.defer(); - - // make the async call - async.call(arg, function onSuccess() { - d.resolve(); - }, function onError() { - d.reject(); - }); - - return d.promise(); -} -~~~ - -*Wrong:* - -~~~ {.javascript} -function doAsync(arg, onSuccess, onError) { - async.call(arg, onSuccess, onError); -} -~~~ +```TypeScript +let that = this; +req.on("end", function () { + exp1(); + exp2(); + that.doSomething(); +}); +``` ## Comments Use the [JSDoc][JSDOC] convention for comments. When writing a comment always think how understandable will be for somebody who is new to this code. Even if it may look simple to you think how a guy that just joined will understand it. Always comment in the following cases: + When there is some non-trivial logic. -+ Some 'external' knowledge is needed which is missing in the context - workaround for driver, module bug, special 'hack' because of a bug and so on; ++ Some "external" knowledge is needed which is missing in the context - workaround for driver, module bug, special 'hack' because of a bug and so on; + When you are creating a new class + Public methods - include all the arguments and if possible the types {String}, {Number}. Optional arguments should be marked too. Check the [@param tag][param] [JSDOC]: http://usejsdoc.org/ [param]: http://usejsdoc.org/tags-param.html - -## Commenting of parameters that are objects/complex types - -When you have parameters that are complex objexts like *options* or other type for which the properties are not clear or is external one use the [@type-def tag][typedef] - -*Right:* - -~~~ {.javascript} -/** - * @typedef PropertiesHash - * @type {object} - * @property {string} id - an ID. - * @property {string} name - your name. - * @property {number} age - your age. - */ - -/** - * @param {PropertiesHash} properties - */ -function checkProperties(properties) { - if(!properties.id) { - return false; - } -} -~~~ - -*Wrong:* -~~~ {.javascript} -/** - * @param properties - */ -function checkProperties(properties) { - if(!properties.id) { - return false; - } -} -~~~ - - -[typedef]: http://usejsdoc.org/tags-typedef.html - ## File/module structure Typical module should have the following structure: @@ -624,29 +450,29 @@ file-system FileSystem, fileSystem, file_system ## This, that, self -When you need to keep reference to **this** use **that** as the name of the variable. Additionally, if you use the TypeScript lambda support, the compiler will take care of this automatically. The tricky part here is that it outputs **_this** which is not compliant with our convention. +When you **need** to keep reference to **this** use **that** as the name of the variable. Additionally, if you use the TypeScript lambda support, the compiler will take care of this automatically. *Right:* -~~~ {.javascript} -var that = this; +```TypeScript +let that = this; doSomething(function(){ that.doNothing(); }); -~~~ +``` *Wrong:* -~~~ {.javascript} -var me = this; +```TypeScript +let me = this; doSomething(function(){ me.doNothing(); }); -~~~ +``` ## Private (hidden) variables and methods Although there is the **private** keyword in TypeScript, it is only a syntax sugar. There is no such notation in JavaScript and everything is available to the users. Hence, always use underscore (**_**) to prefix private variables and methods. There are also methods which have the **public** visibility but they are meant to be used within our code ONLY. Such methods should also be prefixed with underscore. *Right:* -~~~ {.javascript} +```TypeScript class Foo { private _myBoolean: boolean; @@ -660,10 +486,10 @@ class Foo { private _doSomething() { } } -~~~ +``` *Wrong:* -~~~ {.javascript} +```TypeScript class Foo { private myBoolean: boolean; @@ -677,58 +503,20 @@ class Foo { private doSomething() { } } -~~~ - -## Falsy values vs. null and undefined -When possible use the falsy comparison vs. comparison with null or undefined. - -*Right:* -~~~ {.javascript} -var myVar = undefined; -if(myVar) { - // myVar is defined -} -~~~ - -*Wrong:* -~~~ {.javascript} -var myVar = undefined; -if(typeof myVar === 'undefined') { -} -~~~ - -## Type comparison -Sometimes we need to explicitly check for a type. In such cases use the built-in module **"types"**. - -*Right:* -~~~ {.javascript} -import * as types from "utils/types"; -var myVar; - -if(types.isString(myVar)) { - // myVar is of type String -} -~~~ - -*Wrong:* -~~~ {.javascript} -var myVar = undefined; -if(typeof myVar === 'string') { -} -~~~ +``` ## TypeScript optional parameters **Do not** use optional parameters in IMPLEMENTATION files. This is because the TS compiler generates additional array and populates its from the **arguments** object. Still, it is OK to use these in a definition file (as declarations ONLY). *Right:* -~~~ {.javascript} +```TypeScript // declaration export declare function concat(...categories: string[]): string; // implementation export function concat(): string { - var i; - var result: string; + let i; + let result: string; // use the arguments object to iterate the parameters for (i = 0; i < arguments.length; i++) { // do something @@ -736,17 +524,17 @@ export function concat(): string { return result; } -~~~ +``` *Wrong:* -~~~ {.javascript} +```TypeScript // declaration export declare function concat(...categories: string[]): string; // implementation export function concat(...categories: string[]): string { - var i; - var result: string; + let i; + let result: string; // use the arguments object to iterate the parameters for (i = 0; i < categories.length; i++) { // do something @@ -754,35 +542,14 @@ export function concat(...categories: string[]): string { return result; } -~~~ - -## (**SUGGESTION**) TypeScript function variable names -Name your function variables with the **Func** suffix. The reader will immediately know that this variable is a function when he sees it. - -*Right:* -~~~ {.javascript} -var eachChildFunc = function eachChildFunc(child: View): boolean { - child.onUnloaded(); - return true; -} -this._eachChildView(eachChildFunc); -~~~ - -*Wrong:* -~~~ {.javascript} -var eachChild = function (child: View): boolean { - child.onUnloaded(); - return true; -} -this._eachChildView(eachChild); -~~~ +``` ## Naming test functions -Name your test function with test_ so that our test runner can find them and add 'underscore' tested method/property name. Different words should be capitalized (and optionally separated by 'underscore'). +Name your test function with `test_` so that our test runner can find them and add 'underscore' tested method/property name. Different words should be capitalized (and optionally separated by 'underscore'). *Right:* -~~~ {.javascript} -export var test_goToVisualState_NoState_ShouldResetStyledProperties = function () { +```TypeScript +export function test_goToVisualState_NoState_ShouldResetStyledProperties() { // Test code here. } -~~~ +``` diff --git a/CreateNewModule.md b/CreateNewModule.md index 48f12eecc..e06738267 100644 --- a/CreateNewModule.md +++ b/CreateNewModule.md @@ -3,60 +3,62 @@ 1. Each module resides in a separate folder. 2. There must be a package.json file in this folder which tells the NS Runtime which is the main file of the module to load. 3. There is a declaration (*.d.ts) file describing the public API of the module. -4. When there is a ***.android.ts** named file this tells our CLI that this file is Android-specific and should be icluded in Android builds ONLY. When a build is started for the Android platform, the **.android** part of the file is stripped in the application package. For example **foo.android.js** will become ***foo.js**. Same convention works for ***.ios.ts** files. +4. When there is a ***.android.ts** named file this tells our CLI that this file is Android-specific and should be included in Android builds ONLY. When a build is started for the Android platform, the **.android** part of the file is stripped in the application package. For example **foo.android.js** will become ***foo.js**. Same convention works for ***.ios.ts** files. ## Declaration and implementation files There are several major scenarios when writing modules: ### The module implementation contains pure JavaScript code ONLY and does not depend on native APIs. In this case the entire logic is executed on the JS Virtual Machine side and the TNS Runtime is not involved. +_Example:_ [matrix module](tns-core-modules/matrix) + **Declaration file (foo.d.ts):** -```javascript -declare module "foo"{ - function a(); - class Foo { - public var1: number; - } +```typescript +export function a(); + +export class Foo { + public var1: number; } ``` **Implementation file (foo.ts):** -```javascript -import * as definition from "foo"; +```typescript +import { Foo as FooDefinition } from "."; -export function a(){ - // do somethign here +export function a() { + // do something here } // require the definition and put implements clause to ensure API consistency between the declaration and implementation -export class Foo implements definition.Foo { +export class Foo implements FooDefinition { public var1: number; } ``` ### The module implementation depends on native APIs ONLY and the common pure JavaScript code between platform-specific implementations is minimal. +_Example:_ [timer module](tns-core-modules/timer) + + **Declaration file (foo.d.ts):** -```javascript -declare module "foo"{ - class Foo { - public running: number; - public start(): void; - public stop(): void; - } +```typescript +export class Foo { + public running: number; + public start(): void; + public stop(): void; } ``` **Android implementation file (foo.android.ts):** -```javascript -import * as definition from "foo"; +```typescript +import { Foo as FooDefinition } from "."; // require the definition and put implements clause to ensure API consistency between the declaration and implementation -export class Foo implements definition.Foo { +export class Foo implements FooDefinition { public running: number; public start(): void { // Call android APIs - e.g. android.os.SystemClock.[xxx] @@ -71,11 +73,11 @@ export class Foo implements definition.Foo { **iOS implementation file (foo.ios.ts):** -```javascript -import * as definition from "foo"; +```typescript +import { Foo as FooDefinition } from "."; // require the definition and put implements clause to ensure API consistency between the declaration and implementation -export class Foo implements definition.Foo { +export class Foo implements FooDefinition { public running: number; public start(): void { // Call iOS APIs - e.g. Foundation.NSObject.[xxx] @@ -92,27 +94,29 @@ export class Foo implements definition.Foo { In this case we will need to reuse the common JavaScript code and to split the implementation only for the platform specific native APIs. There are two different approaches here: -* _Separate the common implementation (code) in a base class. Add two specific files that inherit the base class and provide the platform-specific implementation:_ +#### Separate the common implementation (code) in a base class. Add two specific files that inherit the base class and provide the platform-specific implementation + +This is the way most of the UI modules are written. + +_Example:_ [image module](tns-core-modules/ui/image) **Declaration file (foo.d.ts):** -```javascript -declare module "foo"{ - class Foo { - public running: number; - public start(): void; - public stop(): void; - } +```typescript +export class Foo { + public running: number; + public start(): void; + public stop(): void; } ``` **Common implementation file (foo-common.ts):** -```javascript -import * as definition from "foo"; +```typescript +import { FooBase as FooDefinition } from "."; // require the definition and put implements clause to ensure API consistency between the declaration and implementation -export class Foo implements definition.Foo { +export class FooBase implements FooDefinition { public running: number; public start(): void { this.running = true; @@ -127,11 +131,11 @@ export class Foo implements definition.Foo { **Android implementation file (foo.android.ts):** -```javascript -import * as common from "foo-common"; +```typescript +import { FooBase } from "./foo-common"; // require the common file and extend the base common implementation -export class Foo extends common.Foo { +export class Foo extends FooBase { public start(): void { // call the base method which does the common job super.start(); @@ -147,11 +151,11 @@ export class Foo extends common.Foo { **iOS implementation file (foo.ios.ts):** -```javascript -import * as common from "foo-common"; +```typescript +import { FooBase } from "./foo-common"; // require the common file and extend the base common implementation -export class Foo extends common.Foo { +export class Foo extends FooBase { public start(): void { // call the base method which does the common job super.start(); @@ -165,34 +169,33 @@ export class Foo extends common.Foo { } ``` -* _Extract the platform specific implementation in a separate Facade and aggregate/use it within the JavaScript implementation:_ +#### Extract the platform specific implementation in a separate Facade and aggregate/use it within the JavaScript implementation + +_Example:_ [file-system module](tns-core-modules/file-system) (_Note:_ `file-system-access` is the platform specific implementation) **Declaration file (foo.d.ts):** -```javascript -declare module "foo"{ - class Foo { - public running: number; - public start(): void; - public stop(): void; - } +```typescript +export class Foo { + public running: number; + public start(): void; + public stop(): void; } ``` **Native Implementation Declaration file (foo-native.d.ts):** -```javascript +```typescript //@private // The above statement marks this definition as private so that it is not visible to the users -declare module "foo-native"{ - function startNative(); - function stopNative(); -} + +export function startNative(); +export function stopNative(); ``` **Android Native Implementation file (foo-native.android.ts):** -```javascript +```typescript export function startNative(){ // call native code here } @@ -203,7 +206,7 @@ export function stopNative(){ **iOS Native Implementation file (foo-native.ios.ts):** -```javascript +```typescript export function startNative(){ // call native code here } @@ -214,22 +217,22 @@ export function stopNative(){ **Common implementation file (foo.ts):** -```javascript -import * as definition from "foo"; -import * as fooNative from "foo-native"; +```typescript +import { FooBase as FooDefinition } from "."; +import { startNative, stopNative } from "./foo-native"; // require the definition and put implements clause to ensure API consistency between the declaration and implementation -export class Foo implements definition.Foo { +export class Foo implements FooDefinition { public running: number; public start(): void { this.running = true; // do the native call through the Facade - fooNative.startNative(); + startNative(); } public stop(): void { this.running = false; // do the native call through the Facade - fooNative.stopNative(); + stopNative(); } } ``` diff --git a/CrossPlatformModules.csproj b/CrossPlatformModules.csproj deleted file mode 100644 index 91198cbac..000000000 --- a/CrossPlatformModules.csproj +++ /dev/null @@ -1,2328 +0,0 @@ - - - - 12.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - 1.8 - {2313F1BF-1F2D-4F11-806A-87927FA6A7C0} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - v4.5 - true - - - - - - - - Cross - bin\ - commonjs - True - True - ES5 - - - bin\ - commonjs - True - ES5 - - - bin\ - commonjs - ES5 - True - - - commonjs - False - ES5 - - - bin\ - commonjs - True - ES5 - - - CrossPlatformModules - - - true - - - OnBuildSuccess - - - bin\ - - - - - - action-bar-hidden.xml - - - action-items-text.xml - - - all-between-tags.xml - - - center-view-stack.xml - - - center-view-segmented.xml - - - center-view.xml - - - data-binding.xml - - - - - - - - - - - - main-page.xml - - - - - - - - - - - - - - - - - - - - - modal-page.xml - - - - - - - - - - - - - - - - - - - main-page.xml - - - - main-page.xml - - - - main-page.xml - - - - details-page.xml - - - main-page.xml - - - - Designer - - - - - - - - - Designer - - - - - - - - - Designer - - - Always - - - Designer - - - - - - Designer - - - - - - - - - Designer - - - - - - - - - - - - - - - - Designer - - - Always - - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - - - - main-page.xml - - - navigation-button.xml - - - action-items-icon.xml - - - page-title-icon.xml - - - - - - page21.xml - - - page20.xml - - - page19.xml - - - - - - - - - - - Designer - - - Designer - - - Designer - - - - Designer - - - Designer - - - - - - - - - Designer - - - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - - action-view.xml - - - - - - Designer - - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - - system-icons.xml - - - all.xml - - - background.xml - - - clean.xml - - - color.xml - - - - - - html-view.xml - - - absolute.xml - - - dock.xml - - - grid.xml - - - - stack.xml - - - wrap.xml - - - login-page.xml - - - modal-view.xml - - - nordic.xml - - - - all.xml - - - clean.xml - - - - - - - - - - - - animation.d.ts - - - animation.d.ts - - - animation.d.ts - - - - - list-picker.xml - - - - main-page.xml - - - - - main-page.xml - - - list-view.xml - - - repeater.xml - - - - main-page.xml - - - main-page.xml - - - - main-page.xml - - - - main-page.xml - - - login-page.xml - - - - - main-page.xml - - - - - main-page.xml - - - - - details-page.xml - - - main-page.xml - - - location-example.xml - - - - - - - - - - - - - - - - - page17.xml - - - - - - - - - - - - bindingContext_testPage.xml - - - bindingExpressions_logicalComparisonOperators_testPage.xml - - - bindingExpressions_comparisonOperators_testPage.xml - - - bindingExpressions_binaryOperators_testPage.xml - - - bindingExpressions_ternaryOperator_testPage.xml - - - bindingExpressions_groupingParenthesis_testPage.xml - - - bindingExpressions_unaryOperators_testPage.xml - - - bindingExpressions_logicalOperators_testPage.xml - - - bindingExpressions_arrayAccess_testPage.xml - - - - - - - time-picker-tests-native.d.ts - - - - time-picker-tests-native.d.ts - - - - - - - segmented-bar-tests-native.d.ts - - - - segmented-bar-tests-native.d.ts - - - - date-picker-tests-native.d.ts - - - - date-picker-tests-native.d.ts - - - - - list-picker-tests-native.d.ts - - - list-picker-tests-native.d.ts - - - - - - - - - - - main-page.xml - - - - - xmlbasics.xml - - - - dialogs.xml - - - - absolute.xml - - - dock.xml - - - grid.xml - - - - stack.xml - - - wrap.xml - - - background.xml - - - - - - - - text-field.xml - - - text-field.xml - - - text-view.xml - - - label.xml - - - button.xml - - - web-view.xml - - - connectivity.d.ts - - - - - connectivity.d.ts - - - - connectivity.d.ts - - - - file-name-resolver.d.ts - - - image-source.d.ts - - - image-source.d.ts - - - image-source.d.ts - - - - platform.d.ts - - - platform.d.ts - - - - - application.d.ts - - - - application.d.ts - - - color.d.ts - - - color.d.ts - - - - color.d.ts - - - - console.d.ts - - - - declarations.d.ts - - - declarations.d.ts - - - - fps-meter.d.ts - - - - fps-native.d.ts - - - - fps-native.d.ts - - - - http-request.d.ts - - - http-request.d.ts - - - - - - - location.d.ts - - - location.d.ts - - - location.d.ts - - - - - - - - - - - - - - - - - - - - - - - application-tests-common.ts - - - application-tests-common.ts - - - - - - - - - - - - - view-tests-common.ts - - - view-tests-common.ts - - - text.d.ts - - - - text.d.ts - - - - trace.d.ts - - - - - border.d.ts - - - action-bar.d.ts - - - action-bar.d.ts - - - - action-bar.d.ts - - - - - - - - - - - - - - - - - - - - - - - - - - - - - absolute-layout.d.ts - - - absolute-layout.d.ts - - - absolute-layout.d.ts - - - dock-layout.d.ts - - - dock-layout.d.ts - - - dock-layout.d.ts - - - grid-layout.d.ts - - - grid-layout.d.ts - - - grid-layout.d.ts - - - layout.d.ts - - - layout.d.ts - - - - layout-base.d.ts - - - layout-base.d.ts - - - layout-base.d.ts - - - stack-layout.d.ts - - - stack-layout.d.ts - - - stack-layout.d.ts - - - wrap-layout.d.ts - - - wrap-layout.d.ts - - - wrap-layout.d.ts - - - repeater.d.ts - - - - - list-picker.d.ts - - - list-picker.d.ts - - - - list-picker.d.ts - - - - placeholder.d.ts - - - placeholder.d.ts - - - placeholder.d.ts - - - segmented-bar.d.ts - - - segmented-bar.d.ts - - - segmented-bar.d.ts - - - - button.d.ts - - - content-view.d.ts - - - - - bindable.d.ts - - - - control-state-change.d.ts - - - - image-cache.d.ts - - - - image-cache.d.ts - - - image-cache.d.ts - - - - - - - - - background.d.ts - - - background.d.ts - - - - background.d.ts - - - - css-selector.d.ts - - - font.d.ts - - - font.d.ts - - - - font.d.ts - - - - - - view.d.ts - - - view.d.ts - - - - view.d.ts - - - frame.d.ts - - - frame.d.ts - - - - frame.d.ts - - - image.d.ts - - - - image.d.ts - - - label.d.ts - - - - label.d.ts - - - label.d.ts - - - page.d.ts - - - page.d.ts - - - - page.d.ts - - - progress.d.ts - - - search-bar.d.ts - - - slider.d.ts - - - - - date-picker.d.ts - - - date-picker.d.ts - - - - date-picker.d.ts - - - time-picker.d.ts - - - time-picker.d.ts - - - - time-picker.d.ts - - - text-field.d.ts - - - text-field.d.ts - - - - text-field.d.ts - - - - - utils.d.ts - - - - - - - - utils.d.ts - - - - utils.d.ts - - - - - timer.d.ts - - - - - timer.d.ts - - - - file-system-access.d.ts - - - file-system-access.d.ts - - - application.d.ts - - - - application-settings.d.ts - - - application-settings.d.ts - - - - - - - Always - - - - Always - - - Designer - - - - - - - - - Designer - - - Designer - - - Designer - - - Designer - - - - - - - - Designer - - - - - - - - - - Designer - - - Designer - - - - - - - - - - fonts-test.xml - - - background-test.xml - - - - - - - - - - - - - - - - - - - - - - - - Designer - - - - - - Designer - - - - - - styles.xml - - - - - - - - - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - - - Designer - - - - - - - - - Designer - - - Designer - - - - - - - - - - - - - - - - - Designer - - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - observable.d.ts - - - dialogs.d.ts - - - - dialogs.d.ts - - - - - button.d.ts - - - button.d.ts - - - - slider.d.ts - - - - switch.d.ts - - - switch.d.ts - - - switch.d.ts - - - - - activity-indicator.d.ts - - - activity-indicator.d.ts - - - progress.d.ts - - - - progress.d.ts - - - - search-bar.d.ts - - - search-bar.d.ts - - - - list-view.d.ts - - - list-view.d.ts - - - - scroll-view.d.ts - - - scroll-view.d.ts - - - scroll-view.d.ts - - - - slider.d.ts - - - - - - - PreserveNewest - - - - Designer - - - - Designer - - - - camera.d.ts - - - camera.d.ts - - - camera.d.ts - - - - http.d.ts - - - file-system.d.ts - - - - - - - - - - MyControl.xml - - - Always - - - Always - - - - - - - - - - - - dialogs.xml - - - - - - - - - - - - - - - - Designer - - - Designer - - - - Designer - - - Designer - - - - - - - - - main-page.xml - - - Designer - - - Designer - - - - - - - - - - easysax.d.ts - - - - - - - observable-array.d.ts - - - - - - - - - - xml.d.ts - - - - virtual-array.d.ts - - - - common.d.ts - - - - - - - - esprima.d.ts - - - - polymer-expressions.d.ts - - - - mainPage.xml - - - - text-field-tests-native.d.ts - - - text-field-tests-native.d.ts - - - details-page.xml - - - - - - main-page.xml - - - Designer - - - - - text-view-tests-native.d.ts - - - text-view-tests-native.d.ts - - - - - - - - label-tests-native.d.ts - - - label-tests-native.d.ts - - - Designer - - - - - - - - - - - - - - - - - - login.xml - - - - news.xml - - - - - - - - - - - - controls-page.d.ts - - - - - - native-calls-wrapper.d.ts - - - native-calls-wrapper.d.ts - - - - - - - - - tests.d.ts - - - - tests-native.d.ts - - - tests-native.d.ts - - - - - nav-page.d.ts - - - - - - - image.d.ts - - - activity-indicator.d.ts - - - dependency-observable.d.ts - - - - gestures.d.ts - - - gestures.d.ts - - - gestures.d.ts - - - list-view.d.ts - - - - - - - - utils.d.ts - - - - - - button-tests-native.d.ts - - - button-tests-native.d.ts - - - styling.d.ts - - - - style-property.d.ts - - - - - tab-view.d.ts - - - tab-view.d.ts - - - tab-view.d.ts - - - - - tab-view-tests-native.d.ts - - - tab-view-tests-native.d.ts - - - - - - - - - - - - page-tests-common.ts - - - page-tests-common.ts - - - - builder.d.ts - - - - text-base.d.ts - - - text-base.d.ts - - - text-base.d.ts - - - text-view.d.ts - - - text-view.d.ts - - - text-view.d.ts - - - - weak-event-listener.d.ts - - - - types.d.ts - - - - proxy.d.ts - - - - visual-state-constants.d.ts - - - - enums.d.ts - - - component-builder.d.ts - - - - - - span.d.ts - - - span.d.ts - - - span.d.ts - - - - formatted-string.d.ts - - - formatted-string.d.ts - - - formatted-string.d.ts - - - web-view.d.ts - - - web-view.d.ts - - - web-view.d.ts - - - editable-text-base.d.ts - - - editable-text-base.d.ts - - - editable-text-base.d.ts - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - - - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - - - - PreserveNewest - - - - - PreserveNewest - - - - - - - - - - - - - - - PreserveNewest - - - - - - - - - - - - - PreserveNewest - - - - - - - - - - - - - PreserveNewest - - - - - - - - - - - - - - - - - PreserveNewest - - - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - - - PreserveNewest - - - - - - - - PreserveNewest - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - - - - - - - - - PreserveNewest - - - - - - - - PreserveNewest - - - - - - PreserveNewest - - - PreserveNewest - - - - - PreserveNewest - - - - - - PreserveNewest - - - PreserveNewest - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - - - - PreserveNewest - - - - PreserveNewest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - - PreserveNewest - - - PreserveNewest - - - - - - PreserveNewest - - - - - - - - - - - - - - - - - - - - true - - true - 1.3.0 - node_modules\.bin - tsc.cmd - true - - - - $(BuildDependsOn);CompileAndPack; - - - - - - - --leavecomments=true - --runtslint=true - --runtslint=false - - - - - - - - - - - - - True - True - 0 - / - http://localhost:60276/ - False - False - - - False - - - - - - \ No newline at end of file diff --git a/CrossPlatformModules.sln b/CrossPlatformModules.sln deleted file mode 100644 index 646061d34..000000000 --- a/CrossPlatformModules.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30501.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrossPlatformModules", "CrossPlatformModules.csproj", "{2313F1BF-1F2D-4F11-806A-87927FA6A7C0}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Android_Tests|Any CPU = Android_Tests|Any CPU - Cross|Any CPU = Cross|Any CPU - Cross-TS|Any CPU = Cross-TS|Any CPU - Documentation|Any CPU = Documentation|Any CPU - iOS_Tests|Any CPU = iOS_Tests|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2313F1BF-1F2D-4F11-806A-87927FA6A7C0}.Android_Tests|Any CPU.ActiveCfg = Android_Tests|Any CPU - {2313F1BF-1F2D-4F11-806A-87927FA6A7C0}.Android_Tests|Any CPU.Build.0 = Android_Tests|Any CPU - {2313F1BF-1F2D-4F11-806A-87927FA6A7C0}.Cross|Any CPU.ActiveCfg = Cross|Any CPU - {2313F1BF-1F2D-4F11-806A-87927FA6A7C0}.Cross|Any CPU.Build.0 = Cross|Any CPU - {2313F1BF-1F2D-4F11-806A-87927FA6A7C0}.Cross-TS|Any CPU.ActiveCfg = Cross-TS|Any CPU - {2313F1BF-1F2D-4F11-806A-87927FA6A7C0}.Cross-TS|Any CPU.Build.0 = Cross-TS|Any CPU - {2313F1BF-1F2D-4F11-806A-87927FA6A7C0}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {2313F1BF-1F2D-4F11-806A-87927FA6A7C0}.Documentation|Any CPU.Build.0 = Documentation|Any CPU - {2313F1BF-1F2D-4F11-806A-87927FA6A7C0}.iOS_Tests|Any CPU.ActiveCfg = iOS_Tests|Any CPU - {2313F1BF-1F2D-4F11-806A-87927FA6A7C0}.iOS_Tests|Any CPU.Build.0 = iOS_Tests|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/DebugV8Heap.md b/DebugV8Heap.md deleted file mode 100644 index 85a81425c..000000000 --- a/DebugV8Heap.md +++ /dev/null @@ -1,23 +0,0 @@ -###NOTE: This works for Android ONLY!!! - -* There is the global function - -```js -heapSnapshot(); -``` - -* The function will save a V8's heap dump file in the application private files folder - e.g. - -```js -data/data/com.telerik.tns.unittestapp/files/xxx.xxx.heapsnapshot -``` - -* Open command prompt and go the location of your ADB - e.g. [PathToADT]/sdk/platform-tools/ -* Run `adb shell` -* Go to `/data/data/com.telerik.tns.unittestapp/files/` -* Run `ls` to list the files in the folder and find the *.heapsnapshot file(s). -* Run `exit` to return back to the command prompt -* Run `adb pull /data/data/com.telerik.tns.unittestapp/files/xxx.xxx.heapsnapshot LocalPath/To/Snapshot` -* Open Chrome Developer Tools (Ctrl + Shift + I within Chrome) -* Go to `Profiles` tab on the top of the tools window -* Select `Record Heap Allocations` and load the locally saved *.heapsnapshot file. diff --git a/DevelopmentWorkflow.md b/DevelopmentWorkflow.md index 0eb9b15ef..2668b92c9 100644 --- a/DevelopmentWorkflow.md +++ b/DevelopmentWorkflow.md @@ -1,11 +1,13 @@ Development Workflow ==================== +## Project Structure + The repository contains several packages and apps: - - `tns-platform-declarations` - Android and iOS native APIs supported in JavaScript - - `tns-core-modules` - Core ui, io and sensor modules - - `apps` - UI app used for manual testing and automation - - `tests` - Unit tests for the `tns-core-modules` + - `tns-core-modules` - The core NativeScript TypeScript modules used to develop NativeScript apps. + - `apps` - UI app used for manual testing and automation. + - `tests` - Unit tests app for the `tns-core-modules`. + - `tns-platform-declarations` - TypeScript definitions for Android and iOS native APIs. Working with the repo is organized with npm scripts, go and read through the `scripts` section in the [package.json](./package.json). @@ -23,14 +25,18 @@ Managing dependencies: > NOTE: `tns-core-modules` depends on `tns-core-modules-widgets`, this dependency contains native code and is rarely modified so for now it remains outside this repo. -## Manage Dependencies -Get devDependencies by: +## Initial Setup +Clone (or fork/clone) the repo: +```bash +git clone https://github.com/NativeScript/NativeScript.git +``` + +Install devDependencies: ```bash npm install ``` -Setting up the environment for work we use [`npm link`](https://docs.npmjs.com/cli/link). -The dependencies in the repo are `npm link`-ed (~synlinked) using the following script: +Run setup script. This will [`npm link`](https://docs.npmjs.com/cli/link) the `tns-core-modules` and `tns-core-modules-declarations` dependencies inside the `tests` and `apps` projects. ```bash npm run setup ``` @@ -48,30 +54,56 @@ tsc --skipLibCheck tsc --skipLibCheck -w ``` -The modules have `typescript` as devDependency so you should also be able to use locally installed TypeScript compiler from node_modules: -``` +The modules have `typescript` as a devDependency so you should also be able to use the locally installed TypeScript compiler from node_modules: +```bash ./node_modules/.bin/tsc ``` -You can compile the typescript files in the `tns-core-modules`, `tns-platform-declarations`, `apps` and `tests` at once at the root of the repo: -``` +You can compile the TypeScript files in the `tns-core-modules`, `tns-platform-declarations`, `apps` and `tests` at once at the root of the repo: +```bash npm run tsc ``` -## Tests +## Running Unit Tests The test app is an ordinary NativeScript app that logs the test results as it go. -To run the test app: -``` -# Once after npm install -npm run setup - -# After changes in the modules or the tests +After the [initial setup](#initial-setup) you can run the tests with: +```bash +# Make sure TypeScript is transpiled tsc +# Run the tests app tns run ios --path tests tns run android --path tests ``` +## Running the Test App + +The test app is an ordinary NativeScript app that logs the test results as it go. +After the [initial setup](#initial-setup) you can run the tests with: + +``` +# Make sure TypeScript is transpiled +tsc + +# Run the app +tns run ios --path apps +tns run android --path apps +``` + +## Running Another App +The [initial setup](#initial-setup) will `npm-link` the `tns-core-modules` globally. You can use it in any local project: + +```bash +# Run once: Link tns-core-modules in your project +npm link tns-core-modules + +# Run the app +tns run ios +tns run android +``` +>Note: You still have to rebuild the TypeScript if you have made changes in the code of the core-modules. + + ## Platform declarations To update the platform declarations (the ios.d.ts-es) you can run: ``` diff --git a/Introduction.md b/Introduction.md deleted file mode 100644 index a3caac73f..000000000 --- a/Introduction.md +++ /dev/null @@ -1,51 +0,0 @@ -NativeScript Modules -=== - -#What are the cross-platform modules -The cross-platform modules repository contains the framework to be used for writing code that will run on any of the platforms, supported by NativeScript. - -#Basics -For faster and more stable development, the modules are written in TypeScript, that gets 'transpiled' to JavaScript, which actually runs on the target device. To have that, the JavaScript code is accompanied with a set of platform-specific (native) binaries, called runtimes. These are a middle layer, running the JavaScript code on the device. - -#Code organization -Each runtime provides JavaScript wrappers over the native platform classes. The classes in the cross-platform modules are common wrappers over the native wrappers, organized in a manner, allowing the straightforward development of powerful cross-platform mobile applications. -A cross-platform class would typically have different imlementations for the different platforms. The cross-platform library must have them both and decide which one to use. To avoid runtime checking, a convention is chosen that any files, named \*.[platform].ts (and, respectively, \*.[platform].js) are valid for the specific platform only. That way, common API gets only declared in a file, named `file-system-access.d.ts` while its iOS and Android implementations get coded in the `file-system-access.ios.ts` and `file-system-access.android.ts` respectively. - -One would notice the `apps` folder, which does not fit the notation of a module. Normally each of the subfolders of the `apps` folder would be a separate repository or a project, with its own build and packaging. For a faster and more stable development, aided with code completion and due to limitations in Visual Studio, the current setup is chosen. - -#Steps to build the CrossPlatformModules solution: - -#Before start -1. Make sure you have nodejs and npm installed -2. Navigate to the CrossPlatformModules directory -3. Run `npm install -g grunt-cli` (to be able to trigger the grunt build).
-**Note**: Might require sudo permissions on some *nix systems -4. Run `npm install` (will install the dependencies and devDependencies) - - -#Visual Studio and Project Structure -The CrossPlatformModules project calls a grunt task that transpiles the typescript code to JavaScript. - -A module file that cannot have a common implementation across the platforms -would have a `modulename.d.ts` file, containing the declarations of the -module API and `modulename.[platform].ts` files, containing the actual -platform-specific implementation of the module functionality. -The `modulename.d.ts` file in that case is used by Visual Studio as an intellisense -helper, forcing the Visual Studio typescript compiler to feed its definitions -from the \*.d.ts file rather than the implementation one. - -When built, the project outputs npm packages, containing the fully transpiled -code. There is a package for the modules only and packages for each subfolder -of the apps folder, each representing a standalone cross-platform NativeScript -application. - -### Useful links - -[VSCommands](http://vscommands.squaredinfinity.com/) - -Adds the option to "Group Items" (DependentUpon tag) within the Visual Studio Solution Explorer. Select several items, right-click -> Group Items. - -[A comparison of various features and APIs across mobile platforms](https://github.com/w3c-webmob/web-api-gap/blob/master/features/compass.md) - -## CLI -Run `grunt` to have the the packages built and output to the `bin/dist` subfolder. diff --git a/README.md b/README.md index 3fd80ce1c..348572358 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ In addition to the code that makes up the NativeScript framework itself, we also ## Contributing -We love PRs, and accept them for all of our repositories—even docs! Please follow our [contribution guide](https://www.nativescript.org/contribute) if you want to become part of the project. +We love PRs, and accept them for all of our repositories—even docs! Please follow our [contribution guide](CONTRIBUTING.md) if you want to become part of the project. ## Angular @@ -72,12 +72,6 @@ We [worked together with the Google Angular team](http://angularjs.blogspot.com/ ## Get Help -The NativeScript framework has a vibrant community that can help when you run into problems. - -If you have a question, start by seeing if anyone else has encountered the scenario on [Stack Overflow](http://stackoverflow.com/questions/tagged/nativescript). If you cannot find any information, try [asking the question yourself](http://stackoverflow.com/questions/ask/advice?). Make sure to add any details needed to recreate the issue and include the “NativeScript” tag, so your question is visible to the NativeScript community. - -If you need more help than the Q&A format Stack Overflow can provide, try [joining the NativeScript community Slack](http://developer.telerik.com/wp-login.php?action=slack-invitation). The Slack chat is a great place to get help troubleshooting problems, as well as connect with other NativeScript developers. - -Finally, if you have found an issue with the NativeScript framework itself, please report the problem in the [Issues](https://github.com/NativeScript/NativeScript/issues). +Please, use [github issues](https://github.com/NativeScript/NativeScript/issues) strictly for [reporting a bugs](CONTRIBUTING.md#bugs) or [requesting features](CONTRIBUTING.md#features). For general NativeScript questions and support, check out the [NativeScript community forum](https://discourse.nativescript.org/). ![](https://ga-beacon.appspot.com/UA-111455-24/nativescript/nativescript?pixel) diff --git a/RunTests.md b/RunTests.md deleted file mode 100644 index 1e460e5ed..000000000 --- a/RunTests.md +++ /dev/null @@ -1,22 +0,0 @@ -To run tests please build using one of the *_Tests build configurations and call runAll() method of the Tests module. For example: - -##iOS -``` JavaScript -var app = require("application"); -app.init(null); -var tests = require("Tests"); -tests.runAll(); -``` - -##Android -``` JavaScript -app.init({ - getActivity: function(intent) { - return com.tns.NativeScriptActivity.extend({}); - }, - onCreate: function() { - require("application").init(this); - require("Tests").runAll(); - } -}); -``` diff --git a/WritingUnitTests.md b/WritingUnitTests.md new file mode 100644 index 000000000..5b99b7b7c --- /dev/null +++ b/WritingUnitTests.md @@ -0,0 +1,84 @@ +# Writing Unit Tests for NativeScript Core Modules + +Unit tests for NativeScript Modules are written and executed with a custom lightweight test-runner and assertion framework. +The purpose of this document is to get you familiar with it, so that you can unit-test your contributions to the NativeScript framework. + +# Run Unit Tests Project + +Refer to the [development-workflow guide](DevelopmentWorkflow.md) for instructions on how to set up your repo and get it ready for development. +After the setup, navigate to the `tests` project and run it. It will execute all the tests and output the results in the console. + +```bash +cd tests + +tns run android +# or +tns run ios +``` + +# Test Modules + +All unit tests are organized into test modules(bundles). +By default the test app will run all the tests from all registered test modules. This happens in [`runTests()`](/tests/app/app/mainPage.ts#L26-L28) method in the main page of the test-app. By modifying this method, you can configure the app to: + +* **Execute only the tests from a specific test module**: + +```typescript +function runTests() { + setTimeout(() => tests.runAll('HTTP'), 10); +} +``` + +* **Execute single test from a specific test module**: + +```typescript +function runTests() { + setTimeout(() => tests.runAll('HTTP.test_getJSON'), 10); +} +``` + +## Register Test Module +Test modules are organized in separate files and are registered in the [`tests/app/testRunner.ts`](tests/app/testRunner.ts) file: + +```typescript +import * as httpTests from "./http/http-tests"; +allTests["HTTP"] = httpTests; +``` + +## Writing Test Module +The test modules are actually TypeScript modules which export unit tests and hooks as functions following this convention: + +* All exported functions which with a `test` prefix are unit-tests. +* The `setUpModule()` hook is called once - before all the tests in the module. +* The `setUp()` hook is called before each tests. +* The `tearDown()` hook called after each tests. +* The `tearDownModule()` hook is called once - after all the tests in the module. + +# Asserting +A test will fail if assert is not satisfied or if an error is thrown during execution. +There is a large set of asserting functions available in the [`tests/app/TKUnit.ts`](tests/app/TKUnit.ts) module. We recommend using those in your tests. + +```typescript +import * as TKUnit from "../TKUnit"; + +export function testSomethingWorksFast() { + let arr = [1, 2, 3]; + + TKUnit.assertNotNull(arr, "Array should be defined"); + TKUnit.assertTrue(arr[2] > 2, "arr[2] is not big enough") + TKUnit.assertEqual(arr.length, 3, "Array length should be 3"); +} +``` + +# Async Tests + +Unit tests can accept a single argument - a done callback. The test framework will wait for the `done()` callback to be called (or the test to timeout) before moving on. +Passing an `Error` to the `done()` callback will cause the test to fail: + +```typescript +export function test_getJSON(done) { + http.getJSON("https://httpbin.org/get").then( + (result) => { done(); }, // success + (error) => { done(error); }); // fail +}; +``` diff --git a/running-tests.md b/running-tests.md deleted file mode 100644 index 1d3d4b8e4..000000000 --- a/running-tests.md +++ /dev/null @@ -1,59 +0,0 @@ -Running NativeScript Tests -========================= - - -# Details -NativeScript is a framework for building applications on mobile devices. Many -of its components are UI elements which get tested most efficiently on the -respective device or simulator/emulator. Thus, running the tests involves -the following steps: - -- Create a NativeScript project -- Build it to a native image -- Start a simulator/emulator -- Deploy the application image -- Start the application -- Monitor its output -- Gather test output - -These steps are automated via the `run-testsapp.grunt.js` grunt script, located -under the `build` directory. It gets called by the main `gruntfile.js`, but is -split to a separate file for simplicity. - -# Prerequisites -- Node JS -- grunt -- NativeScript CLI -- Android/iOS setup -- expect - -# Arguments: - ->As this is a [grunt](http://gruntjs.com/) script, the arguments are passed - the grunt way (`--argName=argValue`) - -- `platform`: The platform to run the tests application on: iOS or Android -- `showEmu`: [Optional] Specifies whether the emulator should get launched -in a window or headless mode. Defaults to `false`. -- `modulesPath`: [Optional] The path to the tns-core-modules npm package -to be tested. Defaults to the npm package, located in the current -`bin/dist/` folder. The modules must have been built before that. -- `tnsPath`: [Optional] The path to the NativeScript executable. If not -found, the globally installed `tns` gets called. -- `emuPId`: The ID of the emulator process. This one is used to refresh the -emulator process, as the emulator sometimes hangs. -- `avd`: The name of the Android Virtual Device or the iOS simulator GUID -to be started to run the tests. -- `logFilePath`: [Optional] The path to the file, which the test app run -log will get saved to. Defaults to "./TestRunResult.txt". -- `runtimePath`: [Optional] The path to a custom iOS or Android Runtime -package to have the tests run onto. If not specified, the newest available -build on [npmjs.com](http://npmjs.com) - -[tns-ios](https://www.npmjs.com/package/tns-ios) or -[tns-android](https://www.npmjs.com/package/tns-android). - -# Sample run: -``` -grunt testsapp --platform=Android [--tnsPath="tns"] --emuPId=".*emulator64-x86" ---avd="Api19" [--logFilePath="./TestRunResult.txt"] [--androidRuntimePath="./tns-android.tgz"] --showEmu=true -``` diff --git a/source-control.md b/source-control.md deleted file mode 100644 index 730504ef3..000000000 --- a/source-control.md +++ /dev/null @@ -1,158 +0,0 @@ -#Working with source control - -As a reference point, you might find it useful to check the following [Git tutorial](http://rogerdudler.github.io/git-guide/) and the [Git cheatsheet] (http://www.git-tower.com/files/cheatsheet/Git_Cheat_Sheet_grey.pdf). - -*** -### (!) Important - Before you start -1.`git config --global branch.autosetuprebase always` will make `git pull` to use `--rebase`. (shall works with TortoiseGit as well.) - -2.`git config --global push.default upstream` make `git push --force` to work with upstream of current branch only. - -*** - -When working on a new feature/enhancement, or fixing a bug, every team member should use a separate feature branch. In order to make it easy to differentiate between member branches you should prefix its name with your user name - I.e. such name will look like this **dvarchev/Cordova-mocks-update**. In order to separate different words in branch name use dashes instead of spaces. - -## Create a new feature branch -In order to create a new branch simply run the following **git checkout -b ** command. - -`git checkout -b dvarchev/Cordova-mocks-update` - -If you are currently on another branch (not master) you need to append **master** at the end. This will create the new branch out of the master and not your current one. - -`git checkout -b dvarchev/Cordova-mocks-update master` - -## Publishing a feature branch to origin -When working on a separate branch you would usually push it to GitHub. You can use the **git push -u origin ** command for that. - -`git push -u origin dvarchev/Cordova-mocks-update` - -If you want to have a shorter name for your branch locally and the verbose name only on the server branch, here is how you create and push the branch to the server (local name "mocks", server name "dvarchev/Cordova-mocks-update") - -```bash -git checkout -b mocks -git push -u origin mocks:dvarchev/Cordova-mocks-update -``` - -This way you will easily switch branches locally and on the server their name will be properly descriptive. - -## Get someone else's branch locally - -If you need to start working on someone else's branch, you can set it up locally as follows (the remote branch is again called "dvarchev/Cordova-mocks-update" and you will map it to a local branch called "mocks"): - -```bash -git checkout -b mocks origin/dvarchev/Cordova-mocks-update -``` - -Your upstream will be set automatically and you shouldn't worry where your local branch is pointing to. - -## Updating a feature branch with latest changes from master -While working on a feature branch you need to regularly update with the latest changes from the master branch. You should do that using the fetch & rebase commands. - -```bash -git fetch -git rebase origin/master -``` - -You can also switch to your master, pull latest changes and rebase your feature branch. This way you'll have both your local master and local feature branch up to date. - -```bash -git checkout master -git pull --rebase -git checkout dvarchev/Cordova-mocks-update -git rebase master -``` -**Note: If you use TortoiseGit to pull see [tip](#global-rebase) at the bottom how to make it rebase on pull** - -If you have previously pushed your feature branch to the remote, push the updates as well. - -`git push origin dvarchev/Cordova-mocks-update --force` - -**WARNING: This line may reset remote to you local state on ALL branches including *master*. -See [tip](#push-upstream) at the bottom on how to make it push only to upstream of current branch.** - -## Finishing work on feature branch. - -When you are finished working on your feature branch, you need to create a Pull Request from your branch to master(or **release** during stabilization phase). Your Pull Request must be reviewed before being merged. -* Update your branch with latest changes and push it to GitHub. -* Use the GitHub web interface to open a Pull Request from your branch to master. -* Your Pull Request will be automatically built by our Jenkins build server and its status will be update accordingly. -* You need **2 ThumbUp-s (:+1:) and a green build** for your Pull Request to be accepted. Only small bug fixes can go with 1 ThumbUp. -* If you need to make additional changes push them again to the same branch. **You should rebase** your branch in order to maintain clean history about the changes (comments will not be lost). You can also squash your commits accordingly. After you make the changes **you need again 2 ThumbUp-s and a green build**. -* Once your Pull Request is reviewed and accepted you can merge it. **You should rebase** your branch in order to maintain clean history. -* Merging: - - manually - please use the `--no-ff` option if there are more than one commits to merge. otherwise, do a fast-forward merge as the merge commit adds no value. - - using the GitHub web interface, click the "Merge" button -* Delete the remote branch after merge - - -# Release Branch Management - -On the end of every milestone a "release" branch is created in the Icenium repository to stabilize the build for the upcoming release. - -## Creating the release branch - -After we create the release branch we keep it until we create the next one(for the next milestone release). This allows us to create hot-fixes directly on the release branch. -The workflow for creating the release branch is: - -- Make sure a release tag has been created for the previous release. - -- Delete the release branch locally and remotely - -```bash -git branch -D release -git push origin :release -``` - -- Create the release branch from master or any commit you like - -```bash -git checkout master -git branch release -``` - -- Push the local release branch you just created to the Icenium repository - -```bash -git push origin release -``` - -## Fixing bugs during stabilization -###I have a change that has to be applied to the release. What should I do? - -You have to commit your changes only on the release branch. The release branch will be merged into master occasionally and your changes will end up in master after all. - -## Git Tortoise Tips - -1. After you install Git Tortoise and Generate your SSH key (how to generate PuTTY key) you should save the key using the generator (as described in the tutorial). Then you should right click somewhere on your file system (where the project is located) and select TortoiseGit -> Settings -> Git -> Remote. Then from the Remote section select "origin" and choose the file where your key is located. Save and you should be able to authenticate from now on. - -#Guidelines for commit messages -### All-in-one example: -``` text -Summarize clearly in one line what the commit is about - -Describe the problem the commit solves or the use -case for a new feature. Justify why you chose -the particular solution. Don't describe the code, -describe the intent and the approach. -``` - -### Summary: -* Summary is the first line of the message. This is the line that'll be seen most often, make it count. -* Summary *should* be around 50 chars and **must** be less than 72 (Github max length before wrap). -* Write the summary line and description of what you have done in the imperative mode, that is as if you were commanding someone. Write “fix”, “add”, “change” instead of “fixed”, “added”, “changed”. This is the convention by the messages generated by git commands, so committing after git revert will yield a consistent message. -* Avoid ending the summary line with a period -* Leave a blank line after the summary (and between other paragraphs). - -### Body: -* Bullet points are okay. -* If it seems difficult to summarize what your commit does, it may be because it includes several logical changes or bug fixes, and are better split up into several commits. -* Wrap it to around 72 lines. - -### TeamPulse Items: -* If the commit is related to a TeamPulse item (story or bug), add #id (#123 for example) on a new line in the end of commit message body. Example: fixes #123123 -* Do not add TeamPulse item id in the commit message summary. -* Do not add full links to the TeamPulse item in the commit message. Consider adding that information in the Pull Request description. - -See also: -* http://who-t.blogspot.com/2009/12/on-commit-messages.html -* https://github.com/blog/926-shiny-new-commit-styles