gitlab.com/evatix-go/core@v1.3.55/corevalidator/SliceValidator.go (about) 1 package corevalidator 2 3 import ( 4 "errors" 5 "strings" 6 7 "gitlab.com/evatix-go/core/constants" 8 "gitlab.com/evatix-go/core/enums/stringcompareas" 9 "gitlab.com/evatix-go/core/errcore" 10 "gitlab.com/evatix-go/core/internal/strutilinternal" 11 ) 12 13 type SliceValidator struct { 14 ValidatorCoreCondition 15 CompareAs stringcompareas.Variant 16 // ActualLines considered to be actual 17 // ExpectedLines considered to be expected 18 ActualLines, ExpectedLines []string 19 comparingValidators *TextValidators // lazy 20 } 21 22 func NewSliceValidatorUsingErr( 23 errActual error, 24 compareLinesContentAsExpected string, 25 isTrimLineCompare, 26 isNonEmptyWhitespace, 27 isSortStringsBySpace bool, 28 compareAs stringcompareas.Variant, 29 ) *SliceValidator { 30 inputLines := errcore.ErrorToSplitLines(errActual) 31 compareLines := strings.Split( 32 compareLinesContentAsExpected, 33 constants.NewLineUnix) 34 35 return &SliceValidator{ 36 ActualLines: inputLines, 37 ExpectedLines: compareLines, 38 ValidatorCoreCondition: ValidatorCoreCondition{ 39 IsTrimCompare: isTrimLineCompare, 40 IsNonEmptyWhitespace: isNonEmptyWhitespace, 41 IsSortStringsBySpace: isSortStringsBySpace, 42 }, 43 CompareAs: compareAs, 44 comparingValidators: nil, 45 } 46 } 47 48 func NewSliceValidatorUsingAny( 49 anyValActual interface{}, 50 compareLinesContentExpected string, 51 isTrimLineCompare, 52 isNonEmptyWhitespace, 53 isSortStringsBySpace bool, 54 compareAs stringcompareas.Variant, 55 ) *SliceValidator { 56 anyToString := strutilinternal.AnyToString(anyValActual) 57 splitLines := strings.Split(anyToString, constants.NewLineUnix) 58 compareLines := strings.Split( 59 compareLinesContentExpected, 60 constants.NewLineUnix) 61 62 return &SliceValidator{ 63 ActualLines: splitLines, 64 ExpectedLines: compareLines, 65 ValidatorCoreCondition: ValidatorCoreCondition{ 66 IsTrimCompare: isTrimLineCompare, 67 IsNonEmptyWhitespace: isNonEmptyWhitespace, 68 IsSortStringsBySpace: isSortStringsBySpace, 69 }, 70 CompareAs: compareAs, 71 comparingValidators: nil, 72 } 73 } 74 75 func (it *SliceValidator) ActualLinesLength() int { 76 if it == nil { 77 return 0 78 } 79 80 return len(it.ActualLines) 81 } 82 83 func (it *SliceValidator) MethodName() string { 84 return it.CompareAs.Name() 85 } 86 87 func (it *SliceValidator) IsValidOtherLines( 88 isCaseSensitive bool, 89 otherActualLines []string, 90 ) bool { 91 return it. 92 isValidLines( 93 isCaseSensitive, 94 otherActualLines) 95 } 96 97 func (it *SliceValidator) SetActual( 98 actual []string, 99 ) *SliceValidator { 100 it.ActualLines = actual 101 102 return it 103 } 104 105 func (it *SliceValidator) SetActualVsExpected( 106 actual, expected []string, 107 ) *SliceValidator { 108 it.ActualLines = actual 109 it.ExpectedLines = expected 110 111 return it 112 } 113 114 func (it *SliceValidator) ActualLinesString() string { 115 if it == nil { 116 return constants.EmptyString 117 } 118 119 return errcore.StringLinesToQuoteLinesToSingle( 120 it.ActualLines) 121 } 122 123 func (it *SliceValidator) ExpectingLinesString() string { 124 if it == nil { 125 return constants.EmptyString 126 } 127 128 return errcore.StringLinesToQuoteLinesToSingle( 129 it.ExpectedLines) 130 } 131 132 func (it *SliceValidator) ExpectingLinesLength() int { 133 if it == nil { 134 return 0 135 } 136 137 return len(it.ExpectedLines) 138 } 139 140 func (it *SliceValidator) ComparingValidators() *TextValidators { 141 if it.comparingValidators != nil { 142 return it.comparingValidators 143 } 144 145 validators := NewTextValidators(it.ExpectingLinesLength()) 146 147 for _, line := range it.ExpectedLines { 148 validators.Add(TextValidator{ 149 Search: line, 150 ValidatorCoreCondition: it.ValidatorCoreCondition, 151 SearchAs: it.CompareAs, 152 }) 153 } 154 155 it.comparingValidators = validators 156 157 return it.comparingValidators 158 } 159 160 func (it *SliceValidator) IsValid(isCaseSensitive bool) bool { 161 if it == nil { 162 return true 163 } 164 165 return it.isValidLines( 166 isCaseSensitive, 167 it.ActualLines) 168 } 169 170 func (it *SliceValidator) isValidLines( 171 isCaseSensitive bool, 172 lines []string, 173 ) bool { 174 if it == nil && lines == nil { 175 return true 176 } 177 178 if lines == nil && it.ExpectedLines == nil { 179 return true 180 } 181 182 if lines == nil || it.ExpectedLines == nil { 183 return false 184 } 185 186 inputLength := len(lines) 187 comparingLength := len(it.ExpectedLines) 188 189 if inputLength != comparingLength { 190 return false 191 } 192 193 validators := it.ComparingValidators() 194 195 for i, validator := range validators.Items { 196 isNotMatch := !validator.IsMatch( 197 lines[i], 198 isCaseSensitive) 199 200 if isNotMatch { 201 return false 202 } 203 } 204 205 return true 206 } 207 208 func (it *SliceValidator) VerifyFirstError( 209 paramsBase *ValidatorParamsBase, 210 ) error { 211 if it == nil { 212 return nil 213 } 214 215 return it.VerifyFirstLengthUptoError( 216 paramsBase, 217 it.ExpectingLinesLength()) 218 } 219 220 func (it *SliceValidator) VerifyFirstLengthUptoError( 221 params *ValidatorParamsBase, 222 lengthUpTo int, 223 ) error { 224 if it == nil { 225 return nil 226 } 227 228 return it.AllVerifyErrorUptoLength( 229 true, 230 params, 231 lengthUpTo) 232 } 233 234 func (it *SliceValidator) AllVerifyError( 235 params *ValidatorParamsBase, 236 ) error { 237 if it == nil { 238 return nil 239 } 240 241 return it.AllVerifyErrorUptoLength( 242 false, 243 params, 244 it.ExpectingLinesLength()) 245 } 246 247 func (it *SliceValidator) AllVerifyErrorTestCase( 248 caseIndex int, 249 isCaseSensitive bool, 250 ) error { 251 if it == nil { 252 return nil 253 } 254 255 params := ValidatorParamsBase{ 256 CaseIndex: caseIndex, 257 IsIgnoreCompareOnActualInputEmpty: false, 258 IsAttachUserInputs: true, 259 IsCaseSensitive: isCaseSensitive, 260 } 261 262 err := it.AllVerifyErrorUptoLength( 263 false, 264 ¶ms, 265 it.ExpectingLinesLength()) 266 267 errcore.ErrPrintWithTestIndex(caseIndex, err) 268 269 return err 270 } 271 272 func (it *SliceValidator) AllVerifyErrorExceptLast( 273 params *ValidatorParamsBase, 274 ) error { 275 if it == nil { 276 return nil 277 } 278 279 return it.AllVerifyErrorUptoLength( 280 false, 281 params, 282 it.ExpectingLinesLength()-1) 283 } 284 285 func (it *SliceValidator) AllVerifyErrorUptoLength( 286 isFirstOnly bool, 287 params *ValidatorParamsBase, 288 lengthUpto int, 289 ) error { 290 if it == nil { 291 return nil 292 } 293 294 if it.isEmptyIgnoreCase(params) { 295 return nil 296 } 297 298 initialVerifyErr := it.initialVerifyErrorWithMerged( 299 params, 300 lengthUpto) 301 302 if initialVerifyErr != nil { 303 return initialVerifyErr 304 } 305 306 lengthErr := it.lengthVerifyError(params, lengthUpto) 307 if lengthErr != nil { 308 return lengthErr 309 } 310 311 validators := it.ComparingValidators() 312 var sliceErr []string 313 for i, validator := range validators.Items[:lengthUpto] { 314 err := validator.VerifySimpleError( 315 i, 316 params, 317 it.ActualLines[i]) 318 319 if err != nil { 320 sliceErr = append( 321 sliceErr, 322 err.Error()) 323 } 324 325 if isFirstOnly && err != nil { 326 break 327 } 328 } 329 330 if params.IsAttachUserInputs && len(sliceErr) > constants.Zero { 331 sliceErr = append( 332 sliceErr, 333 it.ActualInputWithExpectingMessage(params.Header)) 334 } 335 336 return errcore.SliceToError(sliceErr) 337 } 338 339 func (it *SliceValidator) lengthVerifyError( 340 params *ValidatorParamsBase, 341 lengthUpto int, 342 ) error { 343 hasLengthUpto := lengthUpto > constants.InvalidValue 344 comparingLength := it.ExpectingLinesLength() 345 346 var comparingLengthError error 347 if hasLengthUpto && lengthUpto > comparingLength { 348 comparingLengthError = errcore.OutOfRangeLengthType.Error( 349 "Asked comparingLength is out of range!", 350 comparingLength, 351 ) 352 } 353 354 if comparingLengthError != nil { 355 return it.UserInputsMergeWithError( 356 params, 357 comparingLengthError) 358 } 359 360 var inputLengthErr error 361 if it.ActualLinesLength() > 0 && comparingLength == 0 { 362 inputLengthErr = errcore.LengthIssueType.Error( 363 "Input comparison has some text but comparing length is 0! Must set comparing text!", 364 comparingLength, 365 ) 366 } 367 368 if inputLengthErr != nil { 369 return it.UserInputsMergeWithError( 370 params, 371 inputLengthErr) 372 } 373 374 return nil 375 } 376 377 // initialVerifyError, verifyLengthUpto less than 0 will check actual length 378 func (it *SliceValidator) initialVerifyError( 379 lengthUpto int, 380 ) error { 381 if it.ActualLines == nil && it.ExpectedLines == nil { 382 return nil 383 } 384 385 isAnyNilCase := it.ActualLines == nil || 386 it.ExpectedLines == nil 387 388 if isAnyNilCase { 389 return errcore.ExpectingErrorSimpleNoType( 390 "ActualLines, ExpectedLines any is nil and other is not.", 391 it.ActualLines, 392 it.ExpectedLines, 393 ) 394 } 395 396 if !it.isLengthOkay(lengthUpto) { 397 return errcore.ExpectingErrorSimpleNoType( 398 "ActualLines, ExpectedLines Length is not equal", 399 len(it.ActualLines), 400 len(it.ExpectedLines), 401 ) 402 } 403 404 return nil 405 } 406 407 func (it *SliceValidator) isLengthOkay(lengthUpto int) bool { 408 inputLength := len(it.ActualLines) 409 comparingLength := len(it.ExpectedLines) 410 isLengthCheckUpto := lengthUpto > constants.InvalidValue 411 var isMinLengthMeet bool 412 413 if isLengthCheckUpto { 414 remainingInputLength := inputLength - lengthUpto 415 remainingCompareLength := comparingLength - lengthUpto 416 417 isMinLengthMeet = remainingInputLength == remainingCompareLength 418 } 419 420 isLengthOkay := isMinLengthMeet || 421 inputLength == comparingLength 422 423 return isLengthOkay 424 } 425 426 func (it *SliceValidator) initialVerifyErrorWithMerged( 427 params *ValidatorParamsBase, 428 lengthUpto int, 429 ) error { 430 initialVerifyErr := it.initialVerifyError( 431 lengthUpto) 432 433 if initialVerifyErr != nil { 434 return it.UserInputsMergeWithError( 435 params, 436 initialVerifyErr) 437 } 438 439 return nil 440 } 441 442 func (it *SliceValidator) ActualInputWithExpectingMessage(header string) string { 443 return it.ActualInputMessage(header) + 444 it.UserExpectingMessage() 445 } 446 447 func (it *SliceValidator) ActualInputMessage(header string) string { 448 return errcore.MsgHeaderPlusEnding( 449 actualUserInputsMessage+header, 450 it.ActualLinesString()) 451 } 452 453 func (it *SliceValidator) UserExpectingMessage() string { 454 return errcore.MsgHeaderPlusEnding( 455 expectingLinesMessage, 456 it.ExpectingLinesString()) 457 } 458 459 func (it *SliceValidator) isEmptyIgnoreCase( 460 params *ValidatorParamsBase, 461 ) bool { 462 return params.IsIgnoreCompareOnActualInputEmpty && 463 len(it.ActualLines) == 0 464 } 465 466 func (it *SliceValidator) UserInputsMergeWithError( 467 paramsBase *ValidatorParamsBase, 468 err error, 469 ) error { 470 if !paramsBase.IsAttachUserInputs { 471 return err 472 } 473 474 if err == nil { 475 return errors.New(it.ActualInputWithExpectingMessage(paramsBase.Header)) 476 } 477 478 msg := err.Error() + 479 it.ActualInputWithExpectingMessage(paramsBase.Header) 480 481 return errors.New(msg) 482 }