diff --git a/src/lib/input/input-container-errors.ts b/src/lib/input/input-container-errors.ts
index 214997f60f6..55485ac1b14 100644
--- a/src/lib/input/input-container-errors.ts
+++ b/src/lib/input/input-container-errors.ts
@@ -20,3 +20,11 @@ export class MdInputContainerDuplicatedHintError extends MdError {
super(`A hint was already declared for 'align="${align}"'.`);
}
}
+
+
+export class MdInputContainerMissingMdInputError extends MdError {
+ constructor() {
+ super('md-input-container must contain an md-input directive. Did you forget to add md-input ' +
+ 'to the native input or textarea element?');
+ }
+}
diff --git a/src/lib/input/input-container.spec.ts b/src/lib/input/input-container.spec.ts
index c0c2bd1985c..defb792f5a9 100644
--- a/src/lib/input/input-container.spec.ts
+++ b/src/lib/input/input-container.spec.ts
@@ -6,6 +6,11 @@ import {MdInputModule} from './input';
import {MdInputContainer} from './input-container';
import {MdPlatform} from '../core/platform/platform';
import {PlatformModule} from '../core/platform/index';
+import {
+ MdInputContainerMissingMdInputError,
+ MdInputContainerPlaceholderConflictError,
+ MdInputContainerDuplicatedHintError
+} from './input-container-errors';
describe('MdInputContainer', function () {
@@ -35,6 +40,7 @@ describe('MdInputContainer', function () {
MdInputContainerNumberTestController,
MdTextareaWithBindings,
MdInputContainerWithDisabled,
+ MdInputContainerMissingMdInputTestController
],
});
@@ -150,25 +156,29 @@ describe('MdInputContainer', function () {
it('validates there\'s only one hint label per side', () => {
let fixture = TestBed.createComponent(MdInputContainerInvalidHintTestController);
- expect(() => fixture.detectChanges()).toThrow();
- // TODO(jelbourn): .toThrow(new MdInputContainerDuplicatedHintError('start'));
- // See https://github.com/angular/angular/issues/8348
+ expect(() => fixture.detectChanges()).toThrowError(
+ angularWrappedErrorMessage(new MdInputContainerDuplicatedHintError('start')));
});
it('validates there\'s only one hint label per side (attribute)', () => {
let fixture = TestBed.createComponent(MdInputContainerInvalidHint2TestController);
- expect(() => fixture.detectChanges()).toThrow();
- // TODO(jelbourn): .toThrow(new MdInputContainerDuplicatedHintError('start'));
- // See https://github.com/angular/angular/issues/8348
+ expect(() => fixture.detectChanges()).toThrowError(
+ angularWrappedErrorMessage(new MdInputContainerDuplicatedHintError('start')));
});
it('validates there\'s only one placeholder', () => {
let fixture = TestBed.createComponent(MdInputContainerInvalidPlaceholderTestController);
- expect(() => fixture.detectChanges()).toThrow();
- // TODO(jelbourn): .toThrow(new MdInputContainerPlaceholderConflictError());
- // See https://github.com/angular/angular/issues/8348
+ expect(() => fixture.detectChanges()).toThrowError(
+ angularWrappedErrorMessage(new MdInputContainerPlaceholderConflictError()));
+ });
+
+ it('validates that md-input child is present', () => {
+ let fixture = TestBed.createComponent(MdInputContainerMissingMdInputTestController);
+
+ expect(() => fixture.detectChanges()).toThrowError(
+ angularWrappedErrorMessage(new MdInputContainerMissingMdInputError()));
});
it('validates the type', () => {
@@ -406,3 +416,21 @@ class MdTextareaWithBindings {
cols: number = 8;
wrap: string = 'hard';
}
+
+@Component({
+ template: ``
+})
+class MdInputContainerMissingMdInputTestController {}
+
+/**
+ * Gets a RegExp used to detect an angular wrapped error message.
+ * See https://github.com/angular/angular/issues/8348
+ */
+const angularWrappedErrorMessage = (e: Error) =>
+ new RegExp(`.*caused by: ${regexpEscape(e.message)}$`);
+
+/**
+ * Escape a string for use inside a RegExp.
+ * Based on https://github.com/sindresorhus/escape-string-regex
+ */
+const regexpEscape = (s: string) => s.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
diff --git a/src/lib/input/input-container.ts b/src/lib/input/input-container.ts
index 4fedf96e7cd..241a6738633 100644
--- a/src/lib/input/input-container.ts
+++ b/src/lib/input/input-container.ts
@@ -19,7 +19,8 @@ import {getSupportedInputTypes} from '../core/platform/features';
import {
MdInputContainerUnsupportedTypeError,
MdInputContainerPlaceholderConflictError,
- MdInputContainerDuplicatedHintError
+ MdInputContainerDuplicatedHintError,
+ MdInputContainerMissingMdInputError
} from './input-container-errors';
@@ -218,6 +219,10 @@ export class MdInputContainer implements AfterContentInit {
@ContentChildren(MdHint) _hintChildren: QueryList;
ngAfterContentInit() {
+ if (!this._mdInputChild) {
+ throw new MdInputContainerMissingMdInputError();
+ }
+
this._validateHints();
this._validatePlaceholders();