Package nexj.core.runtime

Source Code of nexj.core.runtime.InstanceTest

// Copyright 2010-2011 NexJ Systems Inc. This software is licensed under the terms of the Eclipse Public License 1.0
package nexj.core.runtime;

import java.util.Arrays;

import nexj.core.meta.Metaclass;
import nexj.core.meta.Metadata;
import nexj.core.meta.Repository;
import nexj.core.persistence.Query;
import nexj.core.persistence.sql.ReadCountHook;
import nexj.core.persistence.sql.SQLAdapter;
import nexj.core.persistence.sql.SQLDataTest;
import nexj.core.scripting.Symbol;
import nexj.core.util.Invalid;
import nexj.core.util.Undefined;
import nexj.core.util.auth.SimplePrincipal;


public class InstanceTest extends SQLDataTest
{
   public InstanceTest(String sName)
   {
      super(sName);
   }

   public void testCalculatedValue()
   {
      Instance instance = m_context.getUser();

      instance.setValue("names", instance.getValue("names"));
      instance.setValue("names", Arrays.asList(new Object[]{"abc", "def"}));
      assertEquals(Arrays.asList(new Object[]{"abc", "def"}), instance.getValue("names"));
      instance.setValue("names", Arrays.asList(new Object[]{"abc", new Integer(1), "def"}));
      assertEquals(Arrays.asList(new Object[]{"abc", "1", "def"}), instance.getValue("names"));
   }

   /**
    * Tests that updating an instance in a second work unit fails
    * if it has uncommitted changes in the first work unit.
    *
    * @throws Exception
    */
   public void testUpdateInWrongWorkUnit() throws Exception
   {
      //Initialize InvocationContext
      Metadata metadata = Repository.getMetadata();
      InvocationContext context = new InvocationContext(metadata);

      context.setUserClass(metadata.getMetaclass("User"));
      context.initialize(new SimplePrincipal("jtest"));

      ThreadContextHolder.setContext(context);


      //Start work unit 1
      assertNull(context.beginTransaction(true));


      //Create instance in work unit 1
      Metaclass ContactClass = metadata.getMetaclass("Contact");
      Instance contact = (Instance)ContactClass.invoke("new");

      contact.setValue("firstName", "James");

     
      //Switch to work unit 2
      UnitOfWork creationUOW = context.beginTransaction(false);


      //Update in work unit 2 should fail.
      try
      {
         contact.setValue("lastName", "Kirk");
         fail();
      }
      catch (TransactionException ex)
      {
         assertEquals("err.runtime.wrongTransaction", ex.getErrorCode());
         assertEquals("Contact", ex.getErrorArgs()[0]);
      }

      //Clean up
      context.rollbackAndResume(creationUOW);
      context.complete(false);
   }


   /**
    * Tests that deleting an instance in a second work unit fails
    * if it has uncommitted changes in the first work unit.
    *
    * @throws Exception
    */
   public void testDeleteInWrongWorkUnit() throws Exception
   {
      //Initialize InvocationContext
      Metadata metadata = Repository.getMetadata();
      InvocationContext context = new InvocationContext(metadata);

      context.setUserClass(metadata.getMetaclass("User"));
      context.initialize(new SimplePrincipal("jtest"));

      ThreadContextHolder.setContext(context);


      //Start work unit 1
      assertNull(context.beginTransaction(true));

      //Create instance in work unit 1
      Metaclass ContactClass = metadata.getMetaclass("Contact");
      Instance contact = (Instance)ContactClass.invoke("new");
     
      contact.setValue("firstName", "Jean-luc");

      //Switch to work unit 2
      UnitOfWork creationUOW = context.beginTransaction(false);
     
     
      //Delete in work unit 2 should fail.
      try
      {
         contact.invoke("delete");
         fail();
      }
      catch (TransactionException ex)
      {
         assertEquals("err.runtime.wrongTransaction", ex.getErrorCode());
         assertEquals("Contact", ex.getErrorArgs()[0]);
      }
     
      //Clean up
      context.rollbackAndResume(creationUOW);
      context.complete(false);
   }

