Hot For Coding
用QUnit单元测试开发你的程序

关于单元测试

单元测试是保障程序按照预期逻辑执行的一种测试方式,现在也逐渐被应用到前端项目。我刚开始写JavaScript的时候每次测试都要启动浏览器调用一下需要测试的代码,甚至还需要模拟一些数据来达到效果,最后这些测试的代码片段会被删除。但是bug出现的时候不得不在页面中重新写测试代码,非常费时。

事实上单元测试已经非常的成熟,包括赫赫有名的YUI test,今天我们介绍jQuery团队开发的QUnit单元测试框架,目前jQuery的测试正是使用这个单元测试框架,如果感兴趣可以到github上看看jQuery的test内容

准备

QUnit框架实际上就是一个JavaScript文件还有一个css文件,从官网http://qunitjs.com/下载引用或者直接使用cdn镜像

...

READ ALL

lsof好用的Linux命令

lsof(list open files)是一个列出当前系统打开文件的工具,我通常使用它来查看网络端口占用,因为在Linux下所有事物都是以文件的形式存在。

root@node5:~# lsof | head -10
COMMAND     PID   TID       USER   FD      TYPE             DEVICE   SIZE/OFF       NODE NAME
systemd       1             root  cwd       DIR              254,0       4096          2 /
systemd       1             root  rtd       DIR              254,0       4096          2 /
systemd       1             root  txt       REG              254,0    1120992    2884146 /lib/systemd/systemd
systemd       1             root  mem       REG              254,0      19008    2883683 /lib/x86_64-linux-gnu/libuuid.so.1.3.0
systemd       1             root  mem       REG              254,0      18832    2883613 /lib/x86_64-linux-gnu/libattr.so.1.1.0
systemd       1             root  mem       REG              254,0      79936    2883655 /lib/x86_64-linux-gnu/libgpg-error.so.0.21.0
systemd       1             root  mem       REG              254,0     283464    2883666 /lib/x86_64-linux-gnu/libblkid.so.1.1.0
systemd       1             root  mem       REG              254,0      22944    2883621 /lib/x86_64-linux-gnu/libcap-ng.so.0.0.0
systemd       1             root  mem       REG              254,0      14640    2883595 /lib/x86_64-linux-gnu/libdl-2.24.so

...

READ ALL

Cannot locate header file MagickWand.h

今天编译安装PHP拓展imagick的时候,总是提示:

checking for MagickWand.h header file... configure: error: Cannot locate header file MagickWand.h

跳不过去,缺少头文件

configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.
checking for gawk... gawk
checking whether to enable the imagick extension... yes, shared
checking whether to enable the imagick GraphicsMagick backend... no
checking ImageMagick MagickWand API configuration program... found in /usr/local/bin/MagickWand-config
checking if ImageMagick version is at least 6.2.4... found version 6.8.6 Q16 
checking for MagickWand.h header file... configure: error: Cannot locate header file MagickWand.h

...

READ ALL

jQuery Ajax 的同步与异步

默认jQuery所有的Ajax请求默认都是异步处理,即在回调函数里处理返回结果:

$.get('b.txt', function(data){
  console.log(data);
});

执行结果:

full

为了更清楚的知道异步处理特性,改写一下

console.log("开始请求!");
 
$.get('b.txt',function(data){
  console.log("请求结果!");
});
 
console.log("请求之后!");

...

READ ALL

JsDoc生成你的JavaScript文档

这是一个Java写的文档生成工具,注释风格要求跟Java的一样即可生成出注释文档,非常好用。直接到官网下载,网上一大堆教程都是JsDoc2版的,现在官网已经说了不再支持JsDoc2版,推荐使用JsDoc3版本。

Github: https://github.com/jsdoc3/jsdoc

下载后不用安装直接就能用,当然还是要先安装配置好JDK环境,不会的自行找资料。以Win平台做例子,下载过来后解压然后启动命令模式进入程序目录下执行jsdoc即可启动程序,可以直接jsdoc --help查看帮助文档,jsdoc3更直接方便的生成注释文档

