@@ -1975,6 +1975,84 @@ describe('input', function() {
1975
1975
'ng-model-options="{ getterSetter: true }" />' ) ;
1976
1976
} ) ;
1977
1977
1978
+ it ( 'should try to invoke a model with global context if getterSetter is true and ngModelContext is not provided' , inject ( function ( $window ) {
1979
+ $window . value = 'global' ;
1980
+ compileInput (
1981
+ '<input type="text" ng-model="someService.getterSetter" ' +
1982
+ 'ng-model-options="{ getterSetter: true }" />' ) ;
1983
+
1984
+ scope . someService = {
1985
+ value : 'b' ,
1986
+ getterSetter : function ( newValue ) {
1987
+ this . value = newValue || this . value ;
1988
+ return this . value ;
1989
+ }
1990
+ } ;
1991
+ spyOn ( scope . someService , 'getterSetter' ) . andCallThrough ( ) ;
1992
+ scope . $apply ( ) ;
1993
+ expect ( inputElm . val ( ) ) . toBe ( 'global' ) ;
1994
+ expect ( scope . someService . getterSetter ) . toHaveBeenCalledWith ( ) ;
1995
+ expect ( scope . someService . value ) . toBe ( 'b' ) ; // 'this' is not bound to the service w/o ngModelContext
1996
+ expect ( $window . value ) . toBe ( 'global' ) ;
1997
+
1998
+ changeInputValueTo ( 'a' ) ;
1999
+ expect ( scope . someService . getterSetter ) . toHaveBeenCalledWith ( 'a' ) ;
2000
+ expect ( scope . someService . value ) . toBe ( 'b' ) ;
2001
+ expect ( $window . value ) . toBe ( 'a' ) ;
2002
+
2003
+ scope . someService . value = 'c' ;
2004
+ scope . $apply ( ) ;
2005
+ expect ( inputElm . val ( ) ) . toBe ( 'a' ) ;
2006
+ expect ( scope . someService . getterSetter ) . toHaveBeenCalledWith ( ) ;
2007
+ expect ( scope . someService . value ) . toBe ( 'c' ) ;
2008
+ expect ( $window . value ) . toBe ( 'a' ) ;
2009
+
2010
+ $window . value = 'd' ;
2011
+ scope . $apply ( ) ;
2012
+ expect ( inputElm . val ( ) ) . toBe ( 'd' ) ;
2013
+ expect ( scope . someService . getterSetter ) . toHaveBeenCalledWith ( ) ;
2014
+ expect ( scope . someService . value ) . toBe ( 'c' ) ;
2015
+ expect ( $window . value ) . toBe ( 'd' ) ;
2016
+ } ) ) ;
2017
+
2018
+ it ( 'should try to invoke a model with the provided context if getterSetter is true and ngModelContext is provided' , function ( ) {
2019
+ compileInput (
2020
+ '<input type="text" ng-model="someService.getterSetter" ' +
2021
+ 'ng-model-context="someService" ' +
2022
+ 'ng-model-options="{ getterSetter: true }" />' ) ;
2023
+
2024
+ scope . someService = {
2025
+ value : 'b' ,
2026
+ getterSetter : function ( newValue ) {
2027
+ this . value = newValue || this . value ;
2028
+ return this . value ;
2029
+ }
2030
+ } ;
2031
+ spyOn ( scope . someService , 'getterSetter' ) . andCallThrough ( ) ;
2032
+ scope . $apply ( ) ;
2033
+ expect ( inputElm . val ( ) ) . toBe ( 'b' ) ;
2034
+ expect ( scope . someService . getterSetter ) . toHaveBeenCalledWith ( ) ;
2035
+ expect ( scope . someService . value ) . toBe ( 'b' ) ;
2036
+
2037
+ changeInputValueTo ( 'a' ) ;
2038
+ expect ( scope . someService . getterSetter ) . toHaveBeenCalledWith ( 'a' ) ;
2039
+ expect ( scope . someService . value ) . toBe ( 'a' ) ;
2040
+
2041
+ scope . someService . value = 'c' ;
2042
+ scope . $apply ( ) ;
2043
+ expect ( inputElm . val ( ) ) . toBe ( 'c' ) ;
2044
+ expect ( scope . someService . getterSetter ) . toHaveBeenCalledWith ( ) ;
2045
+ expect ( scope . someService . value ) . toBe ( 'c' ) ;
2046
+ } ) ;
2047
+
2048
+ it ( 'should fail on non-assignable ngModelContext binding' , function ( ) {
2049
+ expect ( function ( ) {
2050
+ compileInput ( '<input type="text" ng-model="someService.getterSetter" ' +
2051
+ 'ng-model-context="someService.getInstance()" ' +
2052
+ 'ng-model-options="{ getterSetter: true }" />' ) ;
2053
+ } ) . toThrowMinErr ( 'ngModel' , 'nonassign' , 'Expression \'someService.getInstance()\' is non-assignable.' ) ;
2054
+ } ) ;
2055
+
1978
2056
it ( 'should assign invalid values to the scope if allowInvalid is true' , function ( ) {
1979
2057
compileInput ( '<input type="text" name="input" ng-model="value" maxlength="1" ' +
1980
2058
'ng-model-options="{allowInvalid: true}" />' ) ;
0 commit comments