--- /dev/null
+#!/bin/bash
+java com.ReasoningTechnology."Mosaic".Mosaic
this.parameter_types = method.getParameterTypes();
}
- private static Class<?>[] resolve_parameter_types(Object[] args){
- Class<?>[] parameter_types = new Class<?>[args.length];
- for( int i = 0; i < args.length; i++ ){
- if( args[i] instanceof isPrimitive ){
- parameter_types[i] = ((isPrimitive) args[i]).get_type();
- }else if( args[i] != null ){
- parameter_types[i] = args[i].getClass();
+ private static Class<?>[] resolve_parameter_types(Object[] arg_list){
+ Class<?>[] parameter_types = new Class<?>[arg_list.length];
+ for( int i = 0; i < arg_list.length; i++ ){
+ if( arg_list[i] instanceof Mosaic_IsPrimitive ){
+ parameter_types[i] = ((Mosaic_IsPrimitive) arg_list[i]).get_type();
+ }else if( arg_list[i] != null ){
+ parameter_types[i] = arg_list[i].getClass();
}else{
parameter_types[i] = null;
}
return sb.toString();
}
-
}
class FunctionSignature_To_Handle_Map {
add_class(class_metadata);
}
+ private void add_class(Class<?> class_metadata){
+ try{
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodHandles.Lookup private_lookup = MethodHandles.privateLookupIn(class_metadata ,lookup);
+
+ // Map constructors
+ for(Constructor<?> constructor : class_metadata.getDeclaredConstructors()){
+ Class<?>[] parameter_types = constructor.getParameterTypes();
+ MethodType method_type = MethodType.methodType(class_metadata, parameter_types);
+ MethodHandle constructor_handle;
+
+ if((constructor.getModifiers() & Modifier.PRIVATE) != 0){
+ constructor_handle = private_lookup.findConstructor(class_metadata, method_type);
+ } else{
+ constructor_handle = lookup.findConstructor(class_metadata, method_type);
+ }
+
+ FunctionSignature signature = new FunctionSignature("<init>", parameter_types);
+ map.put(signature, constructor_handle);
+ }
+
+ // Map methods
+ for(Method method : class_metadata.getDeclaredMethods()){
+ Class<?>[] parameter_types = method.getParameterTypes();
+ MethodType method_type = MethodType.methodType(
+ method.getReturnType() ,parameter_types
+ );
+ MethodHandle method_handle;
+
+ if((method.getModifiers() & Modifier.PRIVATE) != 0){
+ method_handle = private_lookup.findSpecial(class_metadata ,method.getName() ,method_type ,class_metadata);
+ } else{
+ method_handle = lookup.findVirtual(class_metadata ,method.getName() ,method_type);
+ }
+
+ FunctionSignature signature = new FunctionSignature(method);
+ map.put(signature ,method_handle);
+ }
+ } catch(Throwable t){
+ System.out.println("FunctionSignature_To_Handle_Map::add_class exception:");
+ t.printStackTrace();
+ }
+ }
+
+
+ /*
+
private void add_class(Class<?> class_metadata){
try{
MethodHandles.Lookup lookup = MethodHandles.lookup();
);
MethodHandle method_handle;
- if( (method.getModifiers() & java.lang.reflect.Modifier.PRIVATE) != 0 ){
+ if((method.getModifiers() & java.lang.reflect.Modifier.PRIVATE) != 0 ){
method_handle = private_lookup.findSpecial(class_metadata ,method.getName() ,method_type ,class_metadata);
}else{
method_handle = lookup.findVirtual(class_metadata ,method.getName() ,method_type);
t.printStackTrace();
}
}
+ */
+
public MethodHandle get_handle(FunctionSignature signature){
return map.get(signature);
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("FunctionSignature to MethodHandle Map:\n");
- for (Map.Entry<FunctionSignature, MethodHandle> entry : map.entrySet()) {
+ for(Map.Entry<FunctionSignature, MethodHandle> entry : map.entrySet()) {
sb.append(" ").append(entry.getKey()).append(" -> ").append(entry.getValue()).append("\n");
}
return sb.toString();
this.map = new FunctionSignature_To_Handle_Map(target_type);
}
+ public Object construct(String constructor_name, Object... arg_list) {
+ try {
+ // Resolve the constructor signature
+ FunctionSignature signature = new FunctionSignature(constructor_name, arg_list);
+ MethodHandle handle = map.get_handle(signature);
+
+ if (handle == null) {
+ throw new NoSuchMethodException("No constructor found for signature: " + signature.get_method_name());
+ }
+
+ // Unwrap Mosaic_IsPrimitive instances
+ Object[] unwrapped_args = new Object[arg_list.length];
+ for (int i = 0; i < arg_list.length; i++) {
+ if (arg_list[i] instanceof Mosaic_IsPrimitive) {
+ unwrapped_args[i] = ((Mosaic_IsPrimitive) arg_list[i]).get_value();
+ } else {
+ unwrapped_args[i] = arg_list[i];
+ }
+ }
+
+ // Invoke the constructor handle
+ return handle.invokeWithArguments(unwrapped_args);
+
+ } catch (Throwable t) {
+ System.out.println("Mosaic_AllMethodsPublicProxy::construct exception:");
+ t.printStackTrace();
+ return null;
+ }
+ }
+
+
public Object invoke(Object target_instance, String method_name, Object... arg_list) {
try {
- if (target_instance == null || !target_type.isInstance(target_instance)) {
+ if(target_instance == null || !target_type.isInstance(target_instance)) {
System.out.println("Warning: Instance is not of type " + target_type.getName());
}
- // Resolve the function signature
+ // Resolve the function signature.
+ // The IsPrimtiive tags are needed here so as to form a correct signature for
+ // looking up the handle.
+ //
FunctionSignature signature = new FunctionSignature(method_name, arg_list);
MethodHandle handle = map.get_handle(signature);
System.out.println( "invoked with signature: " + signature.toString() );
- if (handle == null) {
+ if(handle == null) {
throw new NoSuchMethodException("No method found for signature: " + signature.get_method_name());
}
- // Unwrap isPrimitive instances in arguments
+ // This removes the IsPrimitive tags (unwrap the containted
+ // values). The `get_value` will be boxed in the Java Wrappers,
+ // i.e. `int` values wills till be Integer, because it is
+ // Object type. Later `invokeWithArguments` below will unbox the
+ // primitive values as it is aware of the types required for the call.
+ //
Object[] unwrapped_args = new Object[arg_list.length];
- for (int i = 0; i < arg_list.length; i++) {
- if (arg_list[i] instanceof isPrimitive) {
- unwrapped_args[i] = ((isPrimitive) arg_list[i]).get_value();
+ for(int i = 0; i < arg_list.length; i++) {
+ if(arg_list[i] instanceof Mosaic_IsPrimitive) {
+ unwrapped_args[i] = ((Mosaic_IsPrimitive) arg_list[i]).get_value();
} else {
unwrapped_args[i] = arg_list[i];
}
return handle.bindTo(target_instance).invokeWithArguments(unwrapped_args);
- } catch (Throwable t) {
+ }catch(Throwable t) {
System.out.println("Mosaic_AllMethodsPublicProxy::invoke exception:");
t.printStackTrace();
return null;
--- /dev/null
+package com.ReasoningTechnology.Mosaic;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import com.ReasoningTechnology.Mosaic.Mosaic_IsPrimitive;
+
+public class Mosaic_FunctionSignature {
+ private final String method_name;
+ private final Class<?>[] parameter_types;
+
+ public FunctionSignature(String method_name ,Class<?>[] parameter_types){
+ this.method_name = method_name;
+ this.parameter_types = parameter_types;
+ }
+
+ public FunctionSignature(String method_name ,Object[] args){
+ this.method_name = method_name;
+ this.parameter_types = resolve_parameter_types(args);
+ }
+
+ public FunctionSignature(Method method){
+ this.method_name = method.getName();
+ this.parameter_types = method.getParameterTypes();
+ }
+
+ private static Class<?>[] resolve_parameter_types(Object[] arg_list){
+ Class<?>[] parameter_types = new Class<?>[arg_list.length];
+ for( int i = 0; i < arg_list.length; i++ ){
+ if( arg_list[i] instanceof Mosaic_IsPrimitive ){
+ parameter_types[i] = ((Mosaic_IsPrimitive) arg_list[i]).get_type();
+ }else if( arg_list[i] != null ){
+ parameter_types[i] = arg_list[i].getClass();
+ }else{
+ parameter_types[i] = null;
+ }
+ }
+ return parameter_types;
+ }
+
+ public String get_method_name(){
+ return method_name;
+ }
+
+ public Class<?>[] get_parameter_types(){
+ return parameter_types;
+ }
+
+ @Override
+ public boolean equals(Object o){
+ if( this == o ) return true;
+ if( o == null || getClass() != o.getClass() ) return false;
+ FunctionSignature signature = (FunctionSignature) o;
+ return method_name.equals(signature.method_name) &&
+ java.util.Arrays.equals(parameter_types ,signature.parameter_types);
+ }
+
+ @Override
+ public int hashCode(){
+ int result = method_name.hashCode();
+ result = 31 * result + java.util.Arrays.hashCode(parameter_types);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(method_name).append("(");
+ for (int i = 0; i < parameter_types.length; i++) {
+ sb.append(parameter_types[i].getSimpleName());
+ if (i < parameter_types.length - 1) sb.append(", ");
+ }
+ sb.append(")");
+ return sb.toString();
+ }
+
+}
+
}
public Class<?> get_type(){
+ if( value == null ) return null;
if( value instanceof Integer ) return int.class;
if( value instanceof Boolean ) return boolean.class;
if( value instanceof Double ) return double.class;
--- /dev/null
+import com.ReasoningTechnology.Mosaic.*;
+
+public class Test_FunctionSignature{
+
+ public class TestSuite{
+
+ public Boolean test_basic_signature(Mosaic_IO io){
+ Boolean[] conditions = new Boolean[3];
+ int i = 0;
+
+ // Test resolve_parameter_types with primitives and non-primitives
+ Mosaic_FunctionSignature sig1 = new Mosaic_FunctionSignature("test", new Object[]{42, "hello"});
+ conditions[i++] = sig1.get_parameter_types()[0].equals(int.class);
+ conditions[i++] = sig1.get_parameter_types()[1].equals(String.class);
+
+ // Test method name retrieval
+ conditions[i++] = sig1.get_method_name().equals("test");
+
+ return Mosaic_Util.all(conditions);
+ }
+
+ public Boolean test_signature_equality(Mosaic_IO io){
+ Boolean[] conditions = new Boolean[2];
+ int i = 0;
+
+ Mosaic_FunctionSignature sig1 = new Mosaic_FunctionSignature("test", new Object[]{42, "hello"});
+ Mosaic_FunctionSignature sig2 = new Mosaic_FunctionSignature("test", new Object[]{42, "hello"});
+
+ // Test equality and hash code
+ conditions[i++] = sig1.equals(sig2);
+ conditions[i++] = sig1.hashCode() == sig2.hashCode();
+
+ return Mosaic_Util.all(conditions);
+ }
+
+ public Boolean test_null_arguments(Mosaic_IO io){
+ Boolean[] conditions = new Boolean[2];
+ int i = 0;
+
+ Mosaic_FunctionSignature sig = new Mosaic_FunctionSignature("test", new Object[]{null});
+
+ // Test parameter types for null argument
+ conditions[i++] = sig.get_parameter_types()[0] == null;
+
+ // Test method name retrieval
+ conditions[i++] = sig.get_method_name().equals("test");
+
+ return Mosaic_Util.all(conditions);
+ }
+
+ public Boolean test_to_string(Mosaic_IO io){
+ Boolean[] conditions = new Boolean[1];
+ int i = 0;
+
+ Mosaic_FunctionSignature sig = new Mosaic_FunctionSignature("example", new Object[]{42, "text"});
+ String expected = "example(int, String)";
+
+ // Test string representation
+ conditions[i++] = sig.toString().equals(expected);
+
+ return Mosaic_Util.all(conditions);
+ }
+
+ public Boolean test_method_constructor(Mosaic_IO io){
+ Boolean[] conditions = new Boolean[2];
+ int i = 0;
+
+ class TestClass{
+ public void sampleMethod(int a, String b){}
+ }
+
+ try{
+ Method method = TestClass.class.getDeclaredMethod("sampleMethod", int.class, String.class);
+ Mosaic_FunctionSignature sig = new Mosaic_FunctionSignature(method);
+
+ // Test method name
+ conditions[i++] = sig.get_method_name().equals("sampleMethod");
+
+ // Test parameter types
+ conditions[i++] = sig.get_parameter_types()[0].equals(int.class) &&
+ sig.get_parameter_types()[1].equals(String.class);
+ } catch (NoSuchMethodException e){
+ return false; // This shouldn't happen in a controlled test
+ }
+
+ return Mosaic_Util.all(conditions);
+ }
+ }
+
+ public static void main(String[] args){
+ TestSuite suite = new Test_FunctionSignature().new TestSuite();
+ int result = Mosaic_Testbench.run(suite);
+ System.exit(result);
+ }
+}
--- /dev/null
+/* --------------------------------------------------------------------------------
+ Integration tests directly simulate the use cases for Mosaic_Testbench.
+ Each test method validates a specific feature of Mosaic_Testbench ,including pass,
+ fail ,error handling ,and I/O interactions.
+*/
+import java.util.Scanner;
+
+import com.ReasoningTechnology.Mosaic.Mosaic_IO;
+import com.ReasoningTechnology.Mosaic.Mosaic_IsPrimitive;
+import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
+
+import com.ReasoningTechnology.Mosaic.Mosaic_IO;
+import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
+import com.ReasoningTechnology.Mosaic.Mosaic_IsPrimitive;
+
+public class Test_IsPrimitive{
+
+ public class TestSuite{
+
+
+ public Boolean test_int_type(Mosaic_IO io){
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make(42);
+ return mip.get_type().equals(int.class);
+ }
+
+ public Boolean test_boolean_type(Mosaic_IO io){
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make(true);
+ return mip.get_type().equals(boolean.class);
+ }
+
+ public Boolean test_double_type(Mosaic_IO io){
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make(3.14);
+ return mip.get_type().equals(double.class);
+ }
+
+ public Boolean test_string_type(Mosaic_IO io){
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make("hello");
+ return mip.get_type().equals(String.class);
+ }
+
+ public Boolean test_object_type(Mosaic_IO io){
+ Object obj = new Object();
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make(obj);
+ return mip.get_type().equals(Object.class);
+ }
+
+ public Boolean test_char_type(Mosaic_IO io){
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make('a');
+ return mip.get_type().equals(char.class);
+ }
+
+ public Boolean test_null_value(Mosaic_IO io){
+ try{
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make(null);
+ return mip.get_type() == null; // Should handle gracefully or throw
+ } catch (Exception e){
+ return false;
+ }
+ }
+
+ public Boolean test_empty_string(Mosaic_IO io){
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make("");
+ return mip.get_type().equals(String.class);
+ }
+
+ public Boolean test_blank_string(Mosaic_IO io){
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make(" ");
+ return mip.get_type().equals(String.class);
+ }
+
+ // When passing arguments through Object types, there is no way
+ // for the callee to know if the caller sent a primitive type or a
+ // boxed value. This is the point of having IsPrimitive.
+ // IsPrimitive indicates that we really mean to send the primitive
+ // type, though it appears in the box.
+ public Boolean test_primitive_wrapper(Mosaic_IO io){
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make(Integer.valueOf(42));
+ return mip.get_type().equals(int.class);
+ }
+
+ public Boolean test_primitive_array(Mosaic_IO io){
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make(new int[]{1, 2, 3});
+ return mip.get_type().equals(int[].class);
+ }
+
+ public Boolean test_object_array(Mosaic_IO io){
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make(new String[]{"a", "b", "c"});
+ return mip.get_type().equals(String[].class);
+ }
+
+ public Boolean test_enum_type(Mosaic_IO io){
+ enum TestEnum{ VALUE1, VALUE2 }
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make(TestEnum.VALUE1);
+ return mip.get_type().equals(TestEnum.class);
+ }
+
+ public Boolean test_collection_type(Mosaic_IO io){
+ java.util.List<Integer> list = java.util.Arrays.asList(1, 2, 3);
+ Mosaic_IsPrimitive mip = Mosaic_IsPrimitive.make(list);
+ return mip.get_type().getName().equals("java.util.Arrays$ArrayList");
+ }
+
+ public Boolean test_extreme_primitive_values(Mosaic_IO io){
+ Mosaic_IsPrimitive mipMax = Mosaic_IsPrimitive.make(Integer.MAX_VALUE);
+ Mosaic_IsPrimitive mipMin = Mosaic_IsPrimitive.make(Integer.MIN_VALUE);
+ Mosaic_IsPrimitive mipNaN = Mosaic_IsPrimitive.make(Double.NaN);
+ return mipMax.get_type().equals(int.class)
+ && mipMin.get_type().equals(int.class)
+ && mipNaN.get_type().equals(double.class);
+ }
+ }
+
+ public static void main(String[] args){
+ TestSuite suite = new Test_IsPrimitive().new TestSuite();
+ int result = Mosaic_Testbench.run(suite);
+ System.exit(result);
+ }
+}
Intentional extraneous chars to stderr for testing.
+2024-12-14T05:51:43.096Z [main] INFO c.R.Mosaic.Mosaic_Logger -
+2024-12-14T05:51:43.094778420Z -----------------------------------------------------------
+Test: smoke_test_logging
+Message:
+This is a smoke test for logging.
+
+2024-12-14T05:51:43.496Z [main] INFO c.R.Mosaic.Mosaic_Logger -
+2024-12-14T05:51:43.494998052Z -----------------------------------------------------------
+Test: test_failure_3
+Stream: stdout
+Output:
+Intentional extraneous chars to stdout for testing
+
+
+2024-12-14T05:51:43.497Z [main] INFO c.R.Mosaic.Mosaic_Logger -
+2024-12-14T05:51:43.497259959Z -----------------------------------------------------------
+Test: test_failure_4
+Stream: stderr
+Output:
+Intentional extraneous chars to stderr for testing.
+
+
#!/bin/env bash
script_afp=$(realpath "${BASH_SOURCE[0]}")
+# each test listed here will receive a shell wrapper, and run_tests will
+# include the test in the test run, in the order it appears in the list.
+
# input guards
env_must_be="tester/tool🖉/env"
if [ "$ENV" != "$env_must_be" ]; then
Test_IO\
Test_Testbench\
Test_MockClass_0\
- Test_Util_proxy
-
+ Test_Util_proxy\
+ Test_IsPrimitive\
+ Test_FunctionSignature\
+ ""
export CLASSPATH=\
"$BASE_CLASSPATH\
-:$REPO_HOME/tester/scratchpad
+:$REPO_HOME/tester/scratchpad\
:$REPO_HOME/release/${PROJECT}.jar\
:$CLASSPATH"