   /**
    * Tests an *uncached* calculated attribute that has an initializer.
    */
   public void testUncachedCalculatedValueWithInitializer()
   {
      final Symbol INITIALIZED = Symbol.define("INITIALIZED");
      final Symbol CALCULATED = Symbol.define("CALCULATED");
      final Metaclass userClass = Repository.getMetadata().getMetaclass("User");
      final int attribute = userClass.findAttribute("regionUncached").getOrdinal();
      UnitOfWork oldUOW;
      Instance instance;

      // Get value while new --> run initializer
      // Get value once committed --> run calculated value script
      oldUOW = m_context.beginTransaction();
      instance = (Instance)userClass.invoke("new");
      assertEquals(Undefined.VALUE, instance.getValueDirect(attribute));
      assertEquals(INITIALIZED, instance.getValue(attribute));
      instance.setValue("name", "jack.test");
      instance.setValue("contact", m_context.getUser().getValue("contact"));
      m_context.commitAndResume(oldUOW);
      assertEquals(INITIALIZED, instance.getValueDirect(attribute));
      assertEquals(CALCULATED, instance.getValue(attribute));

      // Ensure that initializer is run by validation
      oldUOW = m_context.beginTransaction();
      instance = (Instance)userClass.invoke("new");
      instance.setValue("name", "jill.test");
      instance.setValue("contact", m_context.getUser().getValue("contact"));
      m_context.commitAndResume(oldUOW);
      assertEquals(INITIALIZED, instance.getValueDirect(attribute));
      assertEquals(CALCULATED, instance.getValue(attribute));
   }

   /**
    * Tests a *cached* calculated attribute that has an initializer.
    */
   public void testCachedCalculatedValueWithInitializer()
   {
      final Symbol INITIALIZED = Symbol.define("INITIALIZED");
      final Symbol CALCULATED = Symbol.define("CALCULATED");
      final Metaclass userClass = Repository.getMetadata().getMetaclass("User");
      final int attribute = userClass.findAttribute("regionCached").getOrdinal();
      UnitOfWork oldUOW;
      Instance instance;

      // Get value while new --> run initializer
      // Get value once committed --> return cached value
      oldUOW = m_context.beginTransaction();
      instance = (Instance)userClass.invoke("new");
      assertEquals(Undefined.VALUE, instance.getValueDirect(attribute));
      assertEquals(INITIALIZED, instance.getValue(attribute));
      instance.setValue("name", "jack.test");
      instance.setValue("contact", m_context.getUser().getValue("contact"));
      m_context.commitAndResume(oldUOW);
      assertEquals(INITIALIZED, instance.getValueDirect(attribute));
      assertEquals(INITIALIZED, instance.getValue(attribute));

      // Invalidate to re-calculate value
      instance.setValueDirect(attribute, Invalid.VALUE);
      assertEquals(CALCULATED, instance.getValue(attribute));
   }

   /**
    * Tests that lazy loads don't cause heterogeneous joins.
    */
   public void testLazyRelationalJoiningRelational()
   {
      Metaclass clazz = getMetadata().getMetaclass("ExternalVisit");
      ReadCountHook readHook = (ReadCountHook)((SQLAdapter)getMetadata().getDataSource("DefaultRelationalDatabase").getComponent().getInstance(m_context)).getSQLHook();
      ReadCountHook extHook = (ReadCountHook)((SQLAdapter)getMetadata().getDataSource("ExternalRelationalDatabase").getComponent().getInstance(m_context)).getSQLHook();
      InstanceArrayList list;
      Instance inst;
      int nStartReadCount = readHook.getReadCount();
      int nExtReadCount = extHook.getReadCount();

      list = (InstanceArrayList)Query.createRead(clazz,
         parse("(version startDate endDate)"),
         null,
         null,
         -1, 0, false, Query.SEC_NODE, m_context).read();

      assertEquals(6, list.getCount());
      inst = list.getInstance(0);
      assertEquals(nStartReadCount, readHook.getReadCount());
      assertEquals(nExtReadCount + 1, extHook.getReadCount());
      nExtReadCount = extHook.getReadCount();

      // This causes a lazy load of ExternalVisit, and will instantiate a lazy Patient instance
      assertEquals("Broken foot", inst.getValue("reason"));
      assertEquals(nExtReadCount + 1, extHook.getReadCount());
      assertEquals(nStartReadCount, readHook.getReadCount());
      inst = (Instance)inst.getValue("patient");
      assertEquals(nStartReadCount, readHook.getReadCount());

      // This will cause the read of Patient
      assertEquals("Sarah", inst.getValue("firstName"));
      assertEquals("Johnson", inst.getValue("lastName"));
      assertEquals(nStartReadCount + 1, readHook.getReadCount());
      assertEquals(nExtReadCount + 1, extHook.getReadCount());
   }
}
TOP

Related Classes of nexj.core.runtime.InstanceTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.