### Question:
ProjectionDriver extends JavaDataModelDriver { @Override public List<Type> getInterfaces(EmitContext context, ModelDeclaration model) { return collect(context, model).stream() .map(context::resolve) .collect(Collectors.toList()); }  @Override List<Type> getInterfaces(EmitContext context, ModelDeclaration model);  }### Answer:
@Test public void projection() { ModelLoader loader = generate(); Class<?> a = loader.modelType("A"); Class<?> b = loader.modelType("B"); Class<?> c = loader.modelType("C"); Class<?> d = loader.modelType("D"); assertThat(a.getInterfaces(), not(includes(b))); assertThat(a.getInterfaces(), not(includes(c))); assertThat(a.getInterfaces(), not(includes(d))); assertThat(b.getInterfaces(), includes(a)); assertThat(b.getInterfaces(), not(includes(c))); assertThat(b.getInterfaces(), not(includes(d))); assertThat(c.getInterfaces(), not(includes(a))); assertThat(c.getInterfaces(), not(includes(b))); assertThat(c.getInterfaces(), not(includes(d))); assertThat(d.getInterfaces(), not(includes(a))); assertThat(d.getInterfaces(), includes(b)); assertThat(d.getInterfaces(), includes(c)); }
@Test public void projection_thin() { ModelLoader loader = generate(new String[] { "projective a = { key : INT; };", "projective b = a;", "c = b;", }); Class<?> a = loader.modelType("A"); Class<?> b = loader.modelType("B"); Class<?> c = loader.modelType("C"); assertThat(b.getInterfaces(), includes(a)); assertThat(c.getInterfaces(), not(includes(a))); assertThat(c.getInterfaces(), includes(b)); assertThat(a.isAssignableFrom(c), is(true)); assertThat(b.isAssignableFrom(c), is(true)); }
@Test public void projection_indirect() { ModelLoader loader = generate(new String[] { "projective a = { key : INT; };", "b = a;", "c = b;", }); Class<?> a = loader.modelType("A"); Class<?> b = loader.modelType("B"); Class<?> c = loader.modelType("C"); assertThat(b.getInterfaces(), includes(a)); assertThat(c.getInterfaces(), includes(a)); assertThat(a.isAssignableFrom(c), is(true)); assertThat(b.isAssignableFrom(c), is(false)); }
@Test public void projection_indirect_projective() { ModelLoader loader = generate(new String[] { "projective a = { key : INT; };", "b = a;", "projective c = b;", }); Class<?> a = loader.modelType("A"); Class<?> b = loader.modelType("B"); Class<?> c = loader.modelType("C"); assertThat(b.getInterfaces(), includes(a)); assertThat(c.getInterfaces(), includes(a)); assertThat(a.isAssignableFrom(c), is(true)); assertThat(b.isAssignableFrom(c), is(false)); }
@Test public void prune_duplicated() { ModelLoader loader = generate(new String[] { "projective a = { key : INT; };", "b = a;", "c = b;", "d = b + c;", }); Class<?> a = loader.modelType("A"); Class<?> d = loader.modelType("D"); assertThat(d.getInterfaces(), includes(a)); }
@Test public void prune_descendants() { ModelLoader loader = generate(new String[] { "projective a = { key : INT; };", "projective b = a;", "c = a;", "d = b;", "e = c + d;", }); Class<?> a = loader.modelType("A"); Class<?> b = loader.modelType("B"); Class<?> e = loader.modelType("E"); assertThat(e.getInterfaces(), includes(b)); assertThat(e.getInterfaces(), not(includes(a))); }