// Path: joiner-core/src/test/java/cz/encircled/joiner/config/TestConfig.java
// @Configuration
// @Import(EntityManagerConfig.class)
// @ComponentScan(basePackages = {"cz.encircled.joiner"})
// public class TestConfig {
// 
//     @PersistenceContext
//     private EntityManager entityManager;
// 
//     @Bean
//     public JoinGraphRegistry joinGraphRegistry() {
//         return new DefaultJoinGraphRegistry();
//     }
// 
//     @Bean
//     public Joiner joiner(JoinGraphRegistry joinGraphRegistry) {
//         Joiner joiner = new Joiner(entityManager);
//         joiner.setJoinGraphRegistry(joinGraphRegistry);
//         return joiner;
//     }
// 
// }
// 
// Path: joiner-core/src/test/java/cz/encircled/joiner/config/hint/HintQueryFeature.java
// public class HintQueryFeature implements QueryFeature {
// 
//     @Override
//     public <T, R> JoinerQuery<T, R> before(final JoinerQuery<T, R> request) {
//         return request;
//     }
// 
//     @Override
//     public <T, R> ExtendedJPAQuery<R> after(JoinerQuery<T, R> request, ExtendedJPAQuery<R> query) {
//         Field f = ReflectionUtils.findField(AbstractJPAQuery.class, "hints");
//         ReflectionUtils.makeAccessible(f);
//         Multimap<String, Object> field = (Multimap<String, Object>) ReflectionUtils.getField(f, query);
// 
//         Object value = ((Collection) field.get("testHint")).iterator().next();
//         if (!"testHintValue".equals(value)) {
//             throw new TestException();
//         }
// 
//         return query;
//     }
// }
// 
// Path: joiner-core/src/main/java/cz/encircled/joiner/query/Q.java
// public class Q {
// 
//     /**
//      * Build tuple query projections (i.e. select clause)
//      *
//      * @param returnProjections path to query projection
//      * @return joiner query with custom tuple query projection
//      */
//     public static FromBuilder<Tuple> select(Expression<?>... returnProjections) {
//         Assert.notNull(returnProjections);
//         return new TupleQueryFromBuilder(returnProjections);
//     }
// 
//     /**
//      * Build  query projection (i.e. select clause)
//      *
//      * @param returnProjection path to query projection
//      * @param <R>              type of source entity
//      * @return joiner query with custom query projection
//      */
//     public static <R> FromBuilder<R> select(Expression<R> returnProjection) {
//         return new ExpressionQueryFromBuilder<>(returnProjection);
//     }
// 
//     /**
//      * Build "from" clause of query
//      *
//      * @param from alias of source entity
//      * @param <T> type of source entity
//      * @return joiner query
//      */
//     public static <T> JoinerQuery<T, T> from(EntityPath<T> from) {
//         return new JoinerQueryBase<>(from, from);
//     }
// 
//     /**
//      * Build count query
//      *
//      * @param from alias of source entity
//      * @param <T> type of source entity
//      * @return count joiner query
//      */
//     public static <T> JoinerQuery<T, Long> count(EntityPath<T> from) {
//         JoinerQueryBase<T, Long> request = new JoinerQueryBase<>(from, true);
//         request.distinct(false);
//         return request;
//     }
// 
// }


import cz.encircled.joiner.config.TestConfig;
import cz.encircled.joiner.config.hint.HintQueryFeature;
import cz.encircled.joiner.model.QUser;
import cz.encircled.joiner.query.Q;
import org.junit.jupiter.api.Test;
import org.springframework.test.context.ContextConfiguration;
import static org.junit.jupiter.api.Assertions.assertThrows;
package cz.encircled.joiner.core;



/**
 * @author Kisel on 04.02.2016.
 */
@ContextConfiguration(classes = {TestConfig.class})
public class HintsTest extends AbstractTest {

    @Test
    public void testHint() {
        joiner.find(Q.from(QUser.user1).addHint("testHint", "testHintValue").addFeatures(new HintQueryFeature()));
    }

    @Test
    public void testOfTest() {
        assertThrows(TestException.class, () -> {
            joiner.find(Q.from(QUser.user1).addHint("testHint", "exception").addFeatures(new HintQueryFeature()));
        });
    }

