/*******************************************************************************
 * Copyright (c) 2011, 2013 Anton Gorenkov and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Anton Gorenkov   - initial implementation
 *     Marc-Andre Laperle
 *     Nathan Ridge
 *     Danny Ferreira
 *******************************************************************************/
package org.eclipse.cdt.codan.core.internal.checkers;

import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
import org.eclipse.cdt.codan.internal.checkers.ClassMembersInitializationChecker;

/**
 * Test for {@see ClassMembersInitializationChecker} class
 */
public class ClassMembersInitializationCheckerTest extends CheckerTestCase {
	@Override
	public boolean isCpp() {
		return true;
	}

	@Override
	public void setUp() throws Exception {
		super.setUp();
		enableProblems(ClassMembersInitializationChecker.ER_ID);
	}

	private void disableSkipConstructorsWithFCalls() {
		setPreferenceValue(ClassMembersInitializationChecker.ER_ID, ClassMembersInitializationChecker.PARAM_SKIP, false);
	}

	public void checkMultiErrorsOnLine(int line, int count) {
		for (int i = 0; i < count; ++i) {
			checkErrorLine(line);
		}
		assertEquals(count, markers.length);
	}

	// class C {
	//   int m;
	//   C() : m(0) {}  // No warnings.
	// };
	public void testInitializationListShouldBeChecked() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	// class C {
	//   int m;
	//   C() { m = 0; }  // No warnings.
	// };
	public void testAssignmentsInConstructorShouldBeChecked() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	// class C {
	//   int m;
	//   unsigned int ui;
	//   float f;
	//   double d;
	//   bool b;
	//   char c;
	//   long l;
	//   C() {}  // 7 warnings for: m, ui, f, d, b, c, l.
	// };
	public void testBasicTypesShouldBeInitialized() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkMultiErrorsOnLine(9, 7);
	}

	// class Value {};
	// class C {
	//   int* i;
	//   Value* v;
	//   C() {}  // 2 warnings for: i, v.
	// }
	public void testPointersShouldBeInitialized() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkMultiErrorsOnLine(5, 2);
	}

	// class Value {};
	// class C {
	//   int& i;
	//   Value& v;
	//   C() {}  // 2 warnings for: i, v.
	// }
	public void testReferencesShouldBeInitialized() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkMultiErrorsOnLine(5, 2);
	}

	// enum Enum { v1, v2 };
	// class C {
	//   Enum e;
	//   C() {}  // 1 warning for: e.
	// }
	public void testEnumsShouldBeInitialized() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkMultiErrorsOnLine(4, 1);
	}

	// enum Enum { v1, v2 };
	// class Value {};
	// typedef int IntTypedef;
	// typedef int* IntPtrTypedef;
	// typedef int& IntRefTypedef;
	// typedef Enum EnumTypedef;
	// typedef Value ValueTypedef;
	// class C {
	//   IntTypedef i;
	//   IntPtrTypedef ip;
	//   IntRefTypedef ir;
	//   EnumTypedef e;
	//   ValueTypedef v;
	//   C() {}  // 5 warnings for: i, ip, ir, e.
	// }
	public void testTypedefsShouldBeInitialized() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkMultiErrorsOnLine(14, 4);
	}

	// class C {
	//   C() : i1(0) {}     // 1 warning for: i2.
	//   C(int) : i2(0) {}  // 1 warning for: i1.
	//   int i1, i2;
	// };
	public void testAFewConstructorsHandling() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(2, 3);
	}

	// template <typename T1, typename T2>
	// class C {
	//   C() : i1(0), t1(T1()) {}  // 1 warning for: i2.
	//   int i1, i2;
	//   T1 t1;
	//   T2 t2;
	// };
	public void testTemplateClassHandling() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(3);
	}

	// class C {
	//   template <typename T>
	//   C() : i1(0) {}  // 1 warning for: i2.
	//   int i1, i2;
	// };
	public void testTemplateConstructorHandling() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(3);
	}

	// class C {
	//   C();  // No warnings.
	//   int i;
	// };
	public void testTemplateConstructorDeclarationOnlyHandling() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	// class C {
	//   C();
	//   int i1, i2;
	// };
	// C::C() : i1(0) {}  // 1 warning for: i2.
	public void testExternalConstructorHandling() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(5);
	}

	// template <typename T1, typename T2>
	// class C {
	//   C();
	//   int i1, i2;
	//   T1 t1;
	//   T2 t2;
	// };
	// template <typename T1, typename T2>
	// C<T1,T2>::C() : i1(0), t1(T1()) {}  // 1 warning for: i2.
	public void testExternalConstructorOfTemplateClassHandling() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(9);
	}

	// class C {
	//   template <typename T>
	//   C();
	//   int i1, i2;
	// };
	// template <typename T>
	// C::C() : i1(0) {}  // 1 warning for: i2.
	public void testExternalTemplateConstructorHandling() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(7);
	}

	// template <typename T1, typename T2>
	// class C {
	//   template <typename T>
	//   C();
	//   int i1, i2;
	//   T1 t1;
	//   T2 t2;
	// };
	// template <typename T1, typename T2>
	// template <typename T>
	// C<T1,T2>::C() : i1(0), t1(T1()) {}  // 1 warning for: i2.
	public void testExternalTemplateConstructorOfTemplateClassHandling() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(11);
	}

	// class C {
	//   class NestedC {
	//     NestedC() : i(0) {} // No warnings.
	//     int i;
	//   };
	//   C() {}  // 1 warning for: i.
	//   int i;
	// };
	public void testNestedClassesHandling() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(6);
	}

	// class C {
	//   C()  // 1 warning for: i.
	//   {
	//     class NestedC {
	//       NestedC() { i = 0; } // No warnings.
	//       int i;
	//     };
	//   }
	//   int i;
	// };
	public void testNestedClassInConstructorHandling() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(2);
	}

	// class C {
	//   C();
	//   int i;
	// };
	//
	// C::C()  // 1 warning for: i.
	// {
	//   class NestedC {  // No warnings.
	//     NestedC() { i = 0; }
	//     int i;
	//   };
	// }
	public void testNestedClassInExternalConstructorHandling() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(6);
	}

	// class C {
	//   C()  // 1 warning for: i.
	//   {
	// 	   class NestedC {
	// 	     NestedC() { i = 0; } // No warnings.
	// 	     void C() { i = 0; }      // No warnings.
	// 	     int i;
	// 	   };
	//   }
	//   int i;
	// };
	public void testNestedClassWithMethodNamedAsAnotherClassHandling() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(2);
	}

	// class C {
	//   C() {}                         // 1 warning for: i.
	//   int someFunction() { i = 0; }  // No warnings.
	//   int i;
	// };
	public void testAssignmentIsNotInConstructor() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(2);
	}

	// class CBase {
	//   CBase() : i1(0) {}     // No warnings.
	//   int i1;
	// };
	// class CDerived : public CBase {
	//   CDerived() : i2(0) {}  // No warnings.
	//   int i2;
	// };
	public void testBaseClassMemberShouldNotBeTakenIntoAccount() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	// class C {
	//   C() {}  // No warnings.
	//   static int i1, i2;
	// };
	// int C::i1 = 0;
	// // NOTE: Static members are always initialized with 0, so there should not be warning on C::i2
	// int C::i2;
	public void testNoErrorsOnStaticMembers() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	// class C {
	// public:
	//   C(const C& c) = delete;
	//   int i1, i2;
	// };
	public void testNoErrorsOnDeletedConstructor() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	// void	func(int & a) { a = 0; }
	// class C {
	//   C() { func(i); }  // No warnings.
	//   int i;
	// };
	public void testNoErrorsOnFunctionCallInitialization() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	// void	func(const int & a) {}
	// class C {
	//   C() { func(i); }  // 1 warning for: i.
	//   int i;
	// };
	public void testNoErrorsOnReadingFunctionCall() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(3);
	}

	// class C {
	//   C() { (i1) = 0; *&i2 = 0; }  // No warnings.
	//   int i1, i2;
	// };
	public void testNoErrorsOnComplexAssignment() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	// class C {
	//   C() : i1(0) {  // No warnings.
	//     i2 = i1;
	//     int someVar = 0;
	//     i3 = someVar;
	//   }
	//   int i1, i2, i3;
	// };
	public void testNoErrorsOnChainInitialization() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	// class A { protected: A(){} public: int a; };  // 1 warning for: a.
	// class C: public A {
	//   C() {
	//       a = 1;
	//   }
	// };
	public void testErrorOnProtectedConstructor() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(1);
	}

	// struct S {
	//   int i;
	//   S() {}  // 1 warning for: i.
	// };
	public void testCheckStructs() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(3);
	}

	// union U {
	//   int a;
	//   char b;
	//   U() {  // No warnings.
	//      a=0;
	//   }
	// };
	public void testSkipUnions() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	// class C {
	//   int c;
	// };
	public void testNoErrorsIfThereIsNoConstructorsDefined() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	// class C {
	//   int i;
	//   C(bool b) {  // No warnings.
	//     if (b)
	//       i = 0;
	//     // else - 'i' will be not initialized
	//   }
	// };
	public void testNoErrorsIfMemberWasInitializedInOneOfTheIfBranch() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	// class A {
	//   int a;
	//   A(int a) { setA(a); }  // No warnings.
	//   A() { getA(); }        // 1 warning for: a.
	//   void setA(int a) {
	//     this->a = a;
	//   }
	//   int getA() const {
	//     return a;
	//   }
	// };
	public void testUsingMethodsInConstructorWithPreference() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(4);
	}

	// class A;
	// void initializeA1(A*);
	// void initializeA2(A**);
	// void initializeA3(A&);
	//
	// class A {
	//   int a;
	//   A() { initializeA1(this); }               // No warnings.
	//   A(int a) { initializeA2(&this); }         // No warnings.
	//   A(float a) { initializeA3(*this); }       // No warnings.
	//   A(double a) { initializeA3(*(this)); }    // No warnings.
	// };
	public void testUsingConstMethodsInConstructorWithPreference() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}


	// class A {
	//   int a;
	//   A(int a) { setA(a); }  // 1 warning for: a.
	//   A() { getA(); }        // 1 warning for: a.
	//   void setA(int a) {
	//     this->a = a;
	//   }
	//   int getA() const {
	//     return a;
	//   }
	// };
	public void testUsingMethodsInConstructorWithoutPreference() throws Exception {
		disableSkipConstructorsWithFCalls();
		loadCodeAndRun(getAboveComment());
		checkErrorLines(3,4);
	}

	// class A;
	// void initializeA1(A*);
	// void initializeA2(A**);
	// void initializeA3(A&);
	//
	// class A {
	//   int a;
	//   A() { initializeA1(this); }               // 1 warning for: a.
	//   A(int a) { initializeA2(&this); }         // 1 warning for: a.
	//   A(float a) { initializeA3(*this); }       // 1 warning for: a.
	//   A(double a) { initializeA3(*(this)); }    // 1 warning for: a.
	// };
	public void testUsingConstMethodsInConstructorWithoutPreference() throws Exception {
		disableSkipConstructorsWithFCalls();
		loadCodeAndRun(getAboveComment());
		checkErrorLines(8,9,10,11);
	}

	// @file:test.h
	// class C {
	//	 int field;
	// C();
	// void initObject();
	//};

	// @file:test.cpp
	// #include "test.h"
	// C::C() {
	//    initObject();
	// }
	public void testMethodDeclarationInOtherFile_368419() throws Exception {
		CharSequence[] code = getContents(2);
		loadcode(code[0].toString());
		loadcode(code[1].toString());
		runOnProject();
		checkNoErrors();
	}

	//class D {
	//  int field;
	//  D(const D& toBeCopied) {
	//    *this = toBeCopied;
	//  };
	//};
	public void testAssignThis_368420() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	//class D {
	//  int field;
	//  D(const D& toBeCopied) {
	//    *(&(*this)) = toBeCopied;
	//  };
	//};
	public void testAssignThisUnaryExpressions_368420() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	//class D {
	//  int field;
	//  D(const D& toBeCopied) {
	//    this = toBeCopied;
	//  };
	//};
	public void testAssignThisNonLValue_368420() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLines(3);
	}

	//class D {
	//  int field;
	//  D();
	//  D(const D& toBeCopied) {
	//    D temp;
	//    temp = *(&(*this)) = toBeCopied;
	//  };
	//};
	public void testAssignThisMultiBinaryExpressions_368420() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	//@file:test.h
	//template <typename>
	//struct B;

	//@file:test.cpp
	//#include "test.h"
	//
	//template <typename>
	//struct A {
	//};
	//
	//template <typename valueT>
	//struct B<A<valueT> > {
	//    const A<valueT>& obj;
	//    B(const A<valueT>& o) : obj(o) {}
	//};
	public void testTemplatePartialSpecialization_368611() throws Exception {
		CharSequence[] code = getContents(2);
		loadcode(code[0].toString());
		loadcode(code[1].toString());
		runOnProject();
		checkNoErrors();
	}

	//	struct S {
	//	    int i;
	//	    S() = default;
	//	};
	public void testDefaultConstructor_365498() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkErrorLine(3);
	}

	//	struct S {
	//	    int i;
	//
	//	    S(S&) = default;
	//	    S(const S&) = default;
	//	    S(volatile S&) = default;
	//	    S(const volatile S&) = default;
	//	    S(S&&) = default;
	//	    S(const S&&) = default;
	//	    S(volatile S&&) = default;
	//	    S(const volatile S&&) = default;
	//	};
	public void testDefaultCopyOrMoveConstructor_395018() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	//	template <typename T>
	//	struct S {
	//	    int i;
	//
	//	    S(const S&) = default;
	//	    S(S&&) = default;
	//	};
	public void testDefaultCopyOrMoveConstructorInTemplate_408303() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	//	struct A {
	//	    A(int n) : waldo(n) {}
	//	    A() : A(42) {}
	//	    int waldo;
	//	};
	public void testDelegatingConstructor_402607() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	//	struct A {
	//      typedef A B;
	//	    A(int n) : waldo(n) {}
	//	    A() : B(42) {}
	//	    int waldo;
	//	};
	public void testDelegatingConstructorTypedef_402607() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	//	template <typename T>
	//	class TemplateWithWarning {
	//	public:
	//	  TemplateWithWarning(int number) {
	//	    internalNumber = number;
	//	  }
	//
	//	  TemplateWithWarning(int number, bool someFlag)
	//	     : TemplateWithWarning(number) {}
	//
	//	protected:
	//	  int internalNumber;
	//	};
	public void testDelegatingConstructorWithTemplate_519311() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	//	struct A {
	//	    A() {};
	//	    int x = 0;
	//	};
	public void testNonstaticDataMemberInitializer_400673() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}

	//	class ClassWithWarning {
	//	public:
	//	  ClassWithWarning(char* n) {
	//	    this->initClass(n);
	//	  }
	//
	//	private:
	//	  char *name;
	//	  void initClass(char *name) {
	//	    this->name = name;
	//	  }
	//	};
	public void testMemberFunctionCalling_519473() throws Exception {
		loadCodeAndRun(getAboveComment());
		checkNoErrors();
	}
}
