package org.minimalj.model.test;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.junit.Assert;
import org.junit.Test;
import org.minimalj.model.annotation.Size;
import org.minimalj.model.annotation.View;
import org.minimalj.model.annotation.ViewOf;
import org.threeten.bp.LocalDate;
import org.threeten.bp.LocalTime;

/**
 * This tests don't test models. It tests the tests for the model.
 * 
 */
public class ModelTestTest {

	@Test public void 
	should_test_not_accept_string_field_without_size() {
		ModelTest modelTest = new ModelTest(TestClass1.class);
		Assert.assertFalse(modelTest.isValid());
	}

	public static class TestClass1 {
		public int id;

		public String a;
	}

	//
	
	@Test public void 
	should_test_accept_fields() {
		ModelTest modelTest = new ModelTest(TestClass2.class);
		assertValid(modelTest);
	}
	
	public static class TestClass2 {
		public int id;
		
		@Size(255)
		public String a;
		public Integer b;
		public Long c;
		public LocalDate d;
		public LocalTime e;
		public BigDecimal f;
	}

	//

	@Test public void 
	should_test_not_accept_primitiv_int() {
		ModelTest modelTest = new ModelTest(TestClass3.class);
		Assert.assertFalse(modelTest.isValid());
	}

	public static class TestClass3 {
		public int id;
		public int a;
	}

	//

	@Test public void 
	should_test_not_accept_primitiv_long() {
		ModelTest modelTest = new ModelTest(TestClass4.class);
		Assert.assertFalse(modelTest.isValid());
	}

	public static class TestClass4 {
		public int id;
		public long a;
	}
	
	//

	@Test public void 
	should_test_not_accept_missing_id() {
		ModelTest modelTest = new ModelTest(TestClass5.class);
		Assert.assertFalse(modelTest.isValid());
	}

	public static class TestClass5 {
		public Integer a;
	}
	
	//
	
	@Test public void 
	should_test_not_accept_reference_to_other_entity() {
		ModelTest modelTest = new ModelTest(TestClass6.class, TestClass2.class);
		Assert.assertFalse(modelTest.isValid());
	}

	public static class TestClass6 {
		public int id;
		public TestClass2 ref;
	}

	//
	
	@Test public void 
	should_test_accept_reference_to_other_entity_with_View_Annotation() {
		ModelTest modelTest = new ModelTest(TestClass7.class, TestClass2.class);
		assertValid(modelTest);
	}

	public static class TestClass7 {
		public int id;
		@View
		public TestClass2 ref;
	}

	//

	@Test public void 
	should_test_accept_reference_to_View() {
		ModelTest modelTest = new ModelTest(TestClass8.class, TestClass9.class);
		assertValid(modelTest);
	}

	public static class TestClass8 implements ViewOf<TestClass2> {
		public int id;

		@Override
		public String display() {
			return null;
		}
	}

	public static class TestClass9 {
		public int id;
		@View
		public TestClass2 ref;
	}

	//
	
	@Test public void 
	should_test_not_accept_list_in_list() {
		ModelTest modelTest = new ModelTest(TestClass10.class);
		Assert.assertFalse(modelTest.isValid());
	}

	public static class TestClass10 {
		public int id;
		public final List<TestClass11> list = new ArrayList<>();
	}

	public static class TestClass11 {
		public final List<TestClass12> list = new ArrayList<>();
	}

	public static class TestClass12 {
		public Integer a;
	}

	//

	@Test public void 
	should_test_not_accept_list_without_final() {
		ModelTest modelTest = new ModelTest(TestClass13.class);
		Assert.assertFalse(modelTest.isValid());
	}

	public static class TestClass13 {
		public int id;
		public List<TestClass12> list = new ArrayList<>();
	}

	//

	@Test public void 
	should_test_not_accept_inheritence() {
		ModelTest modelTest = new ModelTest(TestClass14.class);
		Assert.assertFalse(modelTest.isValid());
	}

	public static class TestClass14 extends TestClass2 {
		public Integer i;
	}

	//

	private void assertValid(ModelTest modelTest) {
		if (!modelTest.isValid()) {
			for (String s : modelTest.getProblems()) {
				System.out.println(s);
			}
		}
		Assert.assertTrue(modelTest.isValid());
	}
	
}

@@ -107,24 +107,74 @@
 .util.List;%0D
+%0Aimport java.util.Set;%0D%0Aimport java.util.TreeSet;%0D
 %0A%0D%0Aimport or
@@ -3968,16 +3968,653 @@
 %0A%09//%0D%0A%0D%0A
+%09@Test public void %0D%0A%09should_test_not_accept_list_without_type() %7B%0D%0A%09%09ModelTest modelTest = new ModelTest(TestClass15.class);%0D%0A%09%09Assert.assertFalse(modelTest.isValid());%0D%0A%09%7D%0D%0A%0D%0A%09public static class TestClass15 %7B%0D%0A%09%09public int id;%0D%0A%09%09@SuppressWarnings(%22rawtypes%22)%0D%0A%09%09public final List list = new ArrayList();%0D%0A%09%7D%0D%0A%0D%0A%09//%0D%0A%0D%0A%09@Test public void %0D%0A%09should_test_not_accept_set_without_type() %7B%0D%0A%09%09ModelTest modelTest = new ModelTest(TestClass16.class);%0D%0A%09%09Assert.assertFalse(modelTest.isValid());%0D%0A%09%7D%0D%0A%0D%0A%09public static class TestClass16 %7B%0D%0A%09%09public int id;%0D%0A%09%09@SuppressWarnings(%22rawtypes%22)%0D%0A%09%09public final Set s = new TreeSet();%0D%0A%09%7D%0D%0A%0D%0A%09//%0D%0A%0D%0A
 %09private

check for missing type in List and Set