...

READ ALL

Linux使用grep命令检索多个文件

Linux中grep是一个常用的搜索命令,今天介绍一下如何使用这个命令在多个文件里检索,用法很简单

grep <searching string> <pattern searching file>

如果我要检索当前所有md文件中的Hello关键字,可以这么用

$ grep Hello *.md
a.md:Hello World!
b.md:Hello, Jac
b.md:Hello, Jim

如果我们想知道是哪一行,可以加-nr属性

grep -nr Hello *.md
a.md:1:Hello World!
b.md:1:Hello, Jac
b.md:2:Hello, Jim

...

READ ALL

jQuery替换标签函数replaceWith()的使用

jQuery中,有一个强大的替换函数replaceWith(),使用非常简单,如:

// 把所有p标签替换为“##”
$('p').replaceWith('##');

利用这个replaceWith,我们可以把所有p标签替换为b标签,内容不变:

$('p').each(function(){
  $(this).replaceWith('<b>'+$(this).html()+'</b>');
});

如果你开发的是一个多语言的网站,甚至可以利用这个特性,比如,在你需要翻译的文字上加上i标签,然后遍历翻译替换。

...

READ ALL

JavaScript深度比较两个对象是否相等

在JavaScript中比较两个对象的成员是否相等有点麻烦,如果只是第一层比较,很容易,但子对象里的属性可能又是一个对象,所以只能递归。

代码:

// 去重
Array.prototype.unique = function () {
  this.sort();
  var re = [this[0]];
  for (var i = 1; i < this.length; i++) {
    if (this[i] !== re[re.length-1]) {
      re.push(this[i]);
    }
  }
  return re;
}

var objectDeepEqual = function(o1, o2) {
  if(typeof o1 != typeof o2){
    return false;
  }

  if(typeof o1.length != typeof o2.length ){
    return false;
  }

  var bool = true;

  var keyArr1 = [];
  var keyArr2 = [];
    
  for (var i in o1) {
    keyArr1.push(i);
  }

  for (var i in o2) {
    keyArr2.push(i);
  }

  if (keyArr1.length != keyArr2.length) {
    return false;
  }

  for(var i = 0, k = keyArr2.length; i < k; i++){
    keyArr1.push(keyArr2[i]);
  }

  var keyArr = keyArr1.unique();

  for(var i=0,k=keyArr.length;i<k;i++){
    if ((keyArr[i] in o1) && (keyArr[i] in o2)) {
      if (typeof o1[keyArr[i]] == 'object' && typeof o2[keyArr[i]] == 'object' ) {
        bool = objectDeepEqual(o1[keyArr[i]], o2[keyArr[i]]);
      } else if (o1[keyArr[i]] !== o2[keyArr[i]]){
        return false;
      }
    }else{
      return false;
    }
  }

  return bool;
};

...

READ ALL

看看这些程序是如何盗取站点数据的

翻了一下Nginx的log,发现这些傻逼天天使用程序不停的想要盗取我站点资料

14.114.23.72 - [23/Jul/2013:16:40:01] "HEAD /wwwroot.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:01] "HEAD /wwwroot.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:01] "HEAD /www.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /www.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /bbs.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /bbs.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /web.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /web.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /www.qttc.net.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /www.qttc.net.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /www_qttc_net.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /www_qttc_net.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /wwwqttcnet.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /wwwqttcnet.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /qttc.net.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:03] "HEAD /qttc.net.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:03] "HEAD /qttc.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:03] "HEAD /qttc.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"

...

READ ALL

阻止IE8下右键菜单的弹出

今天写一个自定义右键菜单功能,要实现这个功能需要捕获右键事件,这个很容易,几乎没有任何兼容。标签上添加 oncontextmenu 事件就好。下来就是阻止事件传播以及阻止系统右键弹出菜单的功能。于是我这么干

var e = evt || window.event;
 
if (e.preventDefault) {
  e.preventDefault();
}
     
if (e.stopPropagation) {
  e.stopPropagation();
} else {
  e.cancelBubble = true;
}

...

READ ALL