Compare commits

...

32 Commits

Author SHA1 Message Date
1e1af7ffcb docs: changelog for 5.0.0-beta.2 release 2017-08-02 13:23:27 -07:00
a84b2bc945 release: cut the 5.0.0-beta.2 release 2017-08-02 13:21:07 -07:00
7abcb99d57 docs: add changelog for 4.3.3 2017-08-02 13:19:00 -07:00
49cd8513e4 feat(router): add events tracking activation of individual routes
* Adds `ChildActivationStart` and `ChildActivationEnd`
* Adds test to verify the PreActivation phase of routing
2017-08-01 10:44:00 -07:00
82b067fc40 build: ignore node_modules for tslint 2017-08-01 10:13:44 -07:00
9479a106bb build: enable TSLint on the packages folder 2017-07-31 15:47:57 -07:00
e64b54b67b fix(compiler): do not consider arguments when determining recursion
The static reflectory check for macro function recursion was too
agressive and disallowed calling a function with argument that also
calls the same function. For example, it disallowed nested animation
groups.

Fixes: #17467
2017-07-31 13:42:31 -07:00
cc2a4c41f9 build(aio): fix warning about missing <h1>
Fixes #17549
2017-07-31 13:40:07 -07:00
a11542a375 docs(aio): fixed list format in FormArray section 2017-07-31 11:31:05 -07:00
b6c4af6495 feat(compiler-cli): automatically lower lambda expressions in metadata 2017-07-31 11:30:44 -07:00
67dff7bd5d feat(tsc-wrapped): allow values to be substituted by collector clients
Also reenabled tests that were unintentionally disabled when they were
moved from tools/@angular.
2017-07-31 11:30:44 -07:00
381471d338 fix(compiler): fix for element needing implicit parent placed in top-level ng-container
fixes #18314
2017-07-31 11:30:19 -07:00
ebef5e697a feat(forms): add options arg to abstract controls
FormControls, FormGroups, and FormArrays now optionally accept an options
object as their second argument. Validators and async validators can be
passed in as part of this options object (though they can still be passed
in as the second and third arg as before).

```ts
const c = new FormControl(, {
   validators: [Validators.required],
   asyncValidators: [myAsyncValidator]
});
```

This commit also adds support for passing arrays of validators and async
validators to FormGroups and FormArrays, which formerly only accepted
individual functions.

```ts
const g = new FormGroup({
   one: new FormControl()
}, [myPasswordValidator, myOtherValidator]);
```

This change paves the way for adding more options to AbstractControls,
such as more fine-grained control of validation timing.
2017-07-31 11:29:32 -07:00
d71ae278ef fix(aio): fix links to source for paths with symlinks
Fixes #18353
2017-07-28 15:28:59 -07:00
46207538ef ci: short-circuit npm install for aio builds that use yarn only 2017-07-28 15:28:28 -07:00
71eb7437b6 docs(aio): delay ngUpgrade e2e test to avoid flakes 2017-07-28 15:28:28 -07:00
b5ffbe342b build: short-circuit build for AIO tasks 2017-07-28 15:28:28 -07:00
0f79223008 docs(aio): fix deprecated protractor API usage
`browser.getLocationAbsUrl()` is deprecated.
We should use `browser.getCurrentUrl()` instead.
2017-07-28 15:28:28 -07:00
a085223331 ci(aio): test the example e2e files using local build of Angular 2017-07-28 15:28:28 -07:00
c383048259 build(aio): ignore generated aot files
Assets such as images and data which are generated
by the aot build were not being ignored.
2017-07-28 15:28:28 -07:00
b18eb04b46 docs(aio): remove generated styles.css file
This file should have been ignored as it is created
during the build of the example
2017-07-28 15:28:28 -07:00
c8c2ab012a build(aio): support overriding the Angular packages in examples with locally built ones 2017-07-28 15:28:28 -07:00
ecff8e6c93 build(aio): refactor and test the example-boilerplate tool 2017-07-28 15:28:28 -07:00
51f1da1b85 ci: shard the aio example e2e tests 2017-07-28 15:28:28 -07:00
a5e18c4cdf ci(aio): support sharding of example e2e tests 2017-07-28 15:28:28 -07:00
cf6284656f build(aio): upgrade @angular/material to 2.0.0-meta.8 2017-07-28 15:26:45 -07:00
3182ddaf3e build(aio): upgrade @angular/* to 4.3.1 2017-07-28 15:26:45 -07:00
416ed691e5 docs(aio): fix URLSearchParams interface link to MDN
Fixes #18367
2017-07-28 15:26:04 -07:00
0fb7484d51 refactor(aio): move content-specific images to content/images/
Fixes #17053
2017-07-28 15:06:49 -07:00
6a3454e81e refactor(aio): rename unused directories to _unused 2017-07-28 15:06:49 -07:00
c3fbe87012 fix(aio): fix link to logo in example 2017-07-28 15:06:49 -07:00
24117d7a49 refactor(aio): move unused images to unused directories
This prevents the ServiceWorker from prefetching unnecessary files.
2017-07-28 15:06:49 -07:00
176 changed files with 2802 additions and 1350 deletions

View File

@ -55,7 +55,8 @@ env:
- CI_MODE=browserstack_optional
- CI_MODE=docs_test
- CI_MODE=aio
- CI_MODE=aio_e2e
- CI_MODE=aio_e2e AIO_SHARD=0
- CI_MODE=aio_e2e AIO_SHARD=1
- CI_MODE=bazel
matrix:
@ -63,7 +64,6 @@ matrix:
allow_failures:
- env: "CI_MODE=saucelabs_optional"
- env: "CI_MODE=browserstack_optional"
- env: "CI_MODE=aio_e2e"
before_install:
# source the env.sh script so that the exported variables are available to other scripts later on

View File

@ -1,3 +1,30 @@
<a name="5.0.0-beta.2"></a>
# [5.0.0-beta.2](https://github.com/angular/angular/compare/5.0.0-beta.1...5.0.0-beta.2) (2017-08-02)
### Bug Fixes
* **compiler:** do not consider arguments when determining recursion ([e64b54b](https://github.com/angular/angular/commit/e64b54b))
* **compiler:** fix for element needing implicit parent placed in top-level ng-container ([381471d](https://github.com/angular/angular/commit/381471d)), closes [#18314](https://github.com/angular/angular/issues/18314)
### Features
* **forms:** add options arg to abstract controls ([ebef5e6](https://github.com/angular/angular/commit/ebef5e6))
* **router:** add events tracking activation of individual routes ([49cd851](https://github.com/angular/angular/commit/49cd851))
<a name="4.3.3"></a>
## [4.3.3](https://github.com/angular/angular/compare/4.3.2...4.3.3) (2017-08-02)
### Bug Fixes
* **compiler:** fix for element needing implicit parent placed in top-level ng-container ([f5cbc2e](https://github.com/angular/angular/commit/f5cbc2e)), closes [#18314](https://github.com/angular/angular/issues/18314)
<a name="5.0.0-beta.1"></a>
# [5.0.0-beta.1](https://github.com/angular/angular/compare/5.0.0-beta.0...5.0.0-beta.1) (2017-07-27)

View File

@ -43,13 +43,9 @@ dist/
**/app/**/*.ajs.js
# aot
**/*.ngfactory.ts
**/*.ngsummary.json
**/*.ngsummary.ts
**/*.shim.ngstyle.ts
**/*.metadata.json
!aot/bs-config.json
!aot/index.html
*/aot/**/*
!*/aot/bs-config.json
!*/aot/index.html
!rollup-config.js
# i18n