    @Test
    public void testNullKeyHint() {
        assertThrows(IllegalArgumentException.class, () -> {
// Path: joiner-core/src/test/java/cz/encircled/joiner/config/TestConfig.java
// @Configuration
// @Import(EntityManagerConfig.class)
// @ComponentScan(basePackages = {"cz.encircled.joiner"})
// public class TestConfig {
// 
//     @PersistenceContext
//     private EntityManager entityManager;
// 
//     @Bean
//     public JoinGraphRegistry joinGraphRegistry() {
//         return new DefaultJoinGraphRegistry();
//     }
// 
//     @Bean
//     public Joiner joiner(JoinGraphRegistry joinGraphRegistry) {
//         Joiner joiner = new Joiner(entityManager);
//         joiner.setJoinGraphRegistry(joinGraphRegistry);
//         return joiner;
//     }
// 
// }
// 
// Path: joiner-core/src/test/java/cz/encircled/joiner/config/hint/HintQueryFeature.java
// public class HintQueryFeature implements QueryFeature {
// 
//     @Override
//     public <T, R> JoinerQuery<T, R> before(final JoinerQuery<T, R> request) {
//         return request;
//     }
// 
//     @Override
//     public <T, R> ExtendedJPAQuery<R> after(JoinerQuery<T, R> request, ExtendedJPAQuery<R> query) {
//         Field f = ReflectionUtils.findField(AbstractJPAQuery.class, "hints");
//         ReflectionUtils.makeAccessible(f);
//         Multimap<String, Object> field = (Multimap<String, Object>) ReflectionUtils.getField(f, query);
// 
//         Object value = ((Collection) field.get("testHint")).iterator().next();
//         if (!"testHintValue".equals(value)) {
//             throw new TestException();
//         }
// 
//         return query;
//     }
// }
// 
// Path: joiner-core/src/main/java/cz/encircled/joiner/query/Q.java
// public class Q {
// 
//     /**
//      * Build tuple query projections (i.e. select clause)
//      *
//      * @param returnProjections path to query projection
//      * @return joiner query with custom tuple query projection
//      */
//     public static FromBuilder<Tuple> select(Expression<?>... returnProjections) {
//         Assert.notNull(returnProjections);
//         return new TupleQueryFromBuilder(returnProjections);
//     }
// 
//     /**
//      * Build  query projection (i.e. select clause)
//      *
//      * @param returnProjection path to query projection
//      * @param <R>              type of source entity
//      * @return joiner query with custom query projection
//      */
//     public static <R> FromBuilder<R> select(Expression<R> returnProjection) {
//         return new ExpressionQueryFromBuilder<>(returnProjection);
//     }
// 
//     /**
//      * Build "from" clause of query
//      *
//      * @param from alias of source entity
//      * @param <T> type of source entity
//      * @return joiner query
//      */
//     public static <T> JoinerQuery<T, T> from(EntityPath<T> from) {
//         return new JoinerQueryBase<>(from, from);
//     }
// 
//     /**
//      * Build count query
//      *
//      * @param from alias of source entity
//      * @param <T> type of source entity
//      * @return count joiner query
//      */
//     public static <T> JoinerQuery<T, Long> count(EntityPath<T> from) {
//         JoinerQueryBase<T, Long> request = new JoinerQueryBase<>(from, true);
//         request.distinct(false);
//         return request;
//     }
// 
// }


// Path: joiner-core/src/test/java/cz/encircled/joiner/core/HintsTest.java
import cz.encircled.joiner.config.TestConfig;
import cz.encircled.joiner.config.hint.HintQueryFeature;
import cz.encircled.joiner.model.QUser;
import cz.encircled.joiner.query.Q;
import org.junit.jupiter.api.Test;
import org.springframework.test.context.ContextConfiguration;
import static org.junit.jupiter.api.Assertions.assertThrows;

package cz.encircled.joiner.core;



/**
 * @author Kisel on 04.02.2016.
 */
@ContextConfiguration(classes = {TestConfig.class})
public class HintsTest extends AbstractTest {

    @Test
    public void testHint() {
        joiner.find(Q.from(QUser.user1).addHint("testHint", "testHintValue").addFeatures(new HintQueryFeature()));
    }

    @Test
    public void testOfTest() {
        assertThrows(TestException.class, () -> {
            joiner.find(Q.from(QUser.user1).addHint("testHint", "exception").addFeatures(new HintQueryFeature()));
        });
    }

    @Test
    public void testNullKeyHint() {
        assertThrows(IllegalArgumentException.class, () -> {
            joiner.find(Q.from(QUser.user1).addHint(null, "testHintValue").addFeatures(new HintQueryFeature()));