<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>test/test_get_global_object.py</filename>
    </added>
    <added>
      <filename>test/test_get_type.py</filename>
    </added>
    <added>
      <filename>test/test_make_function_with_callback.py</filename>
    </added>
    <added>
      <filename>test/test_utils.py</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,2 +1,3 @@
+.DS_Store
 *.bbproject
-*.worksheet
\ No newline at end of file
+*.worksheet</diff>
      <filename>.gitignore</filename>
    </modified>
    <modified>
      <diff>@@ -36,7 +36,7 @@ import os
 #-------------------------------------------------------------------
 # logger
 #-------------------------------------------------------------------
-_LOGGING = False
+_LOGGING = True
 def _log(message=&quot;&quot;):
     if not _LOGGING: return
     
@@ -106,19 +106,16 @@ def _string2jsString(string):
 #--------------------------------------------------------------------
 def _jsString2string(jsString):
     &quot;&quot;&quot;Convert a JSString to a string - always utf8&quot;&quot;&quot;
-    _log(&quot;%s&quot; % str(jsString))
+    _log()
     
     if not jsString: return None
     if isinstance(jsString, str): return jsString
     
     len = _JSStringGetMaximumUTF8CStringSize(jsString)
-    _log(&quot;len: %d&quot; % len)
     
     result = ctypes.c_char_p(&quot; &quot; * len)
-    _log(&quot;result: %s&quot; % str(result))
 
     _JSStringGetUTF8CString(jsString, result, len)
-    _log(&quot;result: %s&quot; % str(result))
     
     return result.value
 
@@ -211,37 +208,31 @@ class JSContext:
         @type  startingLineNumber: number
         @param startingLineNumber: the line number of the script
         &quot;&quot;&quot;
+        _log()
         
-        _log(&quot;script=%s, sourceURL=%s, startingLineNumber=%d&quot; % (repr(script), repr(sourceURL), startingLineNumber))
         self._checkAllocated()
         if not script: raise Exception, &quot;script was None&quot;
         
         script_js = _string2jsString(script)
-        _log(&quot;script_js: %s&quot; % (script_js))
         
         if not sourceURL: 
             sourceURL_js = None
         else:
             sourceURL_js = _string2jsString(sourceURL)
-        _log(&quot;sourceURL_js: %s&quot; % (script_js))
 
         exception = _JSValueRef(None)
-        _log(&quot;exception: %s&quot; % (str(exception)))
-        _log(&quot;_JSCheckScriptSyntax(%s,%s,%s,%d,%s)&quot; % (str(self), script, sourceURL, startingLineNumber, str(exception)))
         result = _JSCheckScriptSyntax(self.ctx,
             script_js,
             sourceURL_js,
             startingLineNumber,
             ctypes.byref(exception)
             )
-        _log(&quot;result: %s&quot; % (str(result)))
         
         _JSStringRelease(script_js)
         if sourceURL_js: _JSStringRelease(sourceURL_js)
         
         if exception.value: 
             jsObject = JSObject(exception, self.ctx)
-            _log(&quot;raise %s, %s&quot; % (str(JSException), str(jsObject)))
             raise JSException, jsObject
             
         return result == 1
@@ -266,7 +257,8 @@ class JSContext:
         @type  startingLineNumber: number
         @param startingLineNumber: the line number of the script
         &quot;&quot;&quot;
-        _log(&quot;script=%s, sourceURL=%s, startingLineNumber=%d&quot; % (repr(script), repr(sourceURL), startingLineNumber))
+        _log()
+
         self._checkAllocated()
         if not script: raise Exception, &quot;script was None&quot;
         
@@ -296,7 +288,7 @@ class JSContext:
         return JSObject(result, self.ctx)._toPython()
 
     #----------------------------------------------------------------
-    def getGlobalObject():
+    def getGlobalObject(self):
         &quot;&quot;&quot;A veneer over JSContextGetGlobalObject()
         
         @rtype:   JSObject
@@ -305,19 +297,36 @@ class JSContext:
 
         self._checkAllocated()
         
-        return JSObject(JSContextGetGlobalObject(self.ctx), self.ctx)
+        return JSObject(_JSContextGetGlobalObject(self.ctx), self.ctx)
         
     #----------------------------------------------------------------
-    def makeConstructorWithCallback(name, callback):
+    def makeConstructorWithCallback(self, name, callback):
         &quot;&quot;&quot;A veneer over JSObjectMakeConstructor()&quot;&quot;&quot;
         
         pass
         
     #----------------------------------------------------------------