View File

@ -9,7 +9,7 @@ export class AppComponent {
wolves = 0;
gender = 'f';
fly = true;
logo = 'https://angular.io/resources/images/logos/angular/angular.png';
logo = 'https://angular.io/assets/images/logos/angular/angular.png';
count = 3;
heroes: string[] = ['Magneta', 'Celeritas', 'Dynama'];
inc(i: number) {

View File

@ -1,116 +0,0 @@
/* #docregion , quickstart, toh */
/* Master Styles */
h1 {
color: #369;
font-family: Arial, Helvetica, sans-serif;
font-size: 250%;
}
h2, h3 {
color: #444;
font-family: Arial, Helvetica, sans-serif;
font-weight: lighter;
}
body {
margin: 2em;
}
/* #enddocregion quickstart */
body, input[text], button {
color: #888;
font-family: Cambria, Georgia;
}
/* #enddocregion toh */
a {
cursor: pointer;
cursor: hand;
}
button {
font-family: Arial;
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
cursor: hand;
}
button:hover {
background-color: #cfd8dc;
}
button:disabled {
background-color: #eee;
color: #aaa;
cursor: auto;
}
/* Navigation link styles */
nav a {
padding: 5px 10px;
text-decoration: none;
margin-right: 10px;
margin-top: 10px;
display: inline-block;
background-color: #eee;
border-radius: 4px;
}
nav a:visited, a:link {
color: #607D8B;
}
nav a:hover {
color: #039be5;
background-color: #CFD8DC;
}
nav a.active {
color: #039be5;
}
/* items class */
.items {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 24em;
}
.items li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.items li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.items li.selected {
background-color: #CFD8DC;
color: white;
}
.items li.selected:hover {
background-color: #BBD8DC;
}
.items .text {
position: relative;
top: -3px;
}
.items .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
/* #docregion toh */
/* everywhere else */
* {
font-family: Arial, Helvetica, sans-serif;
}

View File

@ -9,7 +9,8 @@ describe('PhoneCat Application', function() {
it('should redirect `index.html` to `index.html#!/phones', function() {
browser.get('index.html');
expect(browser.getLocationAbsUrl()).toBe('/phones');
browser.sleep(1000); // Not sure why this is needed but it is. The route change works fine.
expect(browser.getCurrentUrl()).toMatch(/\/phones$/);
});
describe('View: Phone list', function() {
@ -65,7 +66,7 @@ describe('PhoneCat Application', function() {
element.all(by.css('.phones li a')).first().click();
browser.sleep(1000); // Not sure why this is needed but it is. The route change works fine.
expect(browser.getLocationAbsUrl()).toBe('/phones/nexus-s');
expect(browser.getCurrentUrl()).toMatch(/\/phones\/nexus-s$/);
});
});

View File

@ -1080,8 +1080,11 @@ To get access to the `FormArray` class, import it into `hero-detail.component.ts
To _work_ with a `FormArray` you do the following:
1. Define the items (`FormControls` or `FormGroups`) in the array.
1. Initialize the array with items created from data in the _data model_.
1. Add and remove items as the user requires.
In this guide, you define a `FormArray` for `Hero.addresses` and

View File

@ -1830,7 +1830,7 @@ Finally, you activate the observable with `subscribe` method and (re)set the com
#### _ParamMap_ API
The `ParamMap` API is inspired by the [URLSearchParams interface](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParamsOPut). It provides methods
The `ParamMap` API is inspired by the [URLSearchParams interface](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams). It provides methods
to handle parameter access for both route parameters (`paramMap`) and query parameters (`queryParamMap`).
<table>

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

View File

Before

Width:  |  Height:  |  Size: 257 KiB

After

Width:  |  Height:  |  Size: 257 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -8,7 +8,7 @@
<div class="feature-section">
<div class="feature-header">
<div class="text-headline">Cross Platform</div>
<img src="assets/images/icons/feature-icon.svg" height="70px">
<img src="generated/images/marketing/features/feature-icon.svg" height="70px">
</div>
<div class="feature-row">
@ -34,7 +34,7 @@
<div class="feature-section">
<div class="feature-header">
<div class="text-headline">Speed and Performance</div>
<img src="assets/images/icons/feature-icon.svg" height="70px">
<img src="generated/images/marketing/features/feature-icon.svg" height="70px">
</div>
<div class="feature-row">
@ -59,7 +59,7 @@
<div class="feature-section">
<div class="feature-header">
<div class="text-headline">Productivity</div>
<img src="assets/images/icons/feature-icon.svg" height="70px">
<img src="generated/images/marketing/features/feature-icon.svg" height="70px">
</div>
<div class="feature-row">
@ -84,7 +84,7 @@
<div class="feature-section">
<div class="feature-header">
<div class="text-headline">Full Development Story</div>
<img src="assets/images/icons/feature-icon.svg" height="70px">
<img src="generated/images/marketing/features/feature-icon.svg" height="70px">
</div>
<div class="feature-row">

View File

@ -1,10 +1,10 @@
<!--FULL HEADER BLOCK-->
<!-- FULL HEADER BLOCK -->
<header>
<!--BACKGROUND IMAGE-->
<!-- BACKGROUND IMAGE -->
<div class="background-sky hero"></div>
<!--INTRO SECTION -->
<!-- INTRO SECTION -->
<section id="intro">
<!-- LOGO -->
@ -12,35 +12,37 @@
<img src="assets/images/logos/angular/angular.svg"/>
</div>
<!-- CONTAINER -->
<!-- CONTAINER -->
<div class="homepage-container">
<!-- container content starts -->
<div class="hero-headline no-toc">One framework.<br>Mobile &amp; desktop.</div>
<a class="button hero-cta" href="guide/quickstart">Get Started</a>
</div><!-- CONTAINER END -->
</section>
</div>
</section>
</header>
<!-- MAIN CONTENT -->
<article>
<h1 class="no-toc" style="display: none"></h1>
<div class="home-rows">
<!--Announcement Bar-->
<!-- Announcement Bar -->
<div class="homepage-container">
<div class="announcement-bar">
<img src="generated/images/marketing/angular-mix.png" height="40" width="151">
<img src="generated/images/marketing/home/angular-mix.png" height="40" width="151">
<p>Join us at our newest event, October 2017</p>
<a class="button" href="https://angularmix.com/">Learn More</a>
</div>
</div>
</div>
<!-- Group 1-->
<!-- Group 1 -->
<div layout="row" layout-xs="column" class="home-row homepage-container">
<div class="promo-img-container promo-1">
<div>
<img height="222" width="340" src="assets/images/home/responsive-framework.svg" alt="responsive framework">
<img height="222" width="340" src="generated/images/marketing/home/responsive-framework.svg" alt="responsive framework">
</div>
</div>
@ -53,7 +55,8 @@
</div>
</div>
<hr>
<!-- Group 2-->
<!-- Group 2 -->
<div layout="row" layout-xs="column" class="home-row">
<div class="text-container">
<div class="text-block">
@ -65,16 +68,16 @@
<div class="promo-img-container promo-2">
<div>
<img height="222" width="323" src="assets/images/home/speed-performance.svg" alt="speed and performance">
<img height="222" width="323" src="generated/images/marketing/home/speed-performance.svg" alt="speed and performance">
</div>
</div>
</div>
<hr>
<!-- Group 3-->
<!-- Group 3 -->
<div layout="row" layout-xs="column" class="home-row">
<div class="promo-img-container promo-3">
<div><img src="assets/images/home/joyful-development.png" alt="IDE example"></div>
<div><img src="generated/images/marketing/home/joyful-development.svg" alt="IDE example"></div>
</div>
<div class="text-container">
@ -88,9 +91,8 @@
</div>
<hr>
<!-- Group 4-->
<!-- Group 4 -->
<div layout="row" layout-xs="column" class="home-row">
<div class="text-container">
<div class="text-block l-pad-top-2">
<div class="text-headline">Loved by Millions</div>
@ -100,25 +102,24 @@
<div class="promo-img-container promo-4">
<div>
<img src="assets/images/home/loved-by-millions.png" alt="angular on the map" width="455" height="228">
<img src="generated/images/marketing/home/loved-by-millions.svg" alt="angular on the map" width="455" height="228">
</div>
</div>
</div>
<!-- CTA CARDS -->
<div layout="row" layout-xs="column" class="home-row">
<a href="guide/quickstart">
<div class="card">
<img src="assets/images/icons/code-icon.svg" height="70px">
<!-- CTA CARDS -->
<div layout="row" layout-xs="column" class="home-row">
<a href="guide/quickstart">
<div class="card">
<img src="generated/images/marketing/home/code-icon.svg" height="70px">
<div class="card-text-container">
<div class="text-headline">Get Started</div>
<p>Start building your Angular application.</p>
</div>
</div>
</a>
</div>
</div>
</a>
</div>
</div> <!-- end of home rows -->
</div><!-- end of home rows -->
</article>

View File

@ -10,8 +10,8 @@
},
"static.ignore": [
"\\.js\\.map$",
"^/assets/images/.*/unused/",
"^/generated/(?:docs/(?!api/api-list\\.json).*|images|live-examples|zips)/"
"^(?:/|\\\\)assets(?:/|\\\\)images(?:/|\\\\).*(?:/|\\\\)_unused(?:/|\\\\)",
"^(?:/|\\\\)generated(?:/|\\\\)(?:docs(?:/|\\\\)(?!api(?:/|\\\\)api-list\\.json).*|images(?:/|\\\\)(?!marketing(?:/|\\\\)).*|live-examples|zips)(?:/|\\\\)"
],
"static.versioned": [
"\\.[0-9a-z]{20}\\."

View File

@ -33,8 +33,9 @@
"docs-test": "node tools/transforms/test.js",
"serve-and-sync": "concurrently --kill-others \"yarn docs-watch\" \"yarn start\"",
"~~update-webdriver": "webdriver-manager update --standalone false --gecko false",
"boilerplate:add": "node ./tools/examples/add-example-boilerplate add",
"boilerplate:remove": "node ./tools/examples/add-example-boilerplate remove",
"boilerplate:add": "node ./tools/examples/example-boilerplate add",
"boilerplate:remove": "node ./tools/examples/example-boilerplate remove",
"boilerplate:test": "node tools/examples/test.js",
"generate-plunkers": "node ./tools/plunker-builder/generatePlunkers",
"generate-zips": "node ./tools/example-zipper/generateZips",
"sw-manifest": "ngu-sw-manifest --dist dist --in ngsw-manifest.json --out dist/ngsw-manifest.json",
@ -48,17 +49,18 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^4.2.4",
"@angular/common": "^4.2.4",
"@angular/compiler": "^4.2.4",
"@angular/core": "^4.2.4",
"@angular/forms": "^4.2.4",
"@angular/http": "^4.2.4",
"@angular/material": "^2.0.0-beta.7",
"@angular/platform-browser": "^4.2.4",
"@angular/platform-browser-dynamic": "^4.2.4",
"@angular/platform-server": "^4.2.4",
"@angular/router": "^4.2.4",
"@angular/animations": "^4.3.1",
"@angular/cdk": "^2.0.0-beta.8",
"@angular/common": "^4.3.1",
"@angular/compiler": "^4.3.1",
"@angular/core": "^4.3.1",
"@angular/forms": "^4.3.1",
"@angular/http": "^4.3.1",
"@angular/material": "^2.0.0-beta.8",
"@angular/platform-browser": "^4.3.1",
"@angular/platform-browser-dynamic": "^4.3.1",
"@angular/platform-server": "^4.3.1",
"@angular/router": "^4.3.1",
"@angular/service-worker": "^1.0.0-beta.16",
"classlist.js": "^1.1.20150312",
"core-js": "^2.4.1",
@ -72,7 +74,7 @@
},
"devDependencies": {
"@angular/cli": "angular/cli-builds#webpack-next",
"@angular/compiler-cli": "^4.2.4",
"@angular/compiler-cli": "^4.3.1",
"@types/jasmine": "^2.5.52",
"@types/node": "~6.0.60",
"archiver": "^1.3.0",
@ -81,7 +83,7 @@
"concurrently": "^3.4.0",
"cross-spawn": "^5.1.0",
"dgeni": "^0.4.7",
"dgeni-packages": "^0.20.0-rc.6",
"dgeni-packages": "^0.20.0",
"entities": "^1.1.1",
"eslint": "^3.19.0",
"eslint-plugin-jasmine": "^2.2.0",

View File

@ -76,8 +76,8 @@ export class AppComponent implements OnInit {
get homeImageUrl() {
return this.isSideBySide ?
'assets/images/logos/standard/logo-nav@2x.png' :
'assets/images/logos/standard/shield-large.svg';
'assets/images/logos/angular/logo-nav@2x.png' :
'assets/images/logos/angular/shield-large.svg';
}
get isOpened() { return this.isSideBySide && this.isSideNavDoc; }
get mode() { return this.isSideBySide ? 'side' : 'over'; }

View File

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 113 KiB

View File

Before

Width:  |  Height:  |  Size: 178 KiB

After

Width:  |  Height:  |  Size: 178 KiB

View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 519 B

After

Width:  |  Height:  |  Size: 519 B

View File

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 131 KiB

View File

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 422 B

After

Width:  |  Height:  |  Size: 422 B

View File

Before

Width:  |  Height:  |  Size: 783 B

After

Width:  |  Height:  |  Size: 783 B

View File

Before

Width:  |  Height:  |  Size: 452 B

After

Width:  |  Height:  |  Size: 452 B

View File

Before

Width:  |  Height:  |  Size: 864 B

After

Width:  |  Height:  |  Size: 864 B

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

Before

Width:  |  Height:  |  Size: 782 B

After

Width:  |  Height:  |  Size: 782 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -1,148 +0,0 @@
const fs = fsExtra = require('fs-extra');
const globby = require('globby');
const path = require('path');
const Q = require("q");
const shelljs = require('shelljs');
const EXAMPLES_PATH = path.join(__dirname, '/../../content/examples');
const SHARED_PATH = path.join(__dirname, '/shared');
const BOILERPLATE_PATH = path.join(SHARED_PATH, 'boilerplate');
const EXAMPLES_TESTING_PATH = path.join(EXAMPLES_PATH, 'testing');
const files = {
exampleBoilerplate: [
'src/styles.css',
'src/systemjs-angular-loader.js',
'src/systemjs.config.js',
'src/tsconfig.json',
'bs-config.json',
'bs-config.e2e.json',
'package.json',
'tslint.json'
],
exampleUnitTestingBoilerplate: [
'src/browser-test-shim.js',
'karma-test-shim.js',
'karma.conf.js'
],
exampleConfigFilename: 'example-config.json'
};
// requires admin access because it adds symlinks
function add() {
const realPath = path.join(SHARED_PATH, '/node_modules');
const nodeModulesPaths = getNodeModulesPaths(EXAMPLES_PATH);
// we install the examples modules first
installNodeModules();
nodeModulesPaths.map((linkPath) => {
fs.ensureSymlinkSync(realPath, linkPath);
});
return copyExampleBoilerplate();
}
function copyExampleBoilerplate() {
console.log('Copying example boilerplate files');
const examplePaths = getExamplePaths(EXAMPLES_PATH);
// Make boilerplate files read-only to avoid that they be edited by mistake.
const destFileMode = '444';
let foo = copyFiles(files.exampleBoilerplate, BOILERPLATE_PATH, examplePaths, destFileMode)
// copy the unit test boilerplate
.then(() => {
const unittestPaths = getUnitTestingPaths(EXAMPLES_PATH);
return copyFiles(files.exampleUnitTestingBoilerplate, EXAMPLES_TESTING_PATH, unittestPaths, destFileMode);
})
.catch((err) => {
console.error(err);
throw err;
});
}
// Copies fileNames into destPaths, setting the mode of the
// files at the destination as optional_destFileMode if given.
// returns a promise
function copyFiles(fileNames, originPath, destPaths, optional_destFileMode) {
const copy = Q.denodeify(fsExtra.copy);
const chmod = Q.denodeify(fsExtra.chmod);
let copyPromises = [];
destPaths.map((destPath) => {
fileNames.forEach((fileName) => {
const originName = path.join(originPath, fileName);
const destName = path.join(destPath, fileName);
let p = copy(originName, destName, { clobber: true});
if(optional_destFileMode !== undefined) {
p = p.then(() => {
return chmod(destName, optional_destFileMode);
});
}
copyPromises.push(p);
});
});
return Q.all(copyPromises);
}
function getExamplePaths(basePath, includeBase) {
// includeBase defaults to false
return getPaths(basePath, files.exampleConfigFilename, includeBase);
}
function getFilenames(basePath, filename, includeBase) {
let includePatterns = [path.join(basePath, "**/" + filename)];
if (!includeBase) {
// ignore (skip) the top level version.
includePatterns.push("!" + path.join(basePath, "/" + filename));
}
// ignore (skip) the files in BOILERPLATE_PATH.
includePatterns.push("!" + path.join(BOILERPLATE_PATH, "/" + filename));
const nmPattern = path.join(basePath, "**/node_modules/**");
return globby.sync(includePatterns, {ignore: [nmPattern]});
}
function getNodeModulesPaths(basePath) {
return getExamplePaths(basePath).map((examplePath) => {
return path.join(examplePath, "/node_modules");
});
}
function getPaths(basePath, filename, includeBase) {
const filenames = getFilenames(basePath, filename, includeBase);
return filenames.map((fileName) => {
return path.dirname(fileName);
});
}
function getUnitTestingPaths(basePath) {
const examples = getPaths(basePath, files.exampleConfigFilename, true);
return examples.filter((example) => {
const exampleConfig = fs.readJsonSync(`${example}/${files.exampleConfigFilename}`, {throws: false});
return exampleConfig && !!exampleConfig.unittesting;
});
}
function installNodeModules() {
shelljs.exec('yarn', {cwd: SHARED_PATH});
}
function remove() {
shelljs.exec('git clean -xdf', {cwd: EXAMPLES_PATH});
}
module.exports = {
add: add,
remove: remove
};
// being executed from shell script
switch (process.argv[2]) {
case 'add':
add();
break;
case 'remove':
remove();
break;
default:
console.error(`There is no function with the name: ${process.argv}`);
}

View File

@ -0,0 +1,140 @@
const fs = require('fs-extra');
const glob = require('glob');
const path = require('canonical-path');
const shelljs = require('shelljs');
const yargs = require('yargs');
const SHARED_PATH = path.resolve(__dirname, 'shared');
const SHARED_NODE_MODULES_PATH = path.resolve(SHARED_PATH, 'node_modules');
const BOILERPLATE_BASE_PATH = path.resolve(SHARED_PATH, 'boilerplate');
const EXAMPLES_BASE_PATH = path.resolve(__dirname, '../../content/examples');
const TESTING_BASE_PATH = path.resolve(EXAMPLES_BASE_PATH, 'testing');
const BOILERPLATE_SRC_PATHS = [
'src/styles.css',
'src/systemjs-angular-loader.js',
'src/systemjs.config.js',
'src/tsconfig.json',
'bs-config.json',
'bs-config.e2e.json',
'package.json',
'tslint.json'
];
const BOILERPLATE_TEST_PATHS = [
'src/browser-test-shim.js',
'karma-test-shim.js',
'karma.conf.js'
];
const ANGULAR_DIST_PATH = path.resolve(__dirname, '../../../dist');
const ANGULAR_PACKAGES_PATH = path.resolve(ANGULAR_DIST_PATH, 'packages-dist');
const ANGULAR_PACKAGES = [
'animations',
'common',
'compiler',
'compiler-cli',
'core',
'forms',
'http',
'platform-browser',
'platform-browser-dynamic',
'platform-server',
'router',
'upgrade',
];
const ANGULAR_TOOLS_PACKAGES_PATH = path.resolve(ANGULAR_DIST_PATH, 'tools', '@angular');
const ANGULAR_TOOLS_PACKAGES = [
'tsc-wrapped'
];
const EXAMPLE_CONFIG_FILENAME = 'example-config.json';
class ExampleBoilerPlate {
/**
* Add boilerplate files to all the examples
*
* @param useLocal if true then overwrite the Angular library files with locally built ones
*/
add(useLocal) {
// first install the shared node_modules
this.installNodeModules(SHARED_PATH);
// Replace the Angular packages with those from the dist folder, if necessary
if (useLocal) {
ANGULAR_PACKAGES.forEach(packageName => this.overridePackage(ANGULAR_PACKAGES_PATH, packageName));
ANGULAR_TOOLS_PACKAGES.forEach(packageName => this.overridePackage(ANGULAR_TOOLS_PACKAGES_PATH, packageName));
}
// Get all the examples folders, indicated by those that contain a `example-config.json` file
const exampleFolders = this.getFoldersContaining(EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, 'node_modules');
exampleFolders.forEach(exampleFolder => {
// Link the node modules - requires admin access (on Windows) because it adds symlinks
const destinationNodeModules = path.resolve(exampleFolder, 'node_modules');
fs.ensureSymlinkSync(SHARED_NODE_MODULES_PATH, destinationNodeModules);
// Copy the boilerplate source files
BOILERPLATE_SRC_PATHS.forEach(filePath => this.copyFile(BOILERPLATE_BASE_PATH, exampleFolder, filePath));
// Copy the boilerplate test files (if the example is configured to do unit testing)
const exampleConfig = this.loadJsonFile(path.resolve(exampleFolder, EXAMPLE_CONFIG_FILENAME));
if (exampleConfig.unittesting) {
BOILERPLATE_TEST_PATHS.forEach(filePath => this.copyFile(TESTING_BASE_PATH, exampleFolder, filePath));
}
});
}
/**
* Remove all the boilerplate files from all the examples
*/
remove() {
shelljs.exec('git clean -xdfq', {cwd: EXAMPLES_BASE_PATH});
}
main() {
yargs
.usage('$0 <cmd> [args]')
.command('add [--local]', 'add the boilerplate to each example',
{ local: { describe: 'Use the locally built Angular libraries, rather than ones from npm.' } },
argv => this.add(argv.local))
.command('remove', 'remove the boilerplate from each example', () => this.remove())
.demandCommand(1, 'Please supply a command from the list above')
.argv;
}
installNodeModules(basePath) {
shelljs.exec('yarn', {cwd: basePath});
}
overridePackage(basePath, packageName) {
const sourceFolder = path.resolve(basePath, packageName);
const destinationFolder = path.resolve(SHARED_NODE_MODULES_PATH, '@angular', packageName);
shelljs.rm('-rf', destinationFolder);
fs.ensureSymlinkSync(sourceFolder, destinationFolder);
}
getFoldersContaining(basePath, filename, ignore) {
const pattern = path.resolve(basePath, '**', filename);
const ignorePattern = path.resolve(basePath, '**', ignore, '**');
return glob.sync(pattern, { ignore: [ignorePattern] }).map(file => path.dirname(file));
}
copyFile(sourceFolder, destinationFolder, filePath) {
const sourcePath = path.resolve(sourceFolder, filePath);
const destinationPath = path.resolve(destinationFolder, filePath);
fs.copySync(sourcePath, destinationPath, { overwrite: true });
fs.chmodSync(destinationPath, 444);
}
loadJsonFile(filePath) {
return fs.readJsonSync(filePath, {throws: false}) || {};
}
}
module.exports = new ExampleBoilerPlate();
// If this file was run directly then run the main function,
if (require.main === module) {
module.exports.main();
}

View File

@ -0,0 +1,143 @@
const exampleBoilerPlate = require('./example-boilerplate');
const shelljs = require('shelljs');
const fs = require('fs-extra');
const glob = require('glob');
const path = require('canonical-path');
describe('example-boilerplate tool', () => {
describe('add', () => {
const numberOfBoilerPlateFiles = 8;
const numberOfBoilerPlateTestFiles = 3;
const exampleFolders = ['a/b', 'c/d'];
beforeEach(() => {
spyOn(exampleBoilerPlate, 'installNodeModules');
spyOn(exampleBoilerPlate, 'overridePackage');
spyOn(exampleBoilerPlate, 'getFoldersContaining').and.returnValue(exampleFolders);
spyOn(fs, 'ensureSymlinkSync');
spyOn(exampleBoilerPlate, 'copyFile');
spyOn(exampleBoilerPlate, 'loadJsonFile').and.returnValue({});
});
it('should install the node modules', () => {
exampleBoilerPlate.add();
expect(exampleBoilerPlate.installNodeModules).toHaveBeenCalledWith(path.resolve(__dirname, 'shared'));
});
it('should override the Angular node_modules with the locally built Angular packages if `useLocal` is true', () => {
const numberOfAngularPackages = 12;
const numberOfAngularToolsPackages = 1;
exampleBoilerPlate.add(true);
expect(exampleBoilerPlate.overridePackage).toHaveBeenCalledTimes(numberOfAngularPackages + numberOfAngularToolsPackages);
// for example
expect(exampleBoilerPlate.overridePackage).toHaveBeenCalledWith(path.resolve(__dirname, '../../../dist/packages-dist'), 'core');
expect(exampleBoilerPlate.overridePackage).toHaveBeenCalledWith(path.resolve(__dirname, '../../../dist/tools/@angular'), 'tsc-wrapped');
});
it('should process all the example folders', () => {
exampleBoilerPlate.add();
expect(exampleBoilerPlate.getFoldersContaining).toHaveBeenCalledWith(path.resolve(__dirname, '../../content/examples'), 'example-config.json', 'node_modules');
});
it('should symlink the node_modules', () => {
exampleBoilerPlate.add();
expect(fs.ensureSymlinkSync).toHaveBeenCalledTimes(exampleFolders.length);
expect(fs.ensureSymlinkSync).toHaveBeenCalledWith(path.resolve(__dirname, 'shared/node_modules'), path.resolve('a/b/node_modules'));
expect(fs.ensureSymlinkSync).toHaveBeenCalledWith(path.resolve(__dirname, 'shared/node_modules'), path.resolve('c/d/node_modules'));
});
it('should copy all the source boilerplate files', () => {
exampleBoilerPlate.add();
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledTimes(numberOfBoilerPlateFiles * exampleFolders.length);
// for example
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledWith(path.resolve(__dirname, 'shared/boilerplate'), 'a/b', 'package.json');
});
it('should try to load the example config file', () => {
exampleBoilerPlate.add();
expect(exampleBoilerPlate.loadJsonFile).toHaveBeenCalledTimes(exampleFolders.length);
expect(exampleBoilerPlate.loadJsonFile).toHaveBeenCalledWith(path.resolve('a/b/example-config.json'));
expect(exampleBoilerPlate.loadJsonFile).toHaveBeenCalledWith(path.resolve('c/d/example-config.json'));
});
it('should copy all the test boilerplate files if unit testing is configured', () => {
// configure unit testing for example a/b and not c/d
exampleBoilerPlate.loadJsonFile.and.callFake(filePath => filePath.indexOf('a/b') !== -1 ? { unittesting: true } : {});
exampleBoilerPlate.add();
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledTimes((numberOfBoilerPlateFiles * 2) + numberOfBoilerPlateTestFiles);
// for example
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledWith(path.resolve(__dirname, '../../content/examples/testing'), 'a/b', 'karma.conf.js');
expect(exampleBoilerPlate.copyFile).not.toHaveBeenCalledWith(path.resolve(__dirname, '../../content/examples/testing'), 'c/d', 'karma.conf.js');
});
});
describe('remove', () => {
it('should run `git clean`', () => {
spyOn(shelljs, 'exec');
exampleBoilerPlate.remove();
expect(shelljs.exec).toHaveBeenCalledWith('git clean -xdfq', {cwd: path.resolve(__dirname, '../../content/examples') });
});
});
describe('installNodeModules', () => {
it('should run `yarn` in the base path', () => {
spyOn(shelljs, 'exec');
exampleBoilerPlate.installNodeModules('some/base/path');
expect(shelljs.exec).toHaveBeenCalledWith('yarn', { cwd: 'some/base/path' });
});
});
describe('overridePackage', () => {
beforeEach(() => {
spyOn(shelljs, 'rm');
spyOn(fs, 'ensureSymlinkSync');
});
it('should remove the original package from the shared node_modules folder', () => {
exampleBoilerPlate.overridePackage('base/path', 'somePackage');
expect(shelljs.rm).toHaveBeenCalledWith('-rf', path.resolve(__dirname, 'shared/node_modules/@angular/somePackage'));
});
it('should symlink the source folder to the shared node_modules folder', () => {
exampleBoilerPlate.overridePackage('base/path', 'somePackage');
expect(fs.ensureSymlinkSync).toHaveBeenCalledWith(path.resolve('base/path/somePackage'), path.resolve(__dirname, 'shared/node_modules/@angular/somePackage'));
});
});
describe('getFoldersContaining', () => {
it('should use glob.sync', () => {
spyOn(glob, 'sync').and.returnValue(['a/b/config.json', 'c/d/config.json']);
const result = exampleBoilerPlate.getFoldersContaining('base/path', 'config.json', 'node_modules');
expect(glob.sync).toHaveBeenCalledWith(path.resolve('base/path/**/config.json'), { ignore: [path.resolve('base/path/**/node_modules/**')] });
expect(result).toEqual(['a/b', 'c/d']);
});
});
describe('copyFile', () => {
it('should use copySync and chmodSync', () => {
spyOn(fs, 'copySync');
spyOn(fs, 'chmodSync');
exampleBoilerPlate.copyFile('source/folder', 'destination/folder', 'some/file/path');
expect(fs.copySync).toHaveBeenCalledWith(
path.resolve('source/folder/some/file/path'),
path.resolve('destination/folder/some/file/path'),
{ overwrite: true });
expect(fs.chmodSync).toHaveBeenCalledWith(path.resolve('destination/folder/some/file/path'), 444);
});
});
describe('loadJsonFile', () => {
it('should use fs.readJsonSync', () => {
spyOn(fs, 'readJsonSync').and.returnValue({ some: 'value' });
const result = exampleBoilerPlate.loadJsonFile('some/file');
expect(fs.readJsonSync).toHaveBeenCalledWith('some/file', {throws: false});
expect(result).toEqual({ some: 'value' });
});
it('should return an empty object if readJsonSync fails', () => {
spyOn(fs, 'readJsonSync').and.returnValue(null);
const result = exampleBoilerPlate.loadJsonFile('some/file');
expect(result).toEqual({});
});
});
});

View File

@ -22,15 +22,24 @@ const IGNORED_EXAMPLES = [
* --filter to filter/select _example app subdir names
* e.g. --filter=foo // all example apps with 'foo' in their folder names.
*
* --setup run yarn install, copy boilerplate and update webdriver
* --setup run yarn install, copy boilerplate and update webdriver
* e.g. --setup
*
* --local to use the locally built Angular packages, rather than versions from npm
* Must be used in conjunction with --setup as this is when the packages are copied.
* e.g. --setup --local
*
* --shard to shard the specs into groups to allow you to run them in parallel
* e.g. --shard=0/2 // the even specs: 0, 2, 4, etc
* e.g. --shard=1/2 // the odd specs: 1, 3, 5, etc
* e.g. --shard=1/3 // the second of every three specs: 1, 4, 7, etc
*/
function runE2e() {
let promise = Promise.resolve();
if (argv.setup) {
// Run setup.
console.log('runE2e: copy boilerplate');
const spawnInfo = spawnExt('yarn', ['boilerplate:add'], { cwd: AIO_PATH });
const spawnInfo = spawnExt('yarn', ['boilerplate:add', argv.local ? '-- --local': ''], { cwd: AIO_PATH });
promise = spawnInfo.promise
.then(() => {
console.log('runE2e: update webdriver');
@ -41,7 +50,7 @@ function runE2e() {
const outputFile = path.join(AIO_PATH, './protractor-results.txt');
return promise
.then(() => findAndRunE2eTests(argv.filter, outputFile))
.then(() => findAndRunE2eTests(argv.filter, outputFile, argv.shard))
.then((status) => {
reportStatus(status, outputFile);
if (status.failed.length > 0) {
@ -55,7 +64,12 @@ function runE2e() {
// Finds all of the *e2e-spec.tests under the examples folder along with the corresponding apps
// that they should run under. Then run each app/spec collection sequentially.
function findAndRunE2eTests(filter, outputFile) {
function findAndRunE2eTests(filter, outputFile, shard) {
const shardParts = shard ? shard.split('/') : [0,1];
const shardModulo = parseInt(shardParts[0], 10);
const shardDivider = parseInt(shardParts[1], 10);
// create an output file with header.
const startTime = new Date().getTime();
let header = `Doc Sample Protractor Results on ${new Date().toLocaleString()}\n`;
@ -65,7 +79,9 @@ function findAndRunE2eTests(filter, outputFile) {
// Run the tests sequentially.
const status = { passed: [], failed: [] };
return getE2eSpecPaths(EXAMPLES_PATH, filter)
.then(e2eSpecPaths => e2eSpecPaths.reduce((promise, specPath) => {
.then(e2eSpecPaths => e2eSpecPaths
.filter((paths, index) => index % shardDivider === shardModulo)
.reduce((promise, specPath) => {
return promise.then(() => {
const examplePath = path.dirname(specPath);
return runE2eTests(examplePath, outputFile).then((ok) => {

View File

@ -0,0 +1,17 @@
/*
* Use this script to run the tests for the doc generation
* We cannot use the Jasmine CLI directly because it doesn't seem to
* understand the glob and only runs one spec file.
*
* Equally we cannot use a jasmine.json config file because it doesn't
* allow us to set the projectBaseDir, which means that you have to run
* jasmine CLI from this directory.
*
* Using a file like this gives us full control and keeps the package.json
* file clean and simple.
*/
const Jasmine = require('jasmine');
const jasmine = new Jasmine({ projectBaseDir: __dirname });
jasmine.loadConfig({ spec_files: ['*.spec.js'] });
jasmine.execute();

View File

@ -34,5 +34,5 @@ function getText(h1) {
(node.properties.ariaHidden === 'true' || node.properties['aria-hidden'] === 'true')
));
return toString(cleaned);
}
return cleaned ? toString(cleaned) : '';
}

View File

@ -69,4 +69,14 @@ describe('h1Checker postprocessor', () => {
processor.$process([doc]);
expect(doc.vFile.title).toEqual('What is Angular?');
});
});
it('should not break if the h1 is empty (except for an aria-hidden anchor)', () => {
const doc = {
docType: 'a',
renderedContent: `
<h1><a aria-hidden="true"></a></h1>
`
};
expect(() => processor.$process([doc])).not.toThrow();
});
});

View File

@ -1,7 +1,7 @@
{% macro githubHref(doc, versionInfo) -%}
https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInfo.repo $}/tree/{$ versionInfo.currentVersion.isSnapshot and versionInfo.currentVersion.SHA or versionInfo.currentVersion.raw $}/packages/{$ doc.fileInfo.projectRelativePath $}#L{$ doc.startingLine + 1 $}-L{$ doc.endingLine + 1 $}
https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInfo.repo $}/tree/{$ versionInfo.currentVersion.isSnapshot and versionInfo.currentVersion.SHA or versionInfo.currentVersion.raw $}/packages/{$ doc.fileInfo.realProjectRelativePath $}#L{$ doc.startingLine + 1 $}-L{$ doc.endingLine + 1 $}
{%- endmacro %}
{% macro githubViewLink(doc, versionInfo) -%}
<a href="{$ githubHref(doc, versionInfo) $}">{$ doc.fileInfo.projectRelativePath $}</a>
<a href="{$ githubHref(doc, versionInfo) $}">{$ doc.fileInfo.realProjectRelativePath $}</a>
{%- endmacro %}

View File

@ -2,9 +2,15 @@
# yarn lockfile v1
"@angular/animations@^4.2.4":
version "4.2.4"
resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-4.2.4.tgz#552d361fff163c56d0dfda4f963a16bfe4e44e98"
"@angular/animations@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-4.3.1.tgz#1f7e0bb803efc21c608246e6765a1c647f3d1a5f"
dependencies:
tslib "^1.7.1"
"@angular/cdk@^2.0.0-beta.8":
version "2.0.0-beta.8"
resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-2.0.0-beta.8.tgz#71961c851dfbeb19e085e898bf5e4461408f8b57"
dependencies:
tslib "^1.7.1"
@ -73,73 +79,73 @@
optionalDependencies:
node-sass "^4.3.0"
"@angular/common@^4.2.4":
version "4.2.4"
resolved "https://registry.yarnpkg.com/@angular/common/-/common-4.2.4.tgz#9b7ee0e692ab03191a7cd9af331d0f492d3cefeb"
"@angular/common@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@angular/common/-/common-4.3.1.tgz#260f487a7cdca326c436bd3ea9515c797de2ff72"
dependencies:
tslib "^1.7.1"
"@angular/compiler-cli@^4.2.4":
version "4.2.4"
resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-4.2.4.tgz#cce941a28362fc1c042ab85890fcaab1e233dd57"
"@angular/compiler-cli@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-4.3.1.tgz#00b41afb6faeb4aef561b8427804ac8880aff63c"
dependencies:
"@angular/tsc-wrapped" "4.2.4"
"@angular/tsc-wrapped" "4.3.1"
minimist "^1.2.0"
reflect-metadata "^0.1.2"
"@angular/compiler@^4.2.4":
version "4.2.4"
resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-4.2.4.tgz#7936a87b2d483abcef840b868c1fcf67221c4914"
"@angular/compiler@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-4.3.1.tgz#3a24d49ecf01ac2b6e07f63e378b8ff8e257fe09"
dependencies:
tslib "^1.7.1"
"@angular/core@^4.2.4":
version "4.2.4"
resolved "https://registry.yarnpkg.com/@angular/core/-/core-4.2.4.tgz#e8df7a8dd5de5a327784dfc35b5da6344281cf1b"
"@angular/core@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@angular/core/-/core-4.3.1.tgz#a9d0a7d644b96260674269b689a04feea632a8d3"
dependencies:
tslib "^1.7.1"
"@angular/forms@^4.2.4":
version "4.2.4"
resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-4.2.4.tgz#ae09755332ea463f561df01aac2bd369e5d35dc9"
"@angular/forms@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-4.3.1.tgz#33914da2cb146430ff901471e682c76654622dfe"
dependencies:
tslib "^1.7.1"
"@angular/http@^4.2.4":
version "4.2.4"
resolved "https://registry.yarnpkg.com/@angular/http/-/http-4.2.4.tgz#ed039c0d53a587d24575f4cabfd1db8e7f1e3f8b"
"@angular/http@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@angular/http/-/http-4.3.1.tgz#e4f661f746711e88ecbea76a3c905babf97d315a"
dependencies:
tslib "^1.7.1"
"@angular/material@^2.0.0-beta.7":
version "2.0.0-beta.7"
resolved "https://registry.yarnpkg.com/@angular/material/-/material-2.0.0-beta.7.tgz#2584aaf1ffbe24779916345f1ac82921ccbc2577"
"@angular/material@^2.0.0-beta.8":
version "2.0.0-beta.8"
resolved "https://registry.yarnpkg.com/@angular/material/-/material-2.0.0-beta.8.tgz#a92852abc9261aea26c2401f576645470be2cf38"
dependencies:
tslib "^1.7.1"
"@angular/platform-browser-dynamic@^4.2.4":
version "4.2.4"
resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.2.4.tgz#5190fda79425ae49a49224985614c9780a370761"
"@angular/platform-browser-dynamic@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.3.1.tgz#84034da60a82ef36e7effda7b3ade6e645b330b3"
dependencies:
tslib "^1.7.1"
"@angular/platform-browser@^4.2.4":
version "4.2.4"
resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-4.2.4.tgz#00a44dcb2fd777b54bc17c1ce734aa18fe9fd039"
"@angular/platform-browser@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-4.3.1.tgz#db727b06eed64bda5defec71815db26a4da2f690"
dependencies:
tslib "^1.7.1"
"@angular/platform-server@^4.2.4":
version "4.2.4"
resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-4.2.4.tgz#acfd9c620b1d64c3da9f0c6192d6ccd59620d0d6"
"@angular/platform-server@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-4.3.1.tgz#3b915fc4013c6a947a8c147b4db0279b025936eb"
dependencies:
parse5 "^3.0.1"
tslib "^1.7.1"
xhr2 "^0.1.4"
"@angular/router@^4.2.4":
version "4.2.4"
resolved "https://registry.yarnpkg.com/@angular/router/-/router-4.2.4.tgz#2f193f3a36da19b11a08c9b40e391bd8fde59c56"
"@angular/router@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@angular/router/-/router-4.3.1.tgz#5219d44526156d816065841127610165a015b450"
dependencies:
tslib "^1.7.1"
@ -150,9 +156,9 @@
base64-js "^1.1.2"
jshashes "^1.0.5"
"@angular/tsc-wrapped@4.2.4":
version "4.2.4"
resolved "https://registry.yarnpkg.com/@angular/tsc-wrapped/-/tsc-wrapped-4.2.4.tgz#956ff14ccf2043243b0cc82336b221dbe6315aef"
"@angular/tsc-wrapped@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@angular/tsc-wrapped/-/tsc-wrapped-4.3.1.tgz#f6616a4d2a3bbec1cded664fd1f526edce99ef41"
dependencies:
tsickle "^0.21.0"
@ -1904,9 +1910,9 @@ devtools-timeline-model@1.1.6:
chrome-devtools-frontend "1.0.401423"
resolve "1.1.7"
dgeni-packages@^0.20.0-rc.6:
version "0.20.0-rc.6"
resolved "https://registry.yarnpkg.com/dgeni-packages/-/dgeni-packages-0.20.0-rc.6.tgz#d615e0631305dcf091386c802d0e424ef86206d2"
dgeni-packages@^0.20.0:
version "0.20.0"
resolved "https://registry.yarnpkg.com/dgeni-packages/-/dgeni-packages-0.20.0.tgz#e7da99b0a119ee2eb584202d054a5aa01f23e208"
dependencies:
canonical-path "0.0.2"
catharsis "^0.8.1"

View File

@ -1,6 +1,6 @@
{
"name": "angular-srcs",
"version": "5.0.0-beta.1",
"version": "5.0.0-beta.2",
"private": true,
"branchPattern": "2.0.*",
"description": "Angular - a web framework for modern web apps",

View File

@ -201,7 +201,7 @@ export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
} else {
styles.push(styleTuple as ɵStyleData);
}
})
});
} else {
styles.push(metadata.styles);
}

View File

@ -29,8 +29,8 @@ export class AnimationEngine {
this._transitionEngine = new TransitionAnimationEngine(driver, normalizer);
this._timelineEngine = new TimelineAnimationEngine(driver, normalizer);
this._transitionEngine.onRemovalComplete =
(element: any, context: any) => { this.onRemovalComplete(element, context); }
this._transitionEngine.onRemovalComplete = (element: any, context: any) =>
this.onRemovalComplete(element, context);
}
registerTrigger(

View File

@ -490,6 +490,7 @@ export class TransitionAnimationEngine {
// this method is designed to be overridden by the code that uses this engine
public onRemovalComplete = (element: any, context: any) => {};
/** @internal */
_onRemovalComplete(element: any, context: any) { this.onRemovalComplete(element, context); }
constructor(public driver: AnimationDriver, private _normalizer: AnimationStyleNormalizer) {}

View File

@ -427,17 +427,17 @@ export function main() {
it('should throw an error when an input variable is not provided when invoked and is not a default value',
() => {
expect(() => {invokeAnimationSequence(rootElement, [style({color: '{{ color }}'})])})
expect(() => invokeAnimationSequence(rootElement, [style({color: '{{ color }}'})]))
.toThrowError(/Please provide a value for the animation param color/);
expect(
() => {invokeAnimationSequence(
() => invokeAnimationSequence(
rootElement,
[
style({color: '{{ start }}'}),
animate('{{ time }}', style({color: '{{ end }}'})),
],
buildParams({start: 'blue', end: 'red'}))})
buildParams({start: 'blue', end: 'red'})))
.toThrowError(/Please provide a value for the animation param time/);
});
});

Some files were not shown because too many files have changed in this diff Show More