@@ -839,7 +839,7 @@ func TestParameterValidation(t *testing.T) {
839839t .Run (tc .Name ,func (t * testing.T ) {
840840t .Parallel ()
841841value := & tc .Value
842- _ ,diags := tc .Parameter .ValidateInput (value )
842+ _ ,diags := tc .Parameter .ValidateInput (value , nil )
843843if tc .ExpectError != nil {
844844require .True (t ,diags .HasError ())
845845errMsg := fmt .Sprintf ("%+v" ,diags [0 ])// close enough
@@ -881,6 +881,7 @@ func TestParameterValidationEnforcement(t *testing.T) {
881881OutputValue string
882882Optional bool
883883CreateError * regexp.Regexp
884+ Previous * string
884885}
885886
886887rows := make ([]row ,0 )
@@ -898,33 +899,44 @@ func TestParameterValidationEnforcement(t *testing.T) {
898899continue // Skip rows with empty names
899900}
900901
901- optional ,err := strconv .ParseBool (columns [8 ])
902- if columns [8 ]!= "" {
902+ cname ,ctype ,cprev ,cinput ,cdefault ,coptions ,cvalidation ,_ ,coutput ,coptional ,cerr :=
903+ columns [0 ],columns [1 ],columns [2 ],columns [3 ],columns [4 ],columns [5 ],columns [6 ],columns [7 ],columns [8 ],columns [9 ],columns [10 ]
904+
905+ optional ,err := strconv .ParseBool (coptional )
906+ if coptional != "" {
903907// Value does not matter if not specified
904908require .NoError (t ,err )
905909}
906910
907911var rerr * regexp.Regexp
908- if columns [ 9 ] != "" {
909- rerr ,err = regexp .Compile (columns [ 9 ] )
912+ if cerr != "" {
913+ rerr ,err = regexp .Compile (cerr )
910914if err != nil {
911- t .Fatalf ("failed to parse error column %q: %v" ,columns [ 9 ] ,err )
915+ t .Fatalf ("failed to parse error column %q: %v" ,cerr ,err )
912916}
913917}
914918
915919var options []string
916- if columns [ 4 ] != "" {
917- options = strings .Split (columns [ 4 ] ,"," )
920+ if coptions != "" {
921+ options = strings .Split (coptions ,"," )
918922}
919923
920924var validation * provider.Validation
921- if columns [5 ]!= "" {
922- // Min-Max validation should look like:
923- //1-10 :: min=1, max=10
924- //-10 :: max=10
925- //1- :: min=1
926- if validMinMax .MatchString (columns [5 ]) {
927- parts := strings .Split (columns [5 ],"-" )
925+ if cvalidation != "" {
926+ switch {
927+ case cvalidation == provider .ValidationMonotonicIncreasing || cvalidation == provider .ValidationMonotonicDecreasing :
928+ validation = & provider.Validation {
929+ MinDisabled :true ,
930+ MaxDisabled :true ,
931+ Monotonic :cvalidation ,
932+ Error :"monotonicity" ,
933+ }
934+ case validMinMax .MatchString (cvalidation ):
935+ // Min-Max validation should look like:
936+ //1-10 :: min=1, max=10
937+ //-10 :: max=10
938+ //1- :: min=1
939+ parts := strings .Split (cvalidation ,"-" )
928940min ,_ := strconv .ParseInt (parts [0 ],10 ,64 )
929941max ,_ := strconv .ParseInt (parts [1 ],10 ,64 )
930942validation = & provider.Validation {
@@ -936,29 +948,37 @@ func TestParameterValidationEnforcement(t *testing.T) {
936948Regex :"" ,
937949Error :"{min} < {value} < {max}" ,
938950}
939- } else {
951+ default :
940952validation = & provider.Validation {
941953Min :0 ,
942954MinDisabled :true ,
943955Max :0 ,
944956MaxDisabled :true ,
945957Monotonic :"" ,
946- Regex :columns [ 5 ] ,
958+ Regex :cvalidation ,
947959Error :"regex error" ,
948960}
949961}
950962}
951963
964+ var prev * string
965+ if cprev != "" {
966+ prev = ptr (cprev )
967+ if cprev == `""` {
968+ prev = ptr ("" )
969+ }
970+ }
952971rows = append (rows ,row {
953- Name :columns [ 0 ] ,
954- Types :strings .Split (columns [ 1 ] ,"," ),
955- InputValue :columns [ 2 ] ,
956- Default :columns [ 3 ] ,
972+ Name :cname ,
973+ Types :strings .Split (ctype ,"," ),
974+ InputValue :cinput ,
975+ Default :cdefault ,
957976Options :options ,
958977Validation :validation ,
959- OutputValue :columns [ 7 ] ,
978+ OutputValue :coutput ,
960979Optional :optional ,
961980CreateError :rerr ,
981+ Previous :prev ,
962982})
963983}
964984
@@ -976,6 +996,9 @@ func TestParameterValidationEnforcement(t *testing.T) {
976996if row .InputValue != "" {
977997t .Setenv (provider .ParameterEnvironmentVariable ("parameter" ),row .InputValue )
978998}
999+ if row .Previous != nil {
1000+ t .Setenv (provider .ParameterEnvironmentVariablePrevious ("parameter" ),* row .Previous )
1001+ }
9791002
9801003if row .CreateError != nil && row .OutputValue != "" {
9811004t .Errorf ("output value %q should not be set if both errors are set" ,row .OutputValue )
@@ -1067,6 +1090,7 @@ func TestValueValidatesType(t *testing.T) {
10671090Name string
10681091Type provider.OptionType
10691092Value string
1093+ Previous * string
10701094Regex string
10711095RegexError string
10721096Min int
@@ -1154,6 +1178,56 @@ func TestValueValidatesType(t *testing.T) {
11541178Min :0 ,
11551179Max :2 ,
11561180Monotonic :"decreasing" ,
1181+ }, {
1182+ Name :"IncreasingMonotonicityEqual" ,
1183+ Type :"number" ,
1184+ Previous :ptr ("1" ),
1185+ Value :"1" ,
1186+ Monotonic :"increasing" ,
1187+ MinDisabled :true ,
1188+ MaxDisabled :true ,
1189+ }, {
1190+ Name :"DecreasingMonotonicityEqual" ,
1191+ Type :"number" ,
1192+ Value :"1" ,
1193+ Previous :ptr ("1" ),
1194+ Monotonic :"decreasing" ,
1195+ MinDisabled :true ,
1196+ MaxDisabled :true ,
1197+ }, {
1198+ Name :"IncreasingMonotonicityGreater" ,
1199+ Type :"number" ,
1200+ Previous :ptr ("0" ),
1201+ Value :"1" ,
1202+ Monotonic :"increasing" ,
1203+ MinDisabled :true ,
1204+ MaxDisabled :true ,
1205+ }, {
1206+ Name :"DecreasingMonotonicityGreater" ,
1207+ Type :"number" ,
1208+ Value :"1" ,
1209+ Previous :ptr ("0" ),
1210+ Monotonic :"decreasing" ,
1211+ MinDisabled :true ,
1212+ MaxDisabled :true ,
1213+ Error :regexp .MustCompile ("must be equal or" ),
1214+ }, {
1215+ Name :"IncreasingMonotonicityLesser" ,
1216+ Type :"number" ,
1217+ Previous :ptr ("2" ),
1218+ Value :"1" ,
1219+ Monotonic :"increasing" ,
1220+ MinDisabled :true ,
1221+ MaxDisabled :true ,
1222+ Error :regexp .MustCompile ("must be equal or" ),
1223+ }, {
1224+ Name :"DecreasingMonotonicityLesser" ,
1225+ Type :"number" ,
1226+ Value :"1" ,
1227+ Previous :ptr ("2" ),
1228+ Monotonic :"decreasing" ,
1229+ MinDisabled :true ,
1230+ MaxDisabled :true ,
11571231}, {
11581232Name :"ValidListOfStrings" ,
11591233Type :"list(string)" ,
@@ -1205,7 +1279,7 @@ func TestValueValidatesType(t *testing.T) {
12051279Regex :tc .Regex ,
12061280Error :tc .RegexError ,
12071281}
1208- err := v .Valid (tc .Type ,tc .Value )
1282+ err := v .Valid (tc .Type ,tc .Value , tc . Previous )
12091283if tc .Error != nil {
12101284require .Error (t ,err )
12111285require .True (t ,tc .Error .MatchString (err .Error ()),"got: %s" ,err .Error ())