-    def makeFunctionWithCallback(name, callback):
+    def makeFunctionWithCallback(self, name, callback):
         &quot;&quot;&quot;A veneer over JSObjectMakeFunctionWithCallback()&quot;&quot;&quot;
         
-        pass
+        self._checkAllocated()
+        
+        def callback_py(ctx, function, thisObject, argCount, args_js, exception):
+            args = []
+            for i in xrange(0, argCount):
+                arg_js = args_js[i]
+                arg    = JSObject(arg_js, self.ctx)._toPython()
+                args.append(arg)
+            callback(ctx, function, thisObject, argCount, args, exception)
+            
+        name_js = _string2jsString(name)
+        callback_c = _JSObjectCallAsFunctionCallback(callback_py)
+        
+        result = _JSObjectMakeFunctionWithCallback(self.ctx, name_js, callback_c)
+        
+        _JSStringRelease(name_js)
+        
+        return JSObject(result, self.ctx)
 
     #----------------------------------------------------------------
     def makeBoolean(value):
@@ -364,6 +373,23 @@ class JSContext:
 #--------------------------------------------------------------------
 class JSObject:
     &quot;&quot;&quot;Models a JavaScript object &quot;&quot;&quot;
+
+    #--------------------------------------------------------------------
+    @staticmethod
+    def _fromPython(pyObject, ctx):
+        &quot;&quot;&quot;Convert to a Python value&quot;&quot;&quot;
+
+        if not ctx: raise Exception, &quot;ctx has been released&quot;
+       
+        if None == pyObject:            return _JSValueMakeNull(ctx)
+        if JSUndefined == pyObject:     return _JSValueMakeUndefined(ctx)
+        if isinstance(pyObject, bool):  return _JSValueMakeBoolean(ctx, pyObject)
+        if isinstance(pyObject, int):   return _JSValueMakeNumber(ctx, pyObject)
+        if isinstance(pyObject, float): return _JSValueMakeNumber(ctx, pyObject)
+        if isinstance(pyObject, long):  return _JSValueMakeNumber(ctx, pyObject)
+        if isinstance(pyObject, str):   return _string2jsString(pyObject)
+        return pyObject
+
     
     #----------------------------------------------------------------
     def __init__(self, jsRef, ctx):
@@ -538,7 +564,6 @@ class JSObject:
         ctx = jsContext.ctx if jsContext else self.ctx
         self._checkAllocated(ctx)
 
-        _log(&quot;ctx: %s; ref: %s&quot; % (ctx, self.jsRef))
         exception = _JSValueRef(None)
         jsString  = _JSValueToStringCopy(ctx, self.jsRef, ctypes.byref(exception))
         
@@ -563,6 +588,7 @@ class JSObject:
     #----------------------------------------------------------------
     def getPropertyNames(self, jsContext=None):
         &quot;&quot;&quot;A veneer over JSObjectCopyPropertyNames()&quot;&quot;&quot;
+        _log()
         
         ctx = jsContext.ctx if jsContext else self.ctx
         self._checkAllocated(ctx)
@@ -571,10 +597,8 @@ class JSObject:
         length = _JSPropertyNameArrayGetCount(jsPropertyNameArray)
         result = []
         
-        _log(&quot;length: %d&quot; % length)
         for i in xrange(0,length):
             jsString = _JSPropertyNameArrayGetNameAtIndex(jsPropertyNameArray,i)
-            _log(&quot;jsString: %s&quot; % str(jsString))
             result.append(_jsString2string(jsString))
             
         return result
@@ -588,15 +612,13 @@ class JSObject:
     #----------------------------------------------------------------
     def getProperty(self, propertyName, jsContext=None):
         &quot;&quot;&quot;A veneer over JSObjectGetProperty()&quot;&quot;&quot;
-        
-        _log(&quot;self: %s; propertyName: %s&quot; % (str(self), propertyName))
+        _log()
         
         ctx = jsContext.ctx if jsContext else self.ctx
         self._checkAllocated(ctx)
 
         propertyName_js = _string2jsString(propertyName)
         exception       = _JSValueRef(None)
-        _log(&quot;propertyName_js: %s&quot; % propertyName_js)
         jsResult        = _JSObjectGetProperty(ctx, self.jsRef, propertyName_js, ctypes.byref(exception))
         
         _JSStringRelease(propertyName_js)
@@ -604,18 +626,14 @@ class JSObject:
         if exception.value: 
             jsObject = JSObject(exception, self.ctx)
             raise JSException(jsObject)
