Symptoms:

Traceback (most recent call last):
File "./gitinspector.py", line 25, in
localization.init()

File "/Users/nocoo/Downloads/gitinspector-0.3.2/gitinspector/localization.py", line 43, in init
lang = locale.getlocale()

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/locale.py", line 530, in getlocale
return _parse_localename(localename)

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/locale.py", line 443, in _parse_localename
raise ValueError, 'unknown locale: %s' % localename

Solution:
unset LANG
env | grep LC_
export LC_CTYPE="UTF-8"
env | grep LC_

Document:

// Adds a photo to the saved photos album.  The optional completionSelector should have the form:
//  - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;
func UIImageWriteToSavedPhotosAlbum(image: UIImage!, completionTarget: AnyObject!, completionSelector: Selector, contextInfo: UnsafeMutablePointer<()>)

But what you need to do like this:

@IBAction func onSave(sender: AnyObject) {
    UIImageWriteToSavedPhotosAlbum(self.image.image, self, Selector("image:didFinishSavingWithError:contextInfo:"), nil)
}

func image(image: UIImage, didFinishSavingWithError error: NSErrorPointer, contextInfo: UnsafePointer<()>) {
    dispatch_async(dispatch_get_main_queue(), {
        UIAlertView(title: "Success", message: "This image has been saved to your Camera Roll successfully", delegate: nil, cancelButtonTitle: "Close").show()
    })
}

String+md5.swift

import Foundation

extension String {
    func MD5() -> String {
        let data = (self as NSString).dataUsingEncoding(NSUTF8StringEncoding)
        let result = NSMutableData(length: Int(CC_MD5_DIGEST_LENGTH))
        let resultBytes = UnsafeMutablePointer(result.mutableBytes)
        CC_MD5(data.bytes, CC_LONG(data.length), resultBytes)

        let a = UnsafeBufferPointer(start: resultBytes, length: result.length)
        let hash = NSMutableString()

        for i in a {
            hash.appendFormat("%02x", i)
        }

        return hash
    }
}

Bridge.h

#import 

架构是这样的:NodeJS+Express,使用EJS作为模板。
错误是这样的:

HTTP/1.1 open unknown
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 11874
Set-Cookie: connect.sid=x4iNL4p1zGLt5mhMphHtiDFh.WVVHofhb3GyrkXnOyTQbe1SgGC2AEydsHCZiLGSB%2FY0; path=/; expires=Thu, 21 Jun 2012 06:54:36 GMT; httpOnly
Connection: keep-alive

在渲染一些页面的时候,Express会放以上的文字在HTML文档正文前面,一些浏览器(Chrome,IE)会忽略这些文字,看起来正常。还有的浏览器(Opera),会继续等待服务器的返回,表现为页面已经渲染,但是JavaScript并不执行,一直在Loading直至超时,按停止键能够正常加载完成页面功能。另一些浏览器(主要是个版本Safari)会直接认为文档是纯文本,从而显示源代码,如图所示。

也许是Express用户群比较小的原因,我一直没能找到这个问题的原因。经过艰苦卓绝的debug,终于找到了原因。以下是罪魁祸首。

请注意,在192行,我从URL里读取了名为status的参数,原封不动地使用名称status作为模板参数传给了EJS模板。在EJS模板中,这样使用了:

悲剧就此发生。改成这样:

并在EJS中避免使用<%= status %>,改用<%= docstatus %>,问题马上解决。我尚不太明白错误的机制,我猜EJS的参数中,status变量可能保留另有作用了。祝你早日解决HTTP/1.1 open unknown的问题。

QUnit是jQuery支持的一款JavaScript单页测试框架。简单易用。可以从QUnit的Github页面获取其代码。QUnit的使用与JUnit类似,相信有JUnit经验的开发者和测试人员可以很快上手。

开始写测试用例

  • test( name, expected, test )
    一个常规的测试用例。test里是测试用例的具体内容。
  • asyncTest( name, expected, test )
    一个异步测试用例。默认的test都是同步的。内容中必须显示地调用start(),测试才会开始。
  • expect( amount )
    用于测试代码中,表示在本测试里期待会执行amount个断言,大于或少于这个数量,测试都将失败。
  • module( name, lifecycle )
    定义一个名为name的模块。在可选参数lifecycle中,可以定义模块开始和结束的测试内容。具体见文档。
  • QUnit.init( )
    启动QUnit测试。如果测试在进行中,则会重新启动。基本不用。

QUnit支持的断言

  1. ok( state, message )
    真假断言,state为true则通过。类似于JUnit的assertTrue。
  2. equal( actual, expected, message )
    相等断言,actual和expected相等(==)则通过。类似于JUnit的assertEquals。
  3. notEqual( actual, expected, message )
    不等断言,actual和expected不相等(!=)则通过。类似于JUnit的assertNotEquals。
  4. deepEqual( actual, expected, message )
    递归相等断言,actual和expected全相等(包括其子元素都相等,适用于基本类型,数组和对象)则通过。对于基本类型,相当于strictEqual。
  5. notDeepEqual( actual, expected, message )
    递归不相等断言,actual和expected不全相等(包括其子元素都相等,适用于基本类型,数组和对象)则通过。对于基本类型,相当于notStrictEqual。
  6. strictEqual( actual, expected, message )
    全相等断言,actual和expected全相等(===)则通过。
  7. notStrictEqual( actual, expected, message )
    不全相等断言,actual和expected不全相等(===)则通过。
  8. raises( block, expected, message )
    异常断言,block中抛出异常则通过,expected为可选参数,是所期待抛出异常名的正则表达式。

把QUnit集成到现有工具

QUnit在执行的过程中会调用一系列函数,告知外界运行状况,大家可以覆盖这些函数,达到集成的目的。

  • QUnit.log({ result, actual, expected, message })
    每当断言执行结束后会调用此函数。
  • QUnit.testStart({ name })
    每当一个测试执行开始时会调用此函数。
  • QUnit.testDone({ name, failed, passed, total })
    每当一个测试执行结束后会调用此函数。
  • QUnit.moduleStart({ name })
    每当一个模块执行开始时会调用此函数。
  • QUnit.moduleDone({ name, failed, passed, total })
    每当一个模块执行结束后会调用此函数。
  • QUnit.begin()
    当QUnit开始时会调用此函数。
  • QUnit.done()
    当QUnit结束后会调用此函数。

在后面的实例中,我写了一些覆盖,打印了执行过程。相信有了这些回调函数的帮助,写一个进度条出来也不是难事。

QUnit的过滤器

  • noglobals
    如果勾选,那么如果一个测试中引入了全局变量,则测试会失败。JavaScript中引入全局变量(window的属性)是不推荐的行为。
  • notrycatch
    如果勾选,代码中的try-catch将不会生效,一旦程序中有异常发生,测试即刻终止。

QUnit的一个实例

页面输出如下:

页面全部代码如下:

[html]





QUnit example

    test markup, will be hidden



      [/html]