public void Validate(TestedMember testedMember, INamedTypeSymbol errorType, Action <Diagnostic> reportError) { var allCases = ComputeAllCases(errorType); foreach (var casesAnd in CasesAnd) { allCases.CasesAnd.Remove(casesAnd); } if (allCases.CasesAnd.Count == 0) { // No missing cases return; } // Missing cases reportError(SmartTestsDiagnostics.CreateMissingCases(testedMember, GetExpressionSyntax(), allCases.ToString())); foreach (var casesAnd in allCases.CasesAnd) { casesAnd.IsMissing = true; CasesAnd.Add(casesAnd); } }
private bool ValidateParameterNames(Action <Diagnostic> reportError, List <string> parameters) { if (parameters.Count <= 1) { // 0 or 1 parameter: the parameter name is not mandatory if (CasesAndOr.CasesAnd.Count == 1 && CasesAndOr.CasesAnd[0].Cases.Count == 1 && CasesAndOr.CasesAnd.First().Cases.Keys.First() == Case.NoParameter) { return(true); } } var result = true; foreach (var casesAnd in CasesAndOr.CasesAnd) { var unusedParameters = parameters.ToList(); var hasAnonymousCase = false; foreach (var aCase in casesAnd.Cases.Values) { if (aCase.ParameterName == Case.NoParameter) { hasAnonymousCase = true; continue; } if (unusedParameters.Remove(aCase.ParameterName)) { continue; } // This parameter name does not exist result = false; reportError(SmartTestsDiagnostics.CreateWrongParameterName(TestedMember, aCase.ParameterName, aCase.ParameterNameExpression)); } if (casesAnd.HasError) { continue; } // Remaining parameters have no Case! if (parameters.Count == 1 && hasAnonymousCase) { // When 1 parameter, parameter name is not mandatory continue; } foreach (var parameter in unusedParameters) { result = false; reportError(SmartTestsDiagnostics.CreateMissingParameterCase(TestedMember, parameter, casesAnd.Cases.First().Value.CaseExpressions.First())); } } return(result); }
protected bool TryGetSymbolicConstant <T>(ExpressionSyntax expression, out SymbolicConstant <T> value, bool acceptSymbolic = true) where T : IComparable <T> { var constant = Model.GetConstantValue(expression); if (!constant.HasValue) { var symbol = Model.GetSymbolInfo(expression).Symbol; if (_DateTimeConstants.TryGetValue(symbol, out var dt) || _DateTimeConstants.TryGetValue(symbol.OriginalDefinition, out dt)) { value = new SymbolicConstant <T>((T)(object)dt); return(true); } if (_DateTimeConstructions.Contains(symbol)) { return(TryCreateDateTime((ObjectCreationExpressionSyntax)expression, out value)); } if (acceptSymbolic) { if (symbol is IFieldSymbol field) { // Symbolic Range value = new SymbolicConstant <T>(field); return(true); } if (symbol is IPropertySymbol property && !property.IsIndexer) { // Symbolic Range value = new SymbolicConstant <T>(property); return(true); } } if (Equals((symbol as ILocalSymbol)?.Type ?? (symbol as IPropertySymbol)?.Type ?? (symbol as IMethodSymbol)?.ReturnType, _DateTimeType)) { ReportDiagnostic(SmartTestsDiagnostics.CreateNotADateCreation(expression)); } else { ReportDiagnostic(SmartTestsDiagnostics.CreateNotAConstantPropertyField(expression)); } value = default; return(false); } value = new SymbolicConstant <T>((T)Convert.ChangeType(constant.Value, typeof(T))); return(true); }
protected bool TryGetConstant(ExpressionSyntax expression, out bool value) { var constant = Model.GetConstantValue(expression); if (!constant.HasValue) { ReportDiagnostic(SmartTestsDiagnostics.CreateNotAConstant(expression)); value = default(bool); return(false); } value = (bool)Convert.ChangeType(constant.Value, typeof(bool)); return(true); }
private bool ValidateNoParameterNames(Action <Diagnostic> reportError) { var result = true; foreach (var casesAnd in CasesAndOr.CasesAnd) { foreach (var pair in casesAnd.Cases) { if (pair.Key != Case.NoParameter) { result = false; reportError(SmartTestsDiagnostics.CreateWrongParameterName(TestedMember, pair.Key, pair.Value.ParameterNameExpression)); } } } return(result); }
private void Range(InvocationExpressionSyntax node, Action <SymbolicConstant <T>, SymbolicConstant <T> > addRange) { if (TryGetSymbolicConstant(node.GetArgument(0).Expression, out SymbolicConstant <T> min) & TryGetSymbolicConstant(node.GetArgument(1).Expression, out SymbolicConstant <T> max)) { if (min.ConstantGreaterThan(max)) { ReportDiagnostic(SmartTestsDiagnostics.CreateMinShouldBeLessThanMax(node, min.ToString(), max.ToString())); } else if (_Root != null) { addRange(min, max); } } else { _Root = null; } }
private bool TryCreateDateTime <T>(ObjectCreationExpressionSyntax expression, out T result) { try { var args = new List <object>(); foreach (var arg in expression.ArgumentList.Arguments) { args.Add(Model.GetConstantValue(arg.Expression).Value); } result = (T)Activator.CreateInstance(typeof(T), Activator.CreateInstance(typeof(DateTime), args.ToArray())); return(true); } catch { ReportDiagnostic(SmartTestsDiagnostics.CreateNotADateCreation(expression)); result = default(T); return(false); } }
private void Range(InvocationExpressionSyntax node, Action <T, bool, T, bool> addRange) { if (TryGetConstant(node.GetArgument(0).Expression, out T min) & TryGetConstant(node.GetArgument(1).Expression, out bool minIncluded) & TryGetConstant(node.GetArgument(2).Expression, out T max) & TryGetConstant(node.GetArgument(3).Expression, out bool maxIncluded)) { if (min.CompareTo(max) > 0) { ReportDiagnostic(SmartTestsDiagnostics.CreateMinShouldBeLessThanMax(node, min.ToString(), max.ToString())); } else if (_Root != null) { addRange(min, minIncluded, max, maxIncluded); } } else { _Root = null; } }
protected bool TryGetConstant <T>(ExpressionSyntax expression, out T value) { var constant = Model.GetConstantValue(expression); if (!constant.HasValue) { var symbol = Model.GetSymbolInfo(expression).Symbol; if (_DateTimeConstants.TryGetValue(symbol, out var dt) || _DateTimeConstants.TryGetValue(symbol.OriginalDefinition, out dt)) { value = (T)(object)dt; return(true); } if (_DateTimeConstructions.Contains(symbol)) { return(TryCreateDateTime((ObjectCreationExpressionSyntax)expression, out value)); } if (Equals((symbol as ILocalSymbol)?.Type ?? (symbol as IPropertySymbol)?.Type ?? (symbol as IMethodSymbol)?.ReturnType, _DateTimeType)) { ReportDiagnostic(SmartTestsDiagnostics.CreateNotADateCreation(expression)); } else { ReportDiagnostic(SmartTestsDiagnostics.CreateNotAConstantPropertyField(expression)); } value = default; return(false); } value = (T)Convert.ChangeType(constant.Value, typeof(T)); return(true); }
private bool ValidateParameters(Action <Diagnostic> reportError, List <Tuple <string, ITypeSymbol> > testedParameters) { if (testedParameters.Count <= 1) { // 0 or 1 parameter: the parameter name is not mandatory if (CasesAndOr.CasesAnd.Count == 1 && CasesAndOr.CasesAnd[0].Cases.Count == 1 && CasesAndOr.CasesAnd.First().Cases.Values.First().TestedParameter.Name == Case.NoParameter) { return(true); } } var result = true; foreach (var casesAnd in CasesAndOr.CasesAnd) { var untestedParameters = testedParameters.ToDictionary(p => p.Item1); var hasAnonymousCase = false; foreach (var aCase in casesAnd.Cases.Values) { if (aCase.TestedParameter.Name == Case.NoParameter) { hasAnonymousCase = true; continue; } if (!untestedParameters.TryGetValue(aCase.TestedParameter.Name, out var testedParameter)) { // This parameter name does not exist result = false; reportError(SmartTestsDiagnostics.CreateWrongParameterName(TestedMember, aCase.ParameterName, aCase.TestedParameter.Expression)); continue; } // This parameter is tested if (aCase.TestedParameter.IsLambda) { if (testedParameter.Item2 != null && !testedParameter.Item2.Equals(aCase.TestedParameter.Type)) { // This parameter type is not the right one result = false; reportError(SmartTestsDiagnostics.CreateWrongParameterType(TestedMember, aCase.ParameterName, aCase.TestedParameter.Type.ToString(), aCase.TestedParameter.Expression)); } if (aCase.TestedParameter.PathHasErrors) { result = false; reportError(SmartTestsDiagnostics.CreateWrongParameterPath(TestedMember, aCase.ParameterName, aCase.TestedParameter.Path, aCase.TestedParameter.PathExpression)); } } untestedParameters.Remove(aCase.TestedParameter.Name); } if (casesAnd.HasError) { continue; } // Remaining parameters have no Case! if (testedParameters.Count == 1 && hasAnonymousCase) { // When 1 parameter, parameter name is not mandatory continue; } foreach (var parameter in untestedParameters) { result = false; reportError(SmartTestsDiagnostics.CreateMissingParameterCase(TestedMember, parameter.Key, casesAnd.Cases.First().Value.CaseExpressions.First())); } } return(result); }