-
-        _log(&quot;jsResult: %s&quot; % jsResult)
             
         jsObject = JSObject(jsResult, ctx)
-        _log(&quot;jsObject: %s&quot; % str(jsObject))
         
         return jsObject._toPython(jsContext)
 
     #----------------------------------------------------------------
     def getPropertyAtIndex(self, propertyIndex, jsContext=None):
         &quot;&quot;&quot;A veneer over JSGetPropertyAtIndex()&quot;&quot;&quot;
-        
         _log()
         
         ctx = jsContext.ctx if jsContext else self.ctx
@@ -666,9 +684,23 @@ class JSObject:
     #----------------------------------------------------------------
     def setProperty(self, propertyName, value, attributes, jsContext=None):
         &quot;&quot;&quot;A veneer over JSObjectSetProperty()&quot;&quot;&quot;
+        _log()
         
-        self._checkAllocated()
+        ctx = jsContext.ctx if jsContext else self.ctx
+        self._checkAllocated(ctx)
+
+        propertyName_js = _string2jsString(propertyName)
+        exception       = _JSValueRef(None)
+        value_js        = JSObject._fromPython(value, ctx)
+        _log(&quot;_JSObjectSetProperty(%s,%s,%s,%s,%s)&quot; % (str(ctx), str(self.jsRef), str(propertyName_js), str(value), str(attributes)))
+        result          = _JSObjectSetProperty(ctx, self.jsRef, propertyName_js, value.jsRef, attributes, ctypes.byref(exception))
 
+        _JSStringRelease(propertyName_js)
+
+        if exception.value: 
+            jsObject = JSObject(exception, self.ctx)
+            raise JSException(jsObject)
+        
     #----------------------------------------------------------------
     def setPropertyAtIndex(self, propertyIndex, value, jsContext=None):
         &quot;&quot;&quot;A veneer over JSObjectSetPropertyAtIndex()&quot;&quot;&quot;
@@ -714,7 +746,6 @@ class JSException(Exception):
         &quot;&quot;&quot; &quot;&quot;&quot;
         return repr(self.value)
     
-    
 #-------------------------------------------------------------------
 # simple typedefs
 #-------------------------------------------------------------------</diff>
      <filename>lib/Nitro.py</filename>
    </modified>
    <modified>
      <diff>@@ -32,11 +32,6 @@ import unittest
 lib_path = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), &quot;../lib&quot;))
 if lib_path not in sys.path: sys.path.insert(0, lib_path)
 
-import test_jsstring
-import test_load_lib
-import test_check_script_syntax
-import test_eval
-
 suite  = unittest.TestSuite()
 result = unittest.TestResult()
 runner = unittest.TextTestRunner(verbosity=2)
@@ -46,10 +41,20 @@ def addTest(module):
     suite.addTest(unittest.defaultTestLoader.loadTestsFromModule(module))
     
 #-------------------------------------------------------------------
-addTest(test_jsstring)
-addTest(test_load_lib)
-addTest(test_check_script_syntax)
-addTest(test_eval)
+
+moduleNames = &quot;&quot;&quot;
+test_jsstring
+test_load_lib
+test_check_script_syntax
+test_eval
+test_get_global_object
+test_get_type
+test_make_function_with_callback
+&quot;&quot;&quot;.split()
+
+modules = [__import__(moduleName) for moduleName in moduleNames]
+
+for module in modules: addTest(module)
 
 runner.run(suite)
 </diff>
      <filename>test/test_all.py</filename>
    </modified>
    <modified>
      <filename>test/test_check_script_syntax.py</filename>
    </modified>
    <modified>
      <filename>test/test_eval.py</filename>
    </modified>
    <modified>
      <filename>test/test_jsstring.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>8efb09d39908a21c0e9f2a1d875605e208011b2a</id>
    </parent>
  </parents>
  <author>
    <name>Patrick Mueller</name>
    <email>pmuellr@yahoo.com</email>
  </author>
  <url>http://github.com/pmuellr/nitro_pie/commit/45133eb5dc72de4660b09dc6a90397e56077a2d9</url>
  <id>45133eb5dc72de4660b09dc6a90397e56077a2d9</id>
  <committed-date>2009-04-03T12:57:27-07:00</committed-date>
  <authored-date>2009-04-03T12:57:27-07:00</authored-date>
  <message>more test cases; function callbacks not quite working yet</message>
  <tree>b595b3caf87b736677b4c5eceaf11ad1f80c9b02</tree>
  <committer>
    <name>Patrick Mueller</name>
    <email>pmuellr@yahoo.com</email>
  </committer>
</commit>
