diff --git a/packages/core/test/bundling/forms/BUILD.bazel b/packages/core/test/bundling/forms_reactive/BUILD.bazel similarity index 96% rename from packages/core/test/bundling/forms/BUILD.bazel rename to packages/core/test/bundling/forms_reactive/BUILD.bazel index 5c0930c0d9..cd49c7e669 100644 --- a/packages/core/test/bundling/forms/BUILD.bazel +++ b/packages/core/test/bundling/forms_reactive/BUILD.bazel @@ -5,7 +5,7 @@ load("//tools/symbol-extractor:index.bzl", "js_expected_symbol_test") load("@npm//http-server:index.bzl", "http_server") ng_module( - name = "forms", + name = "forms_reactive", srcs = ["index.ts"], tags = [ "ivy-only", @@ -24,7 +24,7 @@ ng_rollup_bundle( "ivy-only", ], deps = [ - ":forms", + ":forms_reactive", "//packages/core", "//packages/forms", "//packages/platform-browser", diff --git a/packages/core/test/bundling/forms/bundle.golden_symbols.json b/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json similarity index 95% rename from packages/core/test/bundling/forms/bundle.golden_symbols.json rename to packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json index b6ddd81b75..bad7d9063a 100644 --- a/packages/core/test/bundling/forms/bundle.golden_symbols.json +++ b/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json @@ -227,9 +227,6 @@ { "name": "FormsExampleModule" }, - { - "name": "FormsModule" - }, { "name": "INJECTOR" }, @@ -389,21 +386,12 @@ { "name": "NgForOfContext" }, - { - "name": "NgForm" - }, { "name": "NgLocaleLocalization" }, { "name": "NgLocalization" }, - { - "name": "NgModel" - }, - { - "name": "NgModelGroup" - }, { "name": "NgModuleFactory" }, @@ -473,9 +461,6 @@ { "name": "RANGE_VALUE_ACCESSOR" }, - { - "name": "REQUIRED_VALIDATOR" - }, { "name": "RadioControlRegistry" }, @@ -512,9 +497,6 @@ { "name": "RendererStyleFlags2" }, - { - "name": "RequiredValidator" - }, { "name": "RootComponent" }, @@ -593,12 +575,6 @@ { "name": "TRANSITION_ID" }, - { - "name": "TemplateFormsComponent" - }, - { - "name": "TemplateFormsComponent_div_14_Template" - }, { "name": "TemplateRef" }, @@ -941,12 +917,6 @@ { "name": "formArrayNameProvider" }, - { - "name": "formControlBinding" - }, - { - "name": "formDirectiveProvider" - }, { "name": "formDirectiveProvider" }, @@ -1094,9 +1064,6 @@ { "name": "getSelectedIndex" }, - { - "name": "getSelectedTNode" - }, { "name": "getSimpleChangesStore" }, @@ -1271,9 +1238,6 @@ { "name": "isPromise" }, - { - "name": "isPropertyUpdated" - }, { "name": "isScheduler" }, @@ -1361,9 +1325,6 @@ { "name": "mergeValidators" }, - { - "name": "modelGroupProvider" - }, { "name": "modules" }, @@ -1391,9 +1352,6 @@ { "name": "nativeParentNode" }, - { - "name": "nextBindingIndex" - }, { "name": "nextNgElementId" }, @@ -1493,9 +1451,6 @@ { "name": "renderComponentOrTemplate" }, - { - "name": "renderStringify" - }, { "name": "renderView" }, @@ -1511,12 +1466,6 @@ { "name": "resolveProvider" }, - { - "name": "resolvedPromise" - }, - { - "name": "resolvedPromise" - }, { "name": "rxSubscriber" }, @@ -1538,9 +1487,6 @@ { "name": "selectIndexInternal" }, - { - "name": "selectValueAccessor" - }, { "name": "setBindingRootForHostBindings" }, @@ -1595,9 +1541,6 @@ { "name": "setUpControl" }, - { - "name": "setUpFormContainer" - }, { "name": "setUpValidators" }, @@ -1622,9 +1565,6 @@ { "name": "subscribeToArray" }, - { - "name": "syncPendingControls" - }, { "name": "throwProviderNotFoundError" }, @@ -1685,12 +1625,6 @@ { "name": "ɵɵProvidersFeature" }, - { - "name": "ɵɵadvance" - }, - { - "name": "ɵɵattribute" - }, { "name": "ɵɵclassProp" }, @@ -1730,15 +1664,9 @@ { "name": "ɵɵlistener" }, - { - "name": "ɵɵnextContext" - }, { "name": "ɵɵproperty" }, - { - "name": "ɵɵtemplate" - }, { "name": "ɵɵtext" } diff --git a/packages/core/test/bundling/forms/forms_e2e_spec.ts b/packages/core/test/bundling/forms_reactive/forms_e2e_spec.ts similarity index 64% rename from packages/core/test/bundling/forms/forms_e2e_spec.ts rename to packages/core/test/bundling/forms_reactive/forms_e2e_spec.ts index eacb295420..65ee1ee746 100644 --- a/packages/core/test/bundling/forms/forms_e2e_spec.ts +++ b/packages/core/test/bundling/forms_reactive/forms_e2e_spec.ts @@ -11,36 +11,16 @@ import {ɵwhenRendered as whenRendered} from '@angular/core'; import {withBody} from '@angular/private/testing'; import * as path from 'path'; -const PACKAGE = 'angular/packages/core/test/bundling/forms'; +const PACKAGE = 'angular/packages/core/test/bundling/forms_reactive'; const BUNDLES = ['bundle.js', 'bundle.min_debug.js', 'bundle.min.js']; -describe('functional test for forms', () => { +describe('functional test for reactive forms', () => { BUNDLES.forEach((bundle) => { describe(`using ${bundle} bundle`, () => { it('should render template form', withBody('', async () => { require(path.join(PACKAGE, bundle)); await (window as any).waitForApp; - // Template forms - const templateFormsComponent = (window as any).templateFormsComponent; - await whenRendered(templateFormsComponent); - - const templateForm = document.querySelector('app-template-forms')!; - - // Check for inputs - const iputs = templateForm.querySelectorAll('input'); - expect(iputs.length).toBe(5); - - // Check for button - const templateButtons = templateForm.querySelectorAll('button'); - expect(templateButtons.length).toBe(1); - expect(templateButtons[0]).toBeDefined(); - - // Make sure button click works - const templateFormSpy = spyOn(templateFormsComponent, 'addCity'); - templateButtons[0].click(); - expect(templateFormSpy).toHaveBeenCalled(); - // Reactive forms const reactiveFormsComponent = (window as any).reactiveFormsComponent; await whenRendered(reactiveFormsComponent); diff --git a/packages/core/test/bundling/forms/index.html b/packages/core/test/bundling/forms_reactive/index.html similarity index 95% rename from packages/core/test/bundling/forms/index.html rename to packages/core/test/bundling/forms_reactive/index.html index 0703f0dbb5..389b4959af 100644 --- a/packages/core/test/bundling/forms/index.html +++ b/packages/core/test/bundling/forms_reactive/index.html @@ -2,7 +2,7 @@ - Angular Forms Example + Angular Reactive Forms Example diff --git a/packages/core/test/bundling/forms/index.ts b/packages/core/test/bundling/forms_reactive/index.ts similarity index 51% rename from packages/core/test/bundling/forms/index.ts rename to packages/core/test/bundling/forms_reactive/index.ts index 4a2e8d1294..b44c4f410b 100644 --- a/packages/core/test/bundling/forms/index.ts +++ b/packages/core/test/bundling/forms_reactive/index.ts @@ -6,76 +6,36 @@ * found in the LICENSE file at https://angular.io/license */ import {Component, NgModule, ɵNgModuleFactory as NgModuleFactory} from '@angular/core'; -import {FormArray, FormBuilder, FormControl, FormGroup, FormsModule, NgForm, ReactiveFormsModule, Validators} from '@angular/forms'; +import {FormArray, FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms'; import {BrowserModule, platformBrowser} from '@angular/platform-browser'; -@Component({ - selector: 'app-template-forms', - template: ` -
-
-
- First Name: - -
-
- Last Name: - -
-
- Subscribe: - -
- -
Disabled:
- -
- City -
- - -
-
`, -}) -class TemplateFormsComponent { - name = {first: 'Nancy', last: 'Drew', subscribed: true}; - addresses = [{city: 'Toronto'}]; - constructor() { - // We use this reference in our test - (window as any).templateFormsComponent = this; - } - - addCity() { - this.addresses.push(({city: ''})); - } -} - @Component({ selector: 'app-reactive-forms', template: ` -
-
- First Name: - -
-
- Last Name: - -
- -
- Subscribe: - -
- -
Disabled:
-
-
-
City:
+ +
+ First Name: +
-
- - `, +
+ Last Name: + +
+ +
+ Subscribe: + +
+ +
Disabled:
+
+
+
City:
+
+
+ + + ` }) class ReactiveFormsComponent { profileForm!: FormGroup; @@ -117,7 +77,6 @@ class ReactiveFormsComponent { @Component({ selector: 'app-root', template: ` - ` }) @@ -125,8 +84,8 @@ class RootComponent { } @NgModule({ - declarations: [RootComponent, TemplateFormsComponent, ReactiveFormsComponent], - imports: [BrowserModule, FormsModule, ReactiveFormsModule] + declarations: [RootComponent, ReactiveFormsComponent], + imports: [BrowserModule, ReactiveFormsModule] }) class FormsExampleModule { ngDoBootstrap(app: any) { diff --git a/packages/core/test/bundling/forms/treeshaking_spec.ts b/packages/core/test/bundling/forms_reactive/treeshaking_spec.ts similarity index 93% rename from packages/core/test/bundling/forms/treeshaking_spec.ts rename to packages/core/test/bundling/forms_reactive/treeshaking_spec.ts index 546a88ee0a..319a0fcb86 100644 --- a/packages/core/test/bundling/forms/treeshaking_spec.ts +++ b/packages/core/test/bundling/forms_reactive/treeshaking_spec.ts @@ -13,7 +13,7 @@ import * as path from 'path'; const UTF8 = { encoding: 'utf-8' }; -const PACKAGE = 'angular/packages/core/test/bundling/forms'; +const PACKAGE = 'angular/packages/core/test/bundling/forms_reactive'; describe('treeshaking with uglify', () => { let content: string; diff --git a/packages/core/test/bundling/forms_template_driven/BUILD.bazel b/packages/core/test/bundling/forms_template_driven/BUILD.bazel new file mode 100644 index 0000000000..caebf192dd --- /dev/null +++ b/packages/core/test/bundling/forms_template_driven/BUILD.bazel @@ -0,0 +1,85 @@ +package(default_visibility = ["//visibility:public"]) + +load("//tools:defaults.bzl", "jasmine_node_test", "ng_module", "ng_rollup_bundle", "ts_library") +load("//tools/symbol-extractor:index.bzl", "js_expected_symbol_test") +load("@npm//http-server:index.bzl", "http_server") + +ng_module( + name = "forms_template_driven", + srcs = ["index.ts"], + tags = [ + "ivy-only", + ], + deps = [ + "//packages/core", + "//packages/forms", + "//packages/platform-browser", + ], +) + +ng_rollup_bundle( + name = "bundle", + entry_point = ":index.ts", + tags = [ + "ivy-only", + ], + deps = [ + ":forms_template_driven", + "//packages/core", + "//packages/forms", + "//packages/platform-browser", + "@npm//rxjs", + ], +) + +ts_library( + name = "test_lib", + testonly = True, + srcs = glob(["*_spec.ts"]), + tags = [ + "ivy-only", + ], + deps = [ + "//packages:types", + "//packages/compiler", + "//packages/core", + "//packages/core/testing", + "//packages/private/testing", + ], +) + +jasmine_node_test( + name = "test", + data = [ + ":bundle.js", + ":bundle.min.js", + ":bundle.min.js.br", + ":bundle.min_debug.js", + ], + tags = [ + "ivy-only", + ], + deps = [":test_lib"], +) + +js_expected_symbol_test( + name = "symbol_test", + src = ":bundle.min_debug.js", + golden = ":bundle.golden_symbols.json", + tags = [ + "ivy-aot", + "ivy-only", + ], +) + +http_server( + name = "prodserver", + data = [ + "index.html", + ":bundle.min.js", + ":bundle.min_debug.js", + ], + tags = [ + "ivy-only", + ], +) diff --git a/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json b/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json new file mode 100644 index 0000000000..39c77b5574 --- /dev/null +++ b/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json @@ -0,0 +1,1676 @@ +[ + { + "name": "ALLOW_MULTIPLE_PLATFORMS" + }, + { + "name": "APPLICATION_MODULE_PROVIDERS" + }, + { + "name": "APP_BOOTSTRAP_LISTENER" + }, + { + "name": "APP_ID" + }, + { + "name": "APP_ID_RANDOM_PROVIDER" + }, + { + "name": "APP_INITIALIZER" + }, + { + "name": "AbstractControl" + }, + { + "name": "AbstractControlDirective" + }, + { + "name": "AbstractControlStatus" + }, + { + "name": "AbstractFormGroupDirective" + }, + { + "name": "AnonymousSubject" + }, + { + "name": "ApplicationInitStatus" + }, + { + "name": "ApplicationModule" + }, + { + "name": "ApplicationRef" + }, + { + "name": "BROWSER_MODULE_PROVIDERS" + }, + { + "name": "BUILTIN_ACCESSORS" + }, + { + "name": "BrowserDomAdapter" + }, + { + "name": "BrowserGetTestability" + }, + { + "name": "BrowserModule" + }, + { + "name": "CHECKBOX_VALUE_ACCESSOR" + }, + { + "name": "CIRCULAR" + }, + { + "name": "CLEAN_PROMISE" + }, + { + "name": "COMPONENT_REGEX" + }, + { + "name": "COMPOSITION_BUFFER_MODE" + }, + { + "name": "ChangeDetectionStrategy" + }, + { + "name": "CheckboxControlValueAccessor" + }, + { + "name": "CommonModule" + }, + { + "name": "Compiler" + }, + { + "name": "Compiler_compileModuleAndAllComponentsAsync" + }, + { + "name": "Compiler_compileModuleAndAllComponentsSync" + }, + { + "name": "Compiler_compileModuleAndAllComponentsSync__POST_R3__" + }, + { + "name": "Compiler_compileModuleAsync" + }, + { + "name": "Compiler_compileModuleSync" + }, + { + "name": "Compiler_compileModuleSync__POST_R3__" + }, + { + "name": "ComponentFactory" + }, + { + "name": "ComponentFactory" + }, + { + "name": "ComponentFactoryResolver" + }, + { + "name": "ComponentFactoryResolver" + }, + { + "name": "ComponentRef" + }, + { + "name": "ConnectableObservable" + }, + { + "name": "ConnectableSubscriber" + }, + { + "name": "Console" + }, + { + "name": "ControlContainer" + }, + { + "name": "DEFAULT_CURRENCY_CODE" + }, + { + "name": "DEFAULT_VALUE_ACCESSOR" + }, + { + "name": "DOCUMENT" + }, + { + "name": "DOCUMENT" + }, + { + "name": "DefaultDomRenderer2" + }, + { + "name": "DefaultIterableDiffer" + }, + { + "name": "DefaultIterableDifferFactory" + }, + { + "name": "DefaultKeyValueDiffer" + }, + { + "name": "DefaultKeyValueDifferFactory" + }, + { + "name": "DefaultValueAccessor" + }, + { + "name": "DomEventsPlugin" + }, + { + "name": "DomRendererFactory2" + }, + { + "name": "DomSharedStylesHost" + }, + { + "name": "EMAIL_REGEXP" + }, + { + "name": "EMPTY_ARRAY" + }, + { + "name": "EMPTY_OBJ" + }, + { + "name": "EMPTY_PAYLOAD" + }, + { + "name": "EVENT_MANAGER_PLUGINS" + }, + { + "name": "ElementRef" + }, + { + "name": "EmulatedEncapsulationDomRenderer2" + }, + { + "name": "ErrorHandler" + }, + { + "name": "EventEmitter" + }, + { + "name": "EventManager" + }, + { + "name": "EventManagerPlugin" + }, + { + "name": "FormArray" + }, + { + "name": "FormControl" + }, + { + "name": "FormGroup" + }, + { + "name": "FormsExampleModule" + }, + { + "name": "FormsModule" + }, + { + "name": "INJECTOR" + }, + { + "name": "INJECTOR_IMPL" + }, + { + "name": "INJECTOR_SCOPE" + }, + { + "name": "Inject" + }, + { + "name": "InjectFlags" + }, + { + "name": "InjectionToken" + }, + { + "name": "Injector" + }, + { + "name": "InnerSubscriber" + }, + { + "name": "IterableChangeRecord_" + }, + { + "name": "IterableDiffers" + }, + { + "name": "KeyEventsPlugin" + }, + { + "name": "KeyValueChangeRecord_" + }, + { + "name": "KeyValueDiffers" + }, + { + "name": "LOCALE_DATA" + }, + { + "name": "LOCALE_ID" + }, + { + "name": "LOCALE_ID" + }, + { + "name": "LifecycleHooksFeature" + }, + { + "name": "LocaleDataIndex" + }, + { + "name": "MODIFIER_KEYS" + }, + { + "name": "MODIFIER_KEY_GETTERS" + }, + { + "name": "MapOperator" + }, + { + "name": "MapSubscriber" + }, + { + "name": "MergeMapOperator" + }, + { + "name": "MergeMapSubscriber" + }, + { + "name": "ModuleWithComponentFactories" + }, + { + "name": "NAMESPACE_URIS" + }, + { + "name": "NEW_LINE" + }, + { + "name": "NG_ASYNC_VALIDATORS" + }, + { + "name": "NG_COMP_DEF" + }, + { + "name": "NG_DIR_DEF" + }, + { + "name": "NG_ELEMENT_ID" + }, + { + "name": "NG_FACTORY_DEF" + }, + { + "name": "NG_INJECTABLE_DEF" + }, + { + "name": "NG_INJECTOR_DEF" + }, + { + "name": "NG_INJ_DEF" + }, + { + "name": "NG_LOC_ID_DEF" + }, + { + "name": "NG_MOD_DEF" + }, + { + "name": "NG_PIPE_DEF" + }, + { + "name": "NG_PROV_DEF" + }, + { + "name": "NG_VALIDATORS" + }, + { + "name": "NG_VALUE_ACCESSOR" + }, + { + "name": "NOT_FOUND" + }, + { + "name": "NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR" + }, + { + "name": "NOT_YET" + }, + { + "name": "NO_CHANGE" + }, + { + "name": "NULL_INJECTOR" + }, + { + "name": "NUMBER_VALUE_ACCESSOR" + }, + { + "name": "NgControl" + }, + { + "name": "NgControlStatus" + }, + { + "name": "NgControlStatusGroup" + }, + { + "name": "NgForOf" + }, + { + "name": "NgForOfContext" + }, + { + "name": "NgForm" + }, + { + "name": "NgLocaleLocalization" + }, + { + "name": "NgLocalization" + }, + { + "name": "NgModel" + }, + { + "name": "NgModelGroup" + }, + { + "name": "NgModuleFactory" + }, + { + "name": "NgModuleRef" + }, + { + "name": "NgModuleRef" + }, + { + "name": "NgOnChangesFeatureImpl" + }, + { + "name": "NgZone" + }, + { + "name": "NodeInjector" + }, + { + "name": "NodeInjectorFactory" + }, + { + "name": "NoopNgZone" + }, + { + "name": "NullInjector" + }, + { + "name": "NumberValueAccessor" + }, + { + "name": "ObjectUnsubscribedError" + }, + { + "name": "Observable" + }, + { + "name": "Optional" + }, + { + "name": "OuterSubscriber" + }, + { + "name": "PLATFORM_ID" + }, + { + "name": "PLATFORM_INITIALIZER" + }, + { + "name": "PlatformRef" + }, + { + "name": "Plural" + }, + { + "name": "R3Injector" + }, + { + "name": "R3TemplateRef" + }, + { + "name": "R3ViewContainerRef" + }, + { + "name": "RADIO_VALUE_ACCESSOR" + }, + { + "name": "RANGE_VALUE_ACCESSOR" + }, + { + "name": "REQUIRED_VALIDATOR" + }, + { + "name": "RadioControlRegistry" + }, + { + "name": "RadioControlValueAccessor" + }, + { + "name": "RangeValueAccessor" + }, + { + "name": "RecordViewTuple" + }, + { + "name": "RefCountOperator" + }, + { + "name": "RefCountSubscriber" + }, + { + "name": "Renderer2" + }, + { + "name": "RendererFactory2" + }, + { + "name": "RendererStyleFlags2" + }, + { + "name": "RequiredValidator" + }, + { + "name": "RootComponent" + }, + { + "name": "RootViewRef" + }, + { + "name": "RuntimeError" + }, + { + "name": "SCHEDULER" + }, + { + "name": "SELECT_MULTIPLE_VALUE_ACCESSOR" + }, + { + "name": "SELECT_VALUE_ACCESSOR" + }, + { + "name": "SERVER_TRANSITION_PROVIDERS" + }, + { + "name": "SWITCH_ELEMENT_REF_FACTORY" + }, + { + "name": "SWITCH_RENDERER2_FACTORY" + }, + { + "name": "SWITCH_TEMPLATE_REF_FACTORY" + }, + { + "name": "SWITCH_VIEW_CONTAINER_REF_FACTORY" + }, + { + "name": "SafeSubscriber" + }, + { + "name": "Sanitizer" + }, + { + "name": "SelectControlValueAccessor" + }, + { + "name": "SelectMultipleControlValueAccessor" + }, + { + "name": "ShadowDomRenderer" + }, + { + "name": "SharedStylesHost" + }, + { + "name": "SimpleChange" + }, + { + "name": "SkipSelf" + }, + { + "name": "Subject" + }, + { + "name": "SubjectSubscriber" + }, + { + "name": "SubjectSubscription" + }, + { + "name": "Subscriber" + }, + { + "name": "Subscription" + }, + { + "name": "THROW_IF_NOT_FOUND" + }, + { + "name": "TRANSITION_ID" + }, + { + "name": "TemplateFormsComponent" + }, + { + "name": "TemplateFormsComponent_div_14_Template" + }, + { + "name": "TemplateRef" + }, + { + "name": "Testability" + }, + { + "name": "TestabilityRegistry" + }, + { + "name": "USE_VALUE" + }, + { + "name": "UnsubscriptionError" + }, + { + "name": "VERSION" + }, + { + "name": "VE_ViewContainerRef" + }, + { + "name": "Validators" + }, + { + "name": "Version" + }, + { + "name": "ViewContainerRef" + }, + { + "name": "ViewEncapsulation" + }, + { + "name": "ViewEngineTemplateRef" + }, + { + "name": "ViewRef" + }, + { + "name": "_DOM" + }, + { + "name": "_DuplicateItemRecordList" + }, + { + "name": "_DuplicateMap" + }, + { + "name": "_NoopGetTestability" + }, + { + "name": "_NullComponentFactoryResolver" + }, + { + "name": "__extends" + }, + { + "name": "__forward_ref__" + }, + { + "name": "__global" + }, + { + "name": "__globalThis" + }, + { + "name": "__self" + }, + { + "name": "__window" + }, + { + "name": "_chromeNumKeyPadMap" + }, + { + "name": "_currentInjector" + }, + { + "name": "_enable_super_gross_mode_that_will_cause_bad_things" + }, + { + "name": "_global" + }, + { + "name": "_keyMap" + }, + { + "name": "_randomChar" + }, + { + "name": "_renderCompCount" + }, + { + "name": "_symbolIterator" + }, + { + "name": "_testabilityGetter" + }, + { + "name": "addComponentLogic" + }, + { + "name": "addToArray" + }, + { + "name": "addToViewTree" + }, + { + "name": "allocExpando" + }, + { + "name": "allocLFrame" + }, + { + "name": "appendChild" + }, + { + "name": "applyNodes" + }, + { + "name": "applyProjectionRecursive" + }, + { + "name": "applyToElementOrContainer" + }, + { + "name": "applyView" + }, + { + "name": "attachInjectFlag" + }, + { + "name": "attachPatchData" + }, + { + "name": "autoRegisterModuleById" + }, + { + "name": "baseElement" + }, + { + "name": "bindingUpdated" + }, + { + "name": "bloomHasToken" + }, + { + "name": "callHook" + }, + { + "name": "callHooks" + }, + { + "name": "checkStable" + }, + { + "name": "classIndexOf" + }, + { + "name": "cleanUpView" + }, + { + "name": "coerceToAsyncValidator" + }, + { + "name": "coerceToValidator" + }, + { + "name": "collectStylingFromDirectives" + }, + { + "name": "collectStylingFromTAttrs" + }, + { + "name": "composeAsyncValidators" + }, + { + "name": "composeValidators" + }, + { + "name": "computeStaticStyling" + }, + { + "name": "concatStringsWithSpace" + }, + { + "name": "config" + }, + { + "name": "configureViewWithDirective" + }, + { + "name": "connectableObservableDescriptor" + }, + { + "name": "controlPath" + }, + { + "name": "createDirectivesInstances" + }, + { + "name": "createElementNode" + }, + { + "name": "createElementRef" + }, + { + "name": "createInjectorWithoutInjectorInstances" + }, + { + "name": "createLContainer" + }, + { + "name": "createLFrame" + }, + { + "name": "createLView" + }, + { + "name": "createNodeInjector" + }, + { + "name": "createPlatformFactory" + }, + { + "name": "createTView" + }, + { + "name": "decoratePreventDefault" + }, + { + "name": "deepForEach" + }, + { + "name": "defaultErrorLogger" + }, + { + "name": "defaultIterableDiffers" + }, + { + "name": "defaultIterableDiffersFactory" + }, + { + "name": "defaultKeyValueDiffers" + }, + { + "name": "defaultKeyValueDiffersFactory" + }, + { + "name": "defaultScheduler" + }, + { + "name": "destroyLView" + }, + { + "name": "detachMovedView" + }, + { + "name": "detachView" + }, + { + "name": "detectChangesInRootView" + }, + { + "name": "detectChangesInternal" + }, + { + "name": "diPublicInInjector" + }, + { + "name": "domRendererFactory3" + }, + { + "name": "empty" + }, + { + "name": "enterDI" + }, + { + "name": "enterView" + }, + { + "name": "executeCheckHooks" + }, + { + "name": "executeInitAndCheckHooks" + }, + { + "name": "executeListenerWithErrorHandling" + }, + { + "name": "executeTemplate" + }, + { + "name": "executeValidators" + }, + { + "name": "executeViewQueryFn" + }, + { + "name": "extendStatics" + }, + { + "name": "extractDirectiveDef" + }, + { + "name": "extractPipeDef" + }, + { + "name": "fillProperties" + }, + { + "name": "findAttrIndexInNode" + }, + { + "name": "findStylingValue" + }, + { + "name": "flattenStyles" + }, + { + "name": "flattenUnsubscriptionErrors" + }, + { + "name": "forkJoinInternal" + }, + { + "name": "formControlBinding" + }, + { + "name": "formDirectiveProvider" + }, + { + "name": "forwardRef" + }, + { + "name": "from" + }, + { + "name": "fromArray" + }, + { + "name": "generateInitialInputs" + }, + { + "name": "generatePropertyAliases" + }, + { + "name": "getClosureSafeProperty" + }, + { + "name": "getComponentDef" + }, + { + "name": "getComponentLViewByIndex" + }, + { + "name": "getConstant" + }, + { + "name": "getCurrentTNode" + }, + { + "name": "getCurrentTNodePlaceholderOk" + }, + { + "name": "getDOM" + }, + { + "name": "getDebugContext" + }, + { + "name": "getDeclarationTNode" + }, + { + "name": "getFactoryDef" + }, + { + "name": "getFactoryOf" + }, + { + "name": "getFirstLContainer" + }, + { + "name": "getInjectableDef" + }, + { + "name": "getInjectorDef" + }, + { + "name": "getInjectorIndex" + }, + { + "name": "getLView" + }, + { + "name": "getLViewParent" + }, + { + "name": "getLocaleData" + }, + { + "name": "getNativeByTNode" + }, + { + "name": "getNearestLContainer" + }, + { + "name": "getNextLContainer" + }, + { + "name": "getNgModuleDef" + }, + { + "name": "getNodeInjectable" + }, + { + "name": "getNullInjector" + }, + { + "name": "getOrCreateInjectable" + }, + { + "name": "getOrCreateLViewCleanup" + }, + { + "name": "getOrCreateNodeInjectorForNode" + }, + { + "name": "getOrCreateTComponentView" + }, + { + "name": "getOrCreateTNode" + }, + { + "name": "getOrCreateViewRefs" + }, + { + "name": "getOriginalError" + }, + { + "name": "getOwnDefinition" + }, + { + "name": "getParentInjectorIndex" + }, + { + "name": "getParentInjectorLocation" + }, + { + "name": "getParentInjectorView" + }, + { + "name": "getPlatform" + }, + { + "name": "getPreviousIndex" + }, + { + "name": "getProjectionNodes" + }, + { + "name": "getPromiseCtor" + }, + { + "name": "getSelectedIndex" + }, + { + "name": "getSelectedTNode" + }, + { + "name": "getSimpleChangesStore" + }, + { + "name": "getSymbolIterator" + }, + { + "name": "getSymbolIterator" + }, + { + "name": "getTNode" + }, + { + "name": "getTStylingRangeNext" + }, + { + "name": "getTStylingRangePrev" + }, + { + "name": "getTView" + }, + { + "name": "getViewRefs" + }, + { + "name": "handleError" + }, + { + "name": "hasParentInjector" + }, + { + "name": "hasTagAndTypeMatch" + }, + { + "name": "hasValidLength" + }, + { + "name": "hostReportError" + }, + { + "name": "icuContainerIterate" + }, + { + "name": "identity" + }, + { + "name": "includeViewProviders" + }, + { + "name": "incrementInitPhaseFlags" + }, + { + "name": "indexOf" + }, + { + "name": "inheritContentQueries" + }, + { + "name": "inheritHostBindings" + }, + { + "name": "inheritViewQuery" + }, + { + "name": "initTNodeFlags" + }, + { + "name": "injectArgs" + }, + { + "name": "injectInjectorOnly" + }, + { + "name": "injectRootLimpMode" + }, + { + "name": "injectableDefOrInjectorDefFactory" + }, + { + "name": "insertBloom" + }, + { + "name": "instructionState" + }, + { + "name": "invertObject" + }, + { + "name": "invokeHostBindingsInCreationMode" + }, + { + "name": "isAnimationProp" + }, + { + "name": "isArray" + }, + { + "name": "isArrayLike" + }, + { + "name": "isComponentDef" + }, + { + "name": "isComponentHost" + }, + { + "name": "isContentQueryHost" + }, + { + "name": "isCssClassMatching" + }, + { + "name": "isCurrentTNodeParent" + }, + { + "name": "isDirectiveHost" + }, + { + "name": "isEmptyInputValue" + }, + { + "name": "isForwardRef" + }, + { + "name": "isFunction" + }, + { + "name": "isInCheckNoChangesMode" + }, + { + "name": "isInlineTemplate" + }, + { + "name": "isJsObject" + }, + { + "name": "isLContainer" + }, + { + "name": "isLView" + }, + { + "name": "isListLikeIterable" + }, + { + "name": "isNodeMatchingSelector" + }, + { + "name": "isNodeMatchingSelectorList" + }, + { + "name": "isObject" + }, + { + "name": "isObservable" + }, + { + "name": "isOptionsObj" + }, + { + "name": "isPositive" + }, + { + "name": "isPresent" + }, + { + "name": "isProceduralRenderer" + }, + { + "name": "isPromise" + }, + { + "name": "isPromise" + }, + { + "name": "isScheduler" + }, + { + "name": "isStylingMatch" + }, + { + "name": "isStylingValuePresent" + }, + { + "name": "isTypeProvider" + }, + { + "name": "isValueProvider" + }, + { + "name": "iterator" + }, + { + "name": "keyValDiff" + }, + { + "name": "keyValueArrayGet" + }, + { + "name": "keyValueArrayIndexOf" + }, + { + "name": "keyValueArraySet" + }, + { + "name": "leaveDI" + }, + { + "name": "leaveView" + }, + { + "name": "leaveViewLight" + }, + { + "name": "localeEn" + }, + { + "name": "lookupTokenUsingModuleInjector" + }, + { + "name": "makeParamDecorator" + }, + { + "name": "makeRecord" + }, + { + "name": "map" + }, + { + "name": "markAsComponentHost" + }, + { + "name": "markDuplicates" + }, + { + "name": "markViewDirty" + }, + { + "name": "maybeUnwrapEmpty" + }, + { + "name": "maybeUnwrapFn" + }, + { + "name": "maybeWrapInNotSelector" + }, + { + "name": "mergeAll" + }, + { + "name": "mergeErrors" + }, + { + "name": "mergeHostAttribute" + }, + { + "name": "mergeHostAttrs" + }, + { + "name": "mergeValidators" + }, + { + "name": "modelGroupProvider" + }, + { + "name": "modules" + }, + { + "name": "multiFactoryAdd" + }, + { + "name": "multiProvidersFactoryResolver" + }, + { + "name": "multiResolve" + }, + { + "name": "multiViewProvidersFactoryResolver" + }, + { + "name": "nativeAppendChild" + }, + { + "name": "nativeAppendOrInsertBefore" + }, + { + "name": "nativeInsertBefore" + }, + { + "name": "nativeParentNode" + }, + { + "name": "nextBindingIndex" + }, + { + "name": "nextNgElementId" + }, + { + "name": "ngOnChangesSetInput" + }, + { + "name": "noSideEffects" + }, + { + "name": "noop" + }, + { + "name": "noop" + }, + { + "name": "normalizeValidators" + }, + { + "name": "notFoundValueOrThrow" + }, + { + "name": "observable" + }, + { + "name": "onEnter" + }, + { + "name": "onLeave" + }, + { + "name": "optionsReducer" + }, + { + "name": "pickAsyncValidators" + }, + { + "name": "pickValidators" + }, + { + "name": "pipeFromArray" + }, + { + "name": "platformBrowser" + }, + { + "name": "platformCore" + }, + { + "name": "promise" + }, + { + "name": "providerToFactory" + }, + { + "name": "readPatchedLView" + }, + { + "name": "refCount" + }, + { + "name": "refreshComponent" + }, + { + "name": "refreshContentQueries" + }, + { + "name": "refreshView" + }, + { + "name": "registerDestroyHooksIfSupported" + }, + { + "name": "registerHostBindingOpCodes" + }, + { + "name": "registerOnValidatorChange" + }, + { + "name": "registerPostOrderHooks" + }, + { + "name": "rememberChangeHistoryAndInvokeOnChangesHook" + }, + { + "name": "remove" + }, + { + "name": "removeFromArray" + }, + { + "name": "removeListItem" + }, + { + "name": "renderComponent" + }, + { + "name": "renderComponentOrTemplate" + }, + { + "name": "renderStringify" + }, + { + "name": "renderView" + }, + { + "name": "resetPreOrderHookFlags" + }, + { + "name": "resolveDirectives" + }, + { + "name": "resolveForwardRef" + }, + { + "name": "resolveProvider" + }, + { + "name": "resolvedPromise" + }, + { + "name": "resolvedPromise" + }, + { + "name": "rxSubscriber" + }, + { + "name": "saveNameToExportMap" + }, + { + "name": "saveResolvedLocalsInData" + }, + { + "name": "scheduleArray" + }, + { + "name": "scheduleMicroTask" + }, + { + "name": "searchTokensOnInjector" + }, + { + "name": "selectIndexInternal" + }, + { + "name": "setBindingRootForHostBindings" + }, + { + "name": "setCurrentDirectiveIndex" + }, + { + "name": "setCurrentInjector" + }, + { + "name": "setCurrentQueryIndex" + }, + { + "name": "setCurrentTNode" + }, + { + "name": "setDirectiveInputsWhichShadowsStyling" + }, + { + "name": "setIncludeViewProviders" + }, + { + "name": "setInjectImplementation" + }, + { + "name": "setInputsForProperty" + }, + { + "name": "setInputsFromAttrs" + }, + { + "name": "setIsInCheckNoChangesMode" + }, + { + "name": "setLocaleId" + }, + { + "name": "setSelectedIndex" + }, + { + "name": "setTStylingRangeNext" + }, + { + "name": "setTStylingRangeNextDuplicate" + }, + { + "name": "setTStylingRangePrevDuplicate" + }, + { + "name": "setUpAttributes" + }, + { + "name": "setUpControl" + }, + { + "name": "setUpValidators" + }, + { + "name": "shareSubjectFactory" + }, + { + "name": "shouldSearchParent" + }, + { + "name": "stringify" + }, + { + "name": "stringifyCSSSelector" + }, + { + "name": "stringifyForError" + }, + { + "name": "subscribeTo" + }, + { + "name": "subscribeToArray" + }, + { + "name": "throwProviderNotFoundError" + }, + { + "name": "toObservable" + }, + { + "name": "toRefArray" + }, + { + "name": "toTStylingRange" + }, + { + "name": "trackByIdentity" + }, + { + "name": "u" + }, + { + "name": "unwrapRNode" + }, + { + "name": "updateControl" + }, + { + "name": "updateMicroTaskStatus" + }, + { + "name": "updateTransplantedViewCount" + }, + { + "name": "viewAttachedToChangeDetector" + }, + { + "name": "wrapListener" + }, + { + "name": "writeDirectClass" + }, + { + "name": "writeDirectStyle" + }, + { + "name": "ɵAbstractFormGroupDirective_BaseFactory" + }, + { + "name": "ɵInternalFormsSharedModule" + }, + { + "name": "ɵNgNoValidate" + }, + { + "name": "ɵɵInheritDefinitionFeature" + }, + { + "name": "ɵɵNgOnChangesFeature" + }, + { + "name": "ɵɵProvidersFeature" + }, + { + "name": "ɵɵadvance" + }, + { + "name": "ɵɵattribute" + }, + { + "name": "ɵɵclassProp" + }, + { + "name": "ɵɵdefineComponent" + }, + { + "name": "ɵɵdefineDirective" + }, + { + "name": "ɵɵdefineInjectable" + }, + { + "name": "ɵɵdefineInjector" + }, + { + "name": "ɵɵdefineNgModule" + }, + { + "name": "ɵɵdirectiveInject" + }, + { + "name": "ɵɵelement" + }, + { + "name": "ɵɵelementEnd" + }, + { + "name": "ɵɵelementStart" + }, + { + "name": "ɵɵgetInheritedFactory" + }, + { + "name": "ɵɵinject" + }, + { + "name": "ɵɵlistener" + }, + { + "name": "ɵɵnextContext" + }, + { + "name": "ɵɵproperty" + }, + { + "name": "ɵɵtext" + } +] \ No newline at end of file diff --git a/packages/core/test/bundling/forms_template_driven/forms_e2e_spec.ts b/packages/core/test/bundling/forms_template_driven/forms_e2e_spec.ts new file mode 100644 index 0000000000..fb67ed4908 --- /dev/null +++ b/packages/core/test/bundling/forms_template_driven/forms_e2e_spec.ts @@ -0,0 +1,46 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import '@angular/compiler'; +import {ɵwhenRendered as whenRendered} from '@angular/core'; +import {withBody} from '@angular/private/testing'; +import * as path from 'path'; + +const PACKAGE = 'angular/packages/core/test/bundling/forms_template_driven'; +const BUNDLES = ['bundle.js', 'bundle.min_debug.js', 'bundle.min.js']; + +describe('functional test for forms', () => { + BUNDLES.forEach((bundle) => { + describe(`using ${bundle} bundle`, () => { + it('should render template form', withBody('', async () => { + require(path.join(PACKAGE, bundle)); + await (window as any).waitForApp; + + // Template forms + const templateFormsComponent = (window as any).templateFormsComponent; + await whenRendered(templateFormsComponent); + + const templateForm = document.querySelector('app-template-forms')!; + + // Check for inputs + const iputs = templateForm.querySelectorAll('input'); + expect(iputs.length).toBe(5); + + // Check for button + const templateButtons = templateForm.querySelectorAll('button'); + expect(templateButtons.length).toBe(1); + expect(templateButtons[0]).toBeDefined(); + + // Make sure button click works + const templateFormSpy = spyOn(templateFormsComponent, 'addCity'); + templateButtons[0].click(); + expect(templateFormSpy).toHaveBeenCalled(); + })); + }); + }); +}); diff --git a/packages/core/test/bundling/forms_template_driven/index.html b/packages/core/test/bundling/forms_template_driven/index.html new file mode 100644 index 0000000000..a1c883fd25 --- /dev/null +++ b/packages/core/test/bundling/forms_template_driven/index.html @@ -0,0 +1,32 @@ + + + + + Angular Template-driven Forms Example + + + + + + + + + + diff --git a/packages/core/test/bundling/forms_template_driven/index.ts b/packages/core/test/bundling/forms_template_driven/index.ts new file mode 100644 index 0000000000..fb03c5c0c5 --- /dev/null +++ b/packages/core/test/bundling/forms_template_driven/index.ts @@ -0,0 +1,74 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +import {Component, NgModule, ɵNgModuleFactory as NgModuleFactory} from '@angular/core'; +import {FormsModule} from '@angular/forms'; +import {BrowserModule, platformBrowser} from '@angular/platform-browser'; + +@Component({ + selector: 'app-template-forms', + template: ` +
+
+
+ First Name: + +
+
+ Last Name: + +
+
+ Subscribe: + +
+ +
Disabled:
+ +
+ City +
+ + +
+
+ ` +}) +class TemplateFormsComponent { + name = {first: 'Nancy', last: 'Drew', subscribed: true}; + addresses = [{city: 'Toronto'}]; + constructor() { + // We use this reference in our test + (window as any).templateFormsComponent = this; + } + + addCity() { + this.addresses.push({city: ''}); + } +} + +@Component({ + selector: 'app-root', + template: ` + + ` +}) +class RootComponent { +} + +@NgModule({ + declarations: [RootComponent, TemplateFormsComponent], + imports: [BrowserModule, FormsModule], +}) +class FormsExampleModule { + ngDoBootstrap(app: any) { + app.bootstrap(RootComponent); + } +} + +(window as any).waitForApp = platformBrowser().bootstrapModuleFactory( + new NgModuleFactory(FormsExampleModule), {ngZone: 'noop'}); diff --git a/packages/core/test/bundling/forms_template_driven/treeshaking_spec.ts b/packages/core/test/bundling/forms_template_driven/treeshaking_spec.ts new file mode 100644 index 0000000000..5bbd672263 --- /dev/null +++ b/packages/core/test/bundling/forms_template_driven/treeshaking_spec.ts @@ -0,0 +1,35 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import '@angular/compiler'; +import * as fs from 'fs'; +import * as path from 'path'; + +const UTF8 = { + encoding: 'utf-8' +}; +const PACKAGE = 'angular/packages/core/test/bundling/forms_template_driven'; + +describe('treeshaking with uglify', () => { + let content: string; + // We use the debug version as otherwise symbols/identifiers would be mangled (and the test would + // always pass) + const contentPath = require.resolve(path.join(PACKAGE, 'bundle.min_debug.js')); + beforeAll(() => { + content = fs.readFileSync(contentPath, UTF8); + }); + + it('should drop unused TypeScript helpers', () => { + expect(content).not.toContain('__asyncGenerator'); + }); + + it('should not contain rxjs from commonjs distro', () => { + expect(content).not.toContain('commonjsGlobal'); + expect(content).not.toContain('createCommonjsModule'); + }); +});