Ivor O’Connor

March 9, 2013

The Universal IDE: VI with SPF13

Filed under: bash, git, howto, html5, IDE, JavaScript, Linux, mint 14 xfce, php, sqlite, ubuntu, vi, vim, vundle — ioconnor @ 4:08 am

This is a youtube video I made on how to install SPF13 on Linux Mint 14 XFCE. I like learning from youtube videos whenever possible. If in the future I want to install SPF13 and something is not how I remember it I can return to this video. SPF13 makes VI into a universal IDE. It works on most if not all OSs including windows and the mac.  Sure if you are working with something like AIX, HP-UX, or some platform that does not have vim installed SPF13 will not be for you. I’d recommend you put in your base .vimrc commands directly into the .vimrc.local file and use them along with SPF13. Picking and choosing what you find works.

UPDATE 2013-03-08: Insert the following line into your .bashrc file before starting to get full colors: export TERM=”xterm-256color”

February 19, 2013

The Vim Vundle: spf13-vim

Filed under: bash, IDE, vi, vim, vundle — ioconnor @ 5:41 am

The SPF13 vundle is quite interesting. It is a pre-configured IDE for vim. It comes with quite a few of the best sub-vundles already built in. And works on Windows and Macintoshes just as it does on Linux. However it totally changes vim the look of vim and removes the modifications you may already be comfortable with. When finished installing your vim will look nothing like anything you may have been comfortable with before.

Take the install script and copy it into a file. Run that file. Be prepared to spend hours learning the new tools!

February 18, 2013

Tutorial On Automatically Moving Home To Ram Drive And Back On Startup And Shutdown

Filed under: bash, howto, laptop, Linux, mint 14 xfce, rsync, SSD, tutorial, ubuntu — ioconnor @ 6:36 pm

This posting is meant to compliment the “Linux Mint 14 SSD Settings” and “The Best Linux Directory Structure?“posting. The idea is to move the home directory automatically at start up and shutdown to and from the ram disk. If you are using a ram disk then your computer is very fast. Possibly more importantly you are not wearing out your hard disk or SSD because all the applications that would normally write willy-nilly to the home directory are now fooled into RAM. If you don’t have the computer automatically doing these steps you might forget. So have the computer do them for you!

Firstly everybody should know how to recover in case during boot up the home directory is pointing to a non existent directory. You’ll need to boot up from a USB stick and follow these steps which I do so often I’m pulling them from memory:

  1. sudo mkdir /blah
  2. sudo mount /dev/sda1 /blah
  3. cd /blah/home
  4. sudo rm you
  5. sudo ln -s base you
  6. sudo shutdown -h now

Secondly make a log file in the home directory since this is all about mucking with the home directory

  1. sudo touch /home/log
  2. sudo chmod 777 /home/log

Thirdly follow the directions for /etc/fstab found in my “Linux Mint 14 SSD Settings” posting. I would follow all of the directions there, even for /etc/rc.local, whether or not you have a SSD drive.

Fourthly add the following code which will copy the ram drive back to the hard disk when the computer shutsdown.

Make a file called /etc/init.d/diskhome.sh and put in it something like the following but change the username:

#!/bin/sh

ivorPrintAndLog() {
tStamp=$(date +%Y-%m-%d@%T)
echo “$tStamp $1”
echo “$tStamp $1” >> /home/log
}

argUser=”ivor”
fUserOnDisk=$(ls -l /home | grep “$argUser -> base”)
#echo “fUserOnDisk: ‘$fUserOnDisk'”
fUserOnRam=$(ls -l /home | grep “$argUser -> /tmp/”)
#echo “fUserOnRam: ‘$fUserOnRam'”

if [ “$fUserOnDisk” ]; then
if [ “$fUserOnRam” ]; then # On disk and ram!
sOut=”Script needs fixing because it reports ‘$argUser’ has home on both ram and disk.”
else # On disk but not ram
sOut=”User ‘$argUser’ is already residing on disk so nothing to do.”
fi
else
if [ “$fUserOnRam” ]; then # Not disk but ram
sOut=”Moving ram contents for user: ‘$argUser’ to disk.”
ivorPrintAndLog “$sOut”
rsync -av –delete /tmp/home/base /home
cd /home
sudo rm $argUser
sudo ln -s base $argUser
cd –
sOut=”Moved information to disk successfully”
else # Not disk and not ram
sOut=”Error with script: User: ‘$argUser’ is not on disk or ram.”
fi
fi

ivorPrintAndLog “$sOut”

Make it executable and put links to it from the appropriate places

chmod +x /etc/init.d
cd /etc/rc0.d
sudo ln -s ../init.d/diskhome.sh K99diskhome.sh
cd ../rc6.d
sudo ln -s ../init.d/diskhome.sh K99diskhome.sh

Fifthly update /etc/rc.local so it copies the home directory to ram by adding the following lines into the /etc/rc.local

ivorPrintAndLog() {
tStamp=$(date +%Y-%m-%d@%T)
echo “$tStamp $1”
echo “$tStamp $1” >> /home/log
}

argUser=”ivor”
fUserOnDisk=$(ls -l /home | grep “$argUser -> base”)
echo “fUserOnDisk: ‘$fUserOnDisk'”
#fUserOnRam=$(ls -l /home | grep “$argUser -> /tmp/”)
echo “fUserOnRam: ‘$fUserOnRam'”

blah() {
if [ “$fUserOnDisk” ]; then
if [ “$fUserOnRam” ]; then # On disk and ram!
sOut=”Script needs fixing because it reports ‘$argUser’ has home on both ram and disk.”
else # On disk but not ram
sOut=”Moving disk contents for user: ‘$argUser’ to ram.”
ivorPrintAndLog “$sOut”
rsync -av /home/base /tmp/home
cd /home
sudo rm $argUser
sudo ln -s /tmp/home/base $argUser
cd –
sOut=”Moved information to ram successfully”
fi
else
if [ “$fUserOnRam” ]; then # Not disk but ram
sOut=”User ‘$argUser’ is already residing in ram so nothing to do.”
else # Not disk and not ram
sOut=”Error with script: User: ‘$argUser’ is not on disk or ram.”
fi
fi
ivorPrintAndLog “$sOut”
}

blah

Finally, the sixth step, rename your home directory to “base” and put a link to it. In my case:

    1. sudo mv ivor base
    2. sudo ln -s base ivor

That is all there is to it. The next time you reboot you should find your home directory on the tmp ram drive. Now there are a few problems. Like your home directory is too large. Or you would like to manually backup. The following commands may help:

    1. cd; du -h | sort -h
      Figure out how much space your home directory is using
    2. cd; sudo mkdir /home/Downloads; chmod 777 /home/Downloads; mv Downloads/* /home/downloads/; rm Downloads; ln -s /home/Downloads Downloads
      Basically just moving your Downloads directory which is probably rarely used to another place so it is not copied on to the ram disk. Maybe there are other directories that could also be moved because they take up lots of space and rarely get used. Like pictures, music, etc..
    3. Periodically check your ram disk usage. Mine is usually under 1GB which is less than 50% of it’s capability. (The RAM drives default to half your installed ram and the assumption is you have 4 GBs or more of RAM on your system.)
      df -h
    4. Verify everything is working:
      ls -l /home # Your home drive should be a link pointing to the ram drive.
    5. cat /home/log
      #Your log file should show the files were copied on startup and shutdown.
    6. Backup your ram drive from time to time using the bold red line above. Maybe even make it into an alias like this:
      echo ‘alias bkup=”rsync -av –delete /tmp/home/base /home”‘ >> ~/.bashrc

I’ve used these steps on a few computers and they work for me. However if you run into problems let me know and I’ll update this with the fixes.

February 7, 2013

vundle

Filed under: bash, css, git, html5, JavaScript, Linux, pdo, php, vim, vundle — ioconnor @ 12:36 pm

Vundle is the new package manager for vim plugins. I’m thinking it will be largely responsible for making a resurgence in the use of vim because it allows clean installs of IDE tools for various environments. Allowing easy file navigation, editing, compiling, debugging, and all the other things you might want to do. However vundle is new and largely unknown. Take a look for it in any vim book and you won’t find it. This post will be continuously updated until it has the information I find useful and need on a routine basis. My first effort will be in setting up an environment for PHP, javascript, html, css, bash, c/c++, git, pdo, and mysql/sqlite3 development. So I’m thinking there will probably be a flurry of updates to this post over the next few months.

First off auto installing vundle. I stole the following from this site but had to remove the EOL comments to make it work. Make a copy of your existing “.vimrc” and then add the following to the end of your .vimrc file:

" Setting up Vundle - the vim plugin bundler
let iCanHazVundle=1
let vundle_readme=expand('~/.vim/bundle/vundle/README.md')
if !filereadable(vundle_readme)
echo "Installing Vundle.."
echo ""
silent !mkdir -p ~/.vim/bundle
silent !git clone https://github.com/gmarik/vundle ~/.vim/bundle/vundle
let iCanHazVundle=0
endif
set rtp+=~/.vim/bundle/vundle/
call vundle#rc()
Bundle 'gmarik/vundle'
"Add your bundles here
Bundle 'Syntastic'
Bundle 'altercation/vim-colors-solarized'
Bundle 'https://github.com/tpope/vim-fugitive'
"...All your other bundles...
if iCanHazVundle == 0
echo "Installing Bundles, please ignore key map error messages"
echo ""
:BundleInstall
endif
" Setting up Vundle - the vim plugin bundler end

Then type in to vim “:BundleInstall!” and watch it install before restarting vim.

2013-02-08 UPDATE: Interesting links:

April 16, 2010

Best “diff” utility?

Filed under: bash, diff, git, sdiff, vim — Tags: , , , — ioconnor @ 3:47 pm

I was noticing two files were containing the same information earlier and I wanted to compare them. Without thinking I did a diff on them. Then I got to thinking there must be more visual diffs. Git for instance. With all the diffs they do their it must be very nice. Unfortunately when I looked at git diff it seemed to only work for versions of the same file. If this is not the case please correct me. I then tried vimdiff. It’s nice but the default color scheme is not workable and I did not want to spend an hour playing with it. (Why don’t the vim folk make a nice little popup that lets you modify colors easily. DUH!) So then I used sdiff. sdiff seems to work most intuitively but it’s ancient.

Anybody have better solutions?

January 25, 2010

Navigating Log Files With VIM

Filed under: bash, cli, howto, Linux, tutorial, vi — ioconnor @ 6:40 pm

One of the main problems with VI, VIM and GVIM is the navigation between multiple files. The “:n” and “:rew” commands may get somebody through the basics. But seriously it’s not enough. The secret is writing little macros for the work being done. Often this is such a daunting task that most people haven’t got a clue. So hence this article. The idea presented here is to show how to make a navigation file so that once the cursor is over the file name in question, or information needed to identify the file, two keystrokes will take you to that file.

First there is the ~/.vimrc file or equivalent depending on the OS. Locate it. Add to this file the macros.

:map ** “zyy:@z<Enter>

This command maps the keystrokes “**”, the two asterisks hit in rapid succession, to the commands that follow it. The command that follows reads the line the cursor is on into the z buffer and then executes that buffer. This is very useful because now the commands you want to test can be written on a line and then executed by pressing “**”. It opens the world of macros to you.

So lets write a macro that will bounce the window between the current file and the last file you edited. Say you started gvim by typing gvim file1 file2 file3 and once in file1 you then typed :n and :n again. So you are now in file2. The goal of this macro is to let you move to file2 without doing a “:rew” and “:n”. So start a new line in file 3 and type in:

:map *; :e#<Enter>

Then press “**” over the line so this macro becomes available. Now if you press “*;” you’ll go to file2.

Now we are ready to write some macros to view log like files. I’ll start with the one I wrote yesterday. Websites require a file named “Sitemap.xml” which describes each file’s location, importance, and frequency they should be crawled by the search spiders. Each line has a format similar to this:

<url><loc>http://www.domain-name.com/index.html</loc><priority>0.50</priority><changefreq>weekly</changefreq></url&gt;

Three macros might be all that is needed to navigate a website via its Sitemap.xml. File navigation this way ensures the Sitemap.xml always stays relevant. So the first macro might be something like:

:map *S :e ~/path/Sitemap.xml<Enter>

This is simple enough to understand. When “*S” is typed it will take you to the Sitemap.xml file.

Now the following is all that is needed to edit the files listed in the Sitemap.xml by putting the cursor on the line containing the file and typing “*e”:

:map *e :w<Enter>$0fhf<mz0fml”ay`zo:e ~/path-to-website/<Esc>”ap<Esc>”zyyu:@z<Enter>

First the file is written out with this command “:w<Enter>”. Depending on your habits you may want to remove that.
Then the cursor is moved to the end of the line and then to the beginning with “$0”. There is history to this that is wasted on VIM/GVIM.
Then a search for the ‘h’ in “http” is done, to get to the start of the URL, with “fh” and then another search for the end of the URL with “f<”
Then that location is marked as location “z” with the command “mz”. Then we go back to the start of the file name which for my Sitemaps can be done for searching for the “m” in com. You may have to vary the search depending on your domain name. Then moving the cursor over to the “/”. So altogether it’s “0fml”.
Now yank the name of the file into the a buffer using the backwards tick “”ay`z”.
Now create a line with the command needed to edit the file just yanked “o:e ~/path-to-website/<Esc>”ap<Esc>”
Finally yank the newly created line into the z buffer, undo the line just created, and then execute the z buffer so the editor is now editing the file “”zyyu:@z<Enter>”

The next command sets the browser to the file in question:

:map *b :w<Enter>$0fhf<mz0fh”ay`zo:!gnome-open <Esc>”ap<Esc>”zyyu:@z<Enter>

These techniques can be used for almost anything to avoid typing names. In fact a list of all files you edit, in a centralized place, is all that’s needed to prevent ever repeatedly typing out a file name again. Once familiar with these techniques most of the files needing editing can be gotten to with two key strokes. This gives VI, VIM, and GVIM the ability to navigate files more easily than an IDE without losing all the power you surrender when using an IDE. And it’s all free!

May 7, 2009

How To Install Jslint on Ubuntu

Filed under: bash, cli, debugging, howto, JavaScript, Lint, Linux, tutorial, ubuntu — Tags: , , , , , , — ioconnor @ 5:30 pm

At my entry https://ioconnor.wordpress.com/2009/04/24/javascript-testing/ you’ll notice there are two entirely different lint programs out there for JavaScript. I installed and made an entry on how to install JavaScript Lint here. This posting describes how to install the other version of lint, jslint, under ubuntu. I even tested it under Ubuntu 8.04 and 9.04. Follow these steps:

  1. sudo mkdir -p /my/bin
    I prefer not to much around in the home directory but to create all custom stuff right off the root so I know what is mine. You can choose some other directory if you’d like.
  2. cd /my/bin
  3. sudo wget http://www.jslint.com/rhino/jslint.js
    If they ever remove this send me a mssage and I’ll post it.
  4. sudo chmod a+x jslint.js
    Not sure if this is needed but it’s habit…
  5. sudo apt-get install rhino
    I did not have rhino installed on 9.04 but it does not hurt to verify with this command.
  6. time rhino jslint.js jslint.js
    jslint is written in javascript. So run it on itself to see if there are any errors or warnings.

That’s pretty simple. Too bad their website does not make it simple. In fact their website does not contain enough information. I had to google about for a while to figure it all out. Anyways here is the output when ran on itself. Then further down I use the other lint program on it.

JSLint does allow options. I am going to at some point see if I can make an include file that will specify just the options I want.

JSLint also has a good section on coding standards. I like it.

time rhino /my/bin/jslint.js /my/bin/jslint.js
Lint at line 4 character 236: eval is evil.
“use strict”;JSLINT=(function(){var adsafe_id,adsafe_may,adsafe_went,anonname,approved,atrule={‘import’:true,media:true,’font-face’:true,page:true},banned={apply:true,’arguments’:true,call:true,callee:true,caller:true,constructor:true,’eval’:true,prototype:true,unwatch:true,valueOf:true,watch:true},boolOptions={adsafe:true,bitwise:true,browser:true,cap:true,css:true,debug:true,eqeqeq:true,evil:true,forin:true,fragment:true,immed:true,laxbreak:true,newcap:true,nomen:true,on:true,onevar:true,passfail:true,plusplus:true,regexp:true,rhino:true,undef:true,safe:true,sidebar:true,strict:true,sub:true,white:true,widget:true},browser={alert:true,blur:true,clearInterval:true,clearTimeout:true,close:true,closed:true,confirm:true,console:true,Debug:true,defaultStatus:true,document:true,event:true,focus:true,frames:true,getComputedStyle:true,history:true,Image:true,length:true,location:true,moveBy:true,moveTo:true,name:true,navigator:true,onblur:true,onerror:true,onfocus:true,onload:true,onresize:true,onunload:true,open:true,opener:true,opera:true,Option:true,parent:true,print:true,prompt:true,resizeBy:true,resizeTo:true,screen:true,scroll:true,scrollBy:true,scrollTo:true,setInterval:true,setTimeout:true,status:true,top:true,XMLHttpRequest:true},cssAttributeData,cssAny,cssColorData={“aliceblue”:true,”antiquewhite”:true,”aqua”:true,”aquamarine”:true,”azure”:true,”beige”:true,”bisque”:true,”black”:true,”blanchedalmond”:true,”blue”:true,”blueviolet”:true,”brown”:true,”burlywood”:true,”cadetblue”:true,”chartreuse”:true,”chocolate”:true,”coral”:true,”cornflowerblue”:true,”cornsilk”:true,”crimson”:true,”cyan”:true,”darkblue”:true,”darkcyan”:true,”darkgoldenrod”:true,”darkgray”:true,”darkgreen”:true,”darkkhaki”:true,”darkmagenta”:true,”darkolivegreen”:true,”darkorange”:true,”darkorchid”:true,”darkred”:true,”darksalmon”:true,”darkseagreen”:true,”darkslateblue”:true,”darkslategray”:true,”darkturquoise”:true,”darkviolet”:true,”deeppink”:true,”deepskyblue”:true,”dimgray”:true,”dodgerblue”:true,”firebrick”:true,”floralwhite”:true,”forestgreen”:true,”fuchsia”:true,”gainsboro”:true,”ghostwhite”:true,”gold”:true,”goldenrod”:true,”gray”:true,”green”:true,”greenyellow”:true,”honeydew”:true,”hotpink”:true,”indianred”:true,”indigo”:true,”ivory”:true,”khaki”:true,”lavender”:true,”lavenderblush”:true,”lawngreen”:true,”lemonchiffon”:true,”lightblue”:true,”lightcoral”:true,”lightcyan”:true,”lightgoldenrodyellow”:true,”lightgreen”:true,”lightpink”:true,”lightsalmon”:true,”lightseagreen”:true,”lightskyblue”:true,”lightslategray”:true,”lightsteelblue”:true,”lightyellow”:true,”lime”:true,”limegreen”:true,”linen”:true,”magenta”:true,”maroon”:true,”mediumaquamarine”:true,”mediumblue”:true,”mediumorchid”:true,”mediumpurple”:true,”mediumseagreen”:true,”mediumslateblue”:true,”mediumspringgreen”:true,”mediumturquoise”:true,”mediumvioletred”:true,”midnightblue”:true,”mintcream”:true,”mistyrose”:true,”moccasin”:true,”navajowhite”:true,”navy”:true,”oldlace”:true,”olive”:true,”olivedrab”:true,”orange”:true,”orangered”:true,”orchid”:true,”palegoldenrod”:true,”palegreen”:true,”paleturquoise”:true,”palevioletred”:true,”papayawhip”:true,”peachpuff”:true,”peru”:true,”pink”:true,”plum”:true,”powderblue”:true,”purple”:true,”red”:true,”rosybrown”:true,”royalblue”:true,”saddlebrown”:true,”salmon”:true,”sandybrown”:true,”seagreen”:true,”seashell”:true,”sienna”:true,”silver”:true,”skyblue”:true,”slateblue”:true,”slategray”:true,”snow”:true,”springgreen”:true,”steelblue”:true,”tan”:true,”teal”:true,”thistle”:true,”tomato”:true,”turquoise”:true,”violet”:true,”wheat”:true,”white”:true,”whitesmoke”:true,”yellow”:true,”yellowgreen”:true},cssBorderStyle,cssLengthData={‘%’:true,’cm’:true,’em’:true,’ex’:true,’in’:true,’mm’:true,’pc’:true,’pt’:true,’px’:true},escapes={‘\b’:’\\b’,’\t’:’\\t’,’\n’:’\\n’,’\f’:’\\f’,’\r’:’\\r’,'”‘:’\\”‘,’/’:’\\/’,’\\’:’\\\\’},funct,functions,global,htmltag={a:{},abbr:{},acronym:{},address:{},applet:{},area:{empty:true,parent:’ map ‘},b:{},base:{empty:true,parent:’ head ‘},bdo:{},big:{},blockquote:{},body:{parent:’ html noframes ‘},br:{empty:true},button:{},canvas:{parent:’ body p div th td ‘},caption:{parent:’ table ‘},center:{},cite:{},code:{},col:{empty:true,parent:’ table colgroup ‘},colgroup:{parent:’ table ‘},dd:{parent:’ dl ‘},del:{},dfn:{},dir:{},div:{},dl:{},dt:{parent:’ dl ‘},em:{},embed:{},fieldset:{},font:{},form:{},frame:{empty:true,parent:’ frameset ‘},frameset:{parent:’ html frameset ‘},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{parent:’ html ‘},html:{parent:’*’},hr:{empty:true},i:{},iframe:{},img:{empty:true},input:{empty:true},ins:{},kbd:{},label:{},legend:{parent:’ fieldset ‘},li:{parent:’ dir menu ol ul ‘},link:{empty:true,parent:’ head ‘},map:{},menu:{},meta:{empty:true,parent:’ head noframes noscript ‘},noframes:{parent:’ html body ‘},noscript:{parent:’ body head noframes ‘},object:{},ol:{},optgroup:{parent:’ select ‘},option:{parent:’ optgroup select ‘},p:{},param:{empty:true,parent:’ applet object ‘},pre:{},q:{},samp:{},script:{empty:true,parent:’ body div frame head iframe p pre span ‘},select:{},small:{},span:{},strong:{},style:{parent:’ head ‘,empty:true},sub:{},sup:{},table:{},tbody:{parent:’ table ‘},td:{parent:’ tr ‘},textarea:{},tfoot:{parent:’ table ‘},th:{parent:’ tr ‘},thead:{parent:’ table ‘},title:{parent:’ head ‘},tr:{parent:’ table tbody thead tfoot ‘},tt:{},u:{},ul:{},’var’:{}},ids,implied,inblock,indent,jsonmode,lines,lookahead,member,membersOnly,nexttoken,noreach,option,predefined,prereg,prevtoken,pseudorule={‘first-child’:true,link:true,visited:true,hover:true,active:true,focus:true,lang:true,’first-letter’:true,’first-line’:true,before:true,after:true},rhino={defineClass:true,deserialize:true,gc:true,help:true,load:true,loadClass:true,print:true,quit:true,readFile:true,readUrl:true,runCommand:true,seal:true,serialize:true,spawn:true,sync:true,toint32:true,version:true},scope,sidebar={System:true},src,stack,standard={Array:true,Boolean:true,Date:true,decodeURI:true,decodeURIComponent:true,encodeURI:true,encodeURIComponent:true,Error:true,’eval’:true,EvalError:true,Function:true,isFinite:true,isNaN:true,JSON:true,Math:true,Number:true,Object:true,parseInt:true,parseFloat:true,RangeError:true,ReferenceError:true,RegExp:true,String:true,SyntaxError:true,TypeError:true,URIError:true},standard_member={E:true,LN2:true,LN10:true,LOG2E:true,LOG10E:true,PI:true,SQRT1_2:true,SQRT2:true,MAX_VALUE:true,MIN_VALUE:true,NEGATIVE_INFINITY:true,POSITIVE_INFINITY:true},syntax={},tab,token,urls,warnings,widget={alert:true,animator:true,appleScript:true,beep:true,bytesToUIString:true,Canvas:true,chooseColor:true,chooseFile:true,chooseFolder:true,closeWidget:true,COM:true,convertPathToHFS:true,convertPathToPlatform:true,CustomAnimation:true,escape:true,FadeAnimation:true,filesystem:true,Flash:true,focusWidget:true,form:true,FormField:true,Frame:true,HotKey:true,Image:true,include:true,isApplicationRunning:true,iTunes:true,konfabulatorVersion:true,log:true,md5:true,MenuItem:true,MoveAnimation:true,openURL:true,play:true,Point:true,popupMenu:true,preferenceGroups:true,preferences:true,print:true,prompt:true,random:true,Rectangle:true,reloadWidget:true,ResizeAnimation:true,resolvePath:true,resumeUpdates:true,RotateAnimation:true,runCommand:true,runCommandInBg:true,saveAs:true,savePreferences:true,screen:true,ScrollBar:true,showWidgetPreferences:true,sleep:true,speak:true,Style:true,suppressUpdates:true,system:true,tellWidget:true,Text:true,TextArea:true,Timer:true,unescape:true,updateNow:true,URL:true,Web:true,widget:true,Window:true,XMLDOM:true,XMLHttpRequest:true,yahooCheckLogin:true,yahooLogin:true,yahooLogout:true},xmode,xquote,ax=/@cc|<\/?|script|\]*s\]|<\s*!|&lt/i,cx=/[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,tx=/^\s*([(){}\[.,:;'”~\?\]#@]|==?=?|\/(\*(global|extern|jslint|member|members)?|=|\/)?|\*[\/=]?|\+[+=]?|-[\-=]?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|–)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,hx=/^\s*([‘”=>\/&#]|<(?:\/|\!(?:–)?)?|[a-zA-Z][a-zA-Z0-9_\-]*|[0-9]+|–|.)/,nx=/[\u0000-\u001f&<“\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,nxg=/[\u0000-\u001f&<“\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,ox=/[>&]|<[\/!]?|–/,lx=/\*\/|\/\*/,ix=/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,jx=/^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,ux=/&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i,sx=/^\s*([{:#*%.=,>+\[\]@()”‘;*]|[a-zA-Z0-9_][a-zA-Z0-9_\-]*|<\/|\/\*)/,ssx=/^\s*([@#!”‘};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/,qx=/[^a-zA-Z0-9-_\/ ]/,dx=/[\[\]\/\\”‘*<>.&:(){}+=#]/,rx={outer:hx,html:hx,style:sx,styleproperty:ssx};function F(){}

Lint at line 4 character 6051: eval is evil.
“use strict”;JSLINT=(function(){var adsafe_id,adsafe_may,adsafe_went,anonname,approved,atrule={‘import’:true,media:true,’font-face’:true,page:true},banned={apply:true,’arguments’:true,call:true,callee:true,caller:true,constructor:true,’eval’:true,prototype:true,unwatch:true,valueOf:true,watch:true},boolOptions={adsafe:true,bitwise:true,browser:true,cap:true,css:true,debug:true,eqeqeq:true,evil:true,forin:true,fragment:true,immed:true,laxbreak:true,newcap:true,nomen:true,on:true,onevar:true,passfail:true,plusplus:true,regexp:true,rhino:true,undef:true,safe:true,sidebar:true,strict:true,sub:true,white:true,widget:true},browser={alert:true,blur:true,clearInterval:true,clearTimeout:true,close:true,closed:true,confirm:true,console:true,Debug:true,defaultStatus:true,document:true,event:true,focus:true,frames:true,getComputedStyle:true,history:true,Image:true,length:true,location:true,moveBy:true,moveTo:true,name:true,navigator:true,onblur:true,onerror:true,onfocus:true,onload:true,onresize:true,onunload:true,open:true,opener:true,opera:true,Option:true,parent:true,print:true,prompt:true,resizeBy:true,resizeTo:true,screen:true,scroll:true,scrollBy:true,scrollTo:true,setInterval:true,setTimeout:true,status:true,top:true,XMLHttpRequest:true},cssAttributeData,cssAny,cssColorData={“aliceblue”:true,”antiquewhite”:true,”aqua”:true,”aquamarine”:true,”azure”:true,”beige”:true,”bisque”:true,”black”:true,”blanchedalmond”:true,”blue”:true,”blueviolet”:true,”brown”:true,”burlywood”:true,”cadetblue”:true,”chartreuse”:true,”chocolate”:true,”coral”:true,”cornflowerblue”:true,”cornsilk”:true,”crimson”:true,”cyan”:true,”darkblue”:true,”darkcyan”:true,”darkgoldenrod”:true,”darkgray”:true,”darkgreen”:true,”darkkhaki”:true,”darkmagenta”:true,”darkolivegreen”:true,”darkorange”:true,”darkorchid”:true,”darkred”:true,”darksalmon”:true,”darkseagreen”:true,”darkslateblue”:true,”darkslategray”:true,”darkturquoise”:true,”darkviolet”:true,”deeppink”:true,”deepskyblue”:true,”dimgray”:true,”dodgerblue”:true,”firebrick”:true,”floralwhite”:true,”forestgreen”:true,”fuchsia”:true,”gainsboro”:true,”ghostwhite”:true,”gold”:true,”goldenrod”:true,”gray”:true,”green”:true,”greenyellow”:true,”honeydew”:true,”hotpink”:true,”indianred”:true,”indigo”:true,”ivory”:true,”khaki”:true,”lavender”:true,”lavenderblush”:true,”lawngreen”:true,”lemonchiffon”:true,”lightblue”:true,”lightcoral”:true,”lightcyan”:true,”lightgoldenrodyellow”:true,”lightgreen”:true,”lightpink”:true,”lightsalmon”:true,”lightseagreen”:true,”lightskyblue”:true,”lightslategray”:true,”lightsteelblue”:true,”lightyellow”:true,”lime”:true,”limegreen”:true,”linen”:true,”magenta”:true,”maroon”:true,”mediumaquamarine”:true,”mediumblue”:true,”mediumorchid”:true,”mediumpurple”:true,”mediumseagreen”:true,”mediumslateblue”:true,”mediumspringgreen”:true,”mediumturquoise”:true,”mediumvioletred”:true,”midnightblue”:true,”mintcream”:true,”mistyrose”:true,”moccasin”:true,”navajowhite”:true,”navy”:true,”oldlace”:true,”olive”:true,”olivedrab”:true,”orange”:true,”orangered”:true,”orchid”:true,”palegoldenrod”:true,”palegreen”:true,”paleturquoise”:true,”palevioletred”:true,”papayawhip”:true,”peachpuff”:true,”peru”:true,”pink”:true,”plum”:true,”powderblue”:true,”purple”:true,”red”:true,”rosybrown”:true,”royalblue”:true,”saddlebrown”:true,”salmon”:true,”sandybrown”:true,”seagreen”:true,”seashell”:true,”sienna”:true,”silver”:true,”skyblue”:true,”slateblue”:true,”slategray”:true,”snow”:true,”springgreen”:true,”steelblue”:true,”tan”:true,”teal”:true,”thistle”:true,”tomato”:true,”turquoise”:true,”violet”:true,”wheat”:true,”white”:true,”whitesmoke”:true,”yellow”:true,”yellowgreen”:true},cssBorderStyle,cssLengthData={‘%’:true,’cm’:true,’em’:true,’ex’:true,’in’:true,’mm’:true,’pc’:true,’pt’:true,’px’:true},escapes={‘\b’:’\\b’,’\t’:’\\t’,’\n’:’\\n’,’\f’:’\\f’,’\r’:’\\r’,'”‘:’\\”‘,’/’:’\\/’,’\\’:’\\\\’},funct,functions,global,htmltag={a:{},abbr:{},acronym:{},address:{},applet:{},area:{empty:true,parent:’ map ‘},b:{},base:{empty:true,parent:’ head ‘},bdo:{},big:{},blockquote:{},body:{parent:’ html noframes ‘},br:{empty:true},button:{},canvas:{parent:’ body p div th td ‘},caption:{parent:’ table ‘},center:{},cite:{},code:{},col:{empty:true,parent:’ table colgroup ‘},colgroup:{parent:’ table ‘},dd:{parent:’ dl ‘},del:{},dfn:{},dir:{},div:{},dl:{},dt:{parent:’ dl ‘},em:{},embed:{},fieldset:{},font:{},form:{},frame:{empty:true,parent:’ frameset ‘},frameset:{parent:’ html frameset ‘},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{parent:’ html ‘},html:{parent:’*’},hr:{empty:true},i:{},iframe:{},img:{empty:true},input:{empty:true},ins:{},kbd:{},label:{},legend:{parent:’ fieldset ‘},li:{parent:’ dir menu ol ul ‘},link:{empty:true,parent:’ head ‘},map:{},menu:{},meta:{empty:true,parent:’ head noframes noscript ‘},noframes:{parent:’ html body ‘},noscript:{parent:’ body head noframes ‘},object:{},ol:{},optgroup:{parent:’ select ‘},option:{parent:’ optgroup select ‘},p:{},param:{empty:true,parent:’ applet object ‘},pre:{},q:{},samp:{},script:{empty:true,parent:’ body div frame head iframe p pre span ‘},select:{},small:{},span:{},strong:{},style:{parent:’ head ‘,empty:true},sub:{},sup:{},table:{},tbody:{parent:’ table ‘},td:{parent:’ tr ‘},textarea:{},tfoot:{parent:’ table ‘},th:{parent:’ tr ‘},thead:{parent:’ table ‘},title:{parent:’ head ‘},tr:{parent:’ table tbody thead tfoot ‘},tt:{},u:{},ul:{},’var’:{}},ids,implied,inblock,indent,jsonmode,lines,lookahead,member,membersOnly,nexttoken,noreach,option,predefined,prereg,prevtoken,pseudorule={‘first-child’:true,link:true,visited:true,hover:true,active:true,focus:true,lang:true,’first-letter’:true,’first-line’:true,before:true,after:true},rhino={defineClass:true,deserialize:true,gc:true,help:true,load:true,loadClass:true,print:true,quit:true,readFile:true,readUrl:true,runCommand:true,seal:true,serialize:true,spawn:true,sync:true,toint32:true,version:true},scope,sidebar={System:true},src,stack,standard={Array:true,Boolean:true,Date:true,decodeURI:true,decodeURIComponent:true,encodeURI:true,encodeURIComponent:true,Error:true,’eval’:true,EvalError:true,Function:true,isFinite:true,isNaN:true,JSON:true,Math:true,Number:true,Object:true,parseInt:true,parseFloat:true,RangeError:true,ReferenceError:true,RegExp:true,String:true,SyntaxError:true,TypeError:true,URIError:true},standard_member={E:true,LN2:true,LN10:true,LOG2E:true,LOG10E:true,PI:true,SQRT1_2:true,SQRT2:true,MAX_VALUE:true,MIN_VALUE:true,NEGATIVE_INFINITY:true,POSITIVE_INFINITY:true},syntax={},tab,token,urls,warnings,widget={alert:true,animator:true,appleScript:true,beep:true,bytesToUIString:true,Canvas:true,chooseColor:true,chooseFile:true,chooseFolder:true,closeWidget:true,COM:true,convertPathToHFS:true,convertPathToPlatform:true,CustomAnimation:true,escape:true,FadeAnimation:true,filesystem:true,Flash:true,focusWidget:true,form:true,FormField:true,Frame:true,HotKey:true,Image:true,include:true,isApplicationRunning:true,iTunes:true,konfabulatorVersion:true,log:true,md5:true,MenuItem:true,MoveAnimation:true,openURL:true,play:true,Point:true,popupMenu:true,preferenceGroups:true,preferences:true,print:true,prompt:true,random:true,Rectangle:true,reloadWidget:true,ResizeAnimation:true,resolvePath:true,resumeUpdates:true,RotateAnimation:true,runCommand:true,runCommandInBg:true,saveAs:true,savePreferences:true,screen:true,ScrollBar:true,showWidgetPreferences:true,sleep:true,speak:true,Style:true,suppressUpdates:true,system:true,tellWidget:true,Text:true,TextArea:true,Timer:true,unescape:true,updateNow:true,URL:true,Web:true,widget:true,Window:true,XMLDOM:true,XMLHttpRequest:true,yahooCheckLogin:true,yahooLogin:true,yahooLogout:true},xmode,xquote,ax=/@cc|<\/?|script|\]*s\]|<\s*!|&lt/i,cx=/[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,tx=/^\s*([(){}\[.,:;'”~\?\]#@]|==?=?|\/(\*(global|extern|jslint|member|members)?|=|\/)?|\*[\/=]?|\+[+=]?|-[\-=]?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|–)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,hx=/^\s*([‘”=>\/&#]|<(?:\/|\!(?:–)?)?|[a-zA-Z][a-zA-Z0-9_\-]*|[0-9]+|–|.)/,nx=/[\u0000-\u001f&<“\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,nxg=/[\u0000-\u001f&<“\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,ox=/[>&]|<[\/!]?|–/,lx=/\*\/|\/\*/,ix=/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,jx=/^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,ux=/&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i,sx=/^\s*([{:#*%.=,>+\[\]@()”‘;*]|[a-zA-Z0-9_][a-zA-Z0-9_\-]*|<\/|\/\*)/,ssx=/^\s*([@#!”‘};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/,qx=/[^a-zA-Z0-9-_\/ ]/,dx=/[\[\]\/\\”‘*<>.&:(){}+=#]/,rx={outer:hx,html:hx,style:sx,styleproperty:ssx};function F(){}

Lint at line 119 character 36: eval is evil.
if(!option.evil&&nexttoken.value===’eval’){warning(“eval is evil.”,nexttoken);}}

Lint at line 350 character 604: eval is evil.
return this;},led:function(){error(“Expected an operator and instead saw ‘{a}’.”,nexttoken,nexttoken.value);}};type(‘(regexp)’,function(){return this;});delim(‘(endline)’);delim(‘(begin)’);delim(‘(end)’).reach=true;delim(‘</’).reach=true;delim(‘<!’);delim(‘<!–‘);delim(‘–>’);delim(‘(error)’).reach=true;delim(‘}’).reach=true;delim(‘)’);delim(‘]’);delim(‘”‘).reach=true;delim(“‘”).reach=true;delim(‘;’);delim(‘:’).reach=true;delim(‘,’);delim(‘#’);delim(‘@’);reserve(‘else’);reserve(‘case’).reach=true;reserve(‘catch’);reserve(‘default’).reach=true;reserve(‘finally’);reservevar(‘arguments’);reservevar(‘eval’);reservevar(‘false’);reservevar(‘Infinity’);reservevar(‘NaN’);reservevar(‘null’);reservevar(‘this’);reservevar(‘true’);reservevar(‘undefined’);assignop(‘=’,’assign’,20);assignop(‘+=’,’assignadd’,20);assignop(‘-=’,’assignsub’,20);assignop(‘*=’,’assignmult’,20);assignop(‘/=’,’assigndiv’,20).nud=function(){error(“A regular expression literal can be confused with ‘/=’.”);};assignop(‘%=’,’assignmod’,20);bitwiseassignop(‘&=’,’assignbitand’,20);bitwiseassignop(‘|=’,’assignbitor’,20);bitwiseassignop(‘^=’,’assignbitxor’,20);bitwiseassignop(‘<<=’,’assignshiftleft’,20);bitwiseassignop(‘>>=’,’assignshiftright’,20);bitwiseassignop(‘>>>=’,’assignshiftrightunsigned’,20);infix(‘?’,function(left,that){that.left=left;that.right=parse(10);advance(‘:’);that[‘else’]=parse(10);return that;},30);infix(‘||’,’or’,40);infix(‘&&’,’and’,50);bitwise(‘|’,’bitor’,70);bitwise(‘^’,’bitxor’,80);bitwise(‘&’,’bitand’,90);relation(‘==’,function(left,right){if(option.eqeqeq){warning(“Expected ‘{a}’ and instead saw ‘{b}’.”,this,’===’,’==’);}else if(isPoorRelation(left)){warning(“Use ‘{a}’ to compare with ‘{b}’.”,this,’===’,left.value);}else if(isPoorRelation(right)){warning(“Use ‘{a}’ to compare with ‘{b}’.”,this,’===’,right.value);}

Lint at line 373 character 34: eval is evil.
if(!option.evil){if(left.value===’eval’||left.value===’Function’||left.value===’execScript’){warning(“eval is evil.”,left);}else if(p[0]&&p[0].id==='(string)’&&(left.value===’setTimeout’||left.value===’setInterval’)){warning(“Implied eval is evil. Pass a function instead of a string.”,left);}}

Lint at line 445 character 248: eval is evil.
if(o.safe){o.browser=false;o.css=false;o.debug=false;o.eqeqeq=true;o.evil=false;o.forin=false;o.nomen=true;o.on=false;o.rhino=false;o.safe=true;o.sidebar=false;o.strict=true;o.sub=false;o.undef=true;o.widget=false;predefined.Date=false;predefined[‘eval’]=false;predefined.Function=false;predefined.Object=false;predefined.ADSAFE=true;predefined.lib=true;}

real    1m52.358s
user    1m52.047s
sys    0m0.232s

Ok, looks like their code is ok if the childish “eval is evil” warnings are ignored. However what does JavaScript Lint say. Turns out it’s much more interesting:

time jsl -conf /my/bin/jsl.conf -process jslint.js
JavaScript Lint 0.3.0 (JavaScript-C 1.5 2004-09-24)
Developed by Matthias Miller (http://www.JavaScriptLint.com)

jslint.js
/my/bin/jslint.js(32): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(32): lint warning: missing default case in switch statement
/my/bin/jslint.js(33): warning: anonymous function does not always return a value
/my/bin/jslint.js(42): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(43): warning: function string does not always return a value
/my/bin/jslint.js(53): lint warning: regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
/my/bin/jslint.js(59): warning: anonymous function does not always return a value
/my/bin/jslint.js(61): warning: anonymous function does not always return a value
/my/bin/jslint.js(62): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(67): lint warning: use of label
/my/bin/jslint.js(71): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(72): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(72): lint warning: missing default case in switch statement
/my/bin/jslint.js(81): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(81): lint warning: missing default case in switch statement
/my/bin/jslint.js(82): warning: anonymous function does not always return a value
/my/bin/jslint.js(83): warning: anonymous function does not always return a value
/my/bin/jslint.js(86): warning: anonymous function does not always return a value
/my/bin/jslint.js(87): warning: anonymous function does not always return a value
/my/bin/jslint.js(90): warning: anonymous function does not always return a value
/my/bin/jslint.js(90): warning: anonymous function does not always return a value
/my/bin/jslint.js(97): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(97): lint warning: missing default case in switch statement
/my/bin/jslint.js(114): lint warning: missing default case in switch statement
/my/bin/jslint.js(160): warning: anonymous function does not always return a value
/my/bin/jslint.js(166): warning: anonymous function does not always return a value
/my/bin/jslint.js(172): warning: function identifier does not always return a value
/my/bin/jslint.js(184): warning: function statement does not always return a value
/my/bin/jslint.js(185): lint warning: regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
/my/bin/jslint.js(193): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(193): lint warning: missing default case in switch statement
/my/bin/jslint.js(222): lint warning: missing default case in switch statement
/my/bin/jslint.js(222): warning: function cssWidth does not always return a value
/my/bin/jslint.js(229): warning: function cssCommaList does not always return a value
/my/bin/jslint.js(230): lint warning: empty statement or extra semicolon
/my/bin/jslint.js(247): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(248): warning: anonymous function does not always return a value
/my/bin/jslint.js(255): lint warning: missing default case in switch statement
/my/bin/jslint.js(261): warning: function styleValue does not always return a value
/my/bin/jslint.js(280): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(282): warning: function stylePattern does not always return a value
/my/bin/jslint.js(289): lint warning: regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
/my/bin/jslint.js(289): lint warning: regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
/my/bin/jslint.js(293): lint warning: regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
/my/bin/jslint.js(306): lint warning: duplicate case in switch statements
/my/bin/jslint.js(306): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(309): lint warning: missing default case in switch statement
/my/bin/jslint.js(343): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(347): lint warning: missing default case in switch statement
/my/bin/jslint.js(349): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(349): lint warning: missing default case in switch statement
/my/bin/jslint.js(349): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(356): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(399): warning: function functionparams does not always return a value
/my/bin/jslint.js(399): warning: function functionparams does not always return a value
/my/bin/jslint.js(411): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(412): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(414): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(414): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(415): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(424): warning: anonymous function does not always return a value
/my/bin/jslint.js(442): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(452): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(466): lint warning: missing default case in switch statement

0 error(s), 64 warning(s)
real 0m0.083s
user 0m0.068s
sys 0m0.008s

So, kind of neat how jslint.js is a JavaScript file but it appears to be weak, wimpy, and worthless. Meaning it doesn’t catch nearly as many possible problems and it took over 1652 times longer than JavaScript Lint.

However. The website version of jslint is much better. It’s faster and allows various options than it’s CLI version. Still it reported what seemed like spurious errors and miscellaneous information that was just plain confusing if even correct. (It was probably correct but I just didn’t have the desire to figure out what it was going on about.) The options are fun to play with but who wants to cut and paste to a website?

April 24, 2009

JavaScript Testing

I’m finding my JavaScript code is not behaving as I’d like it to. Code I thought was solid and have been using consistently is less than solid. Code involving money. So it’s time to start rigorously testing things as if I were coding in C/C++. At http://www.opensourcetesting.org/unit_javascript.php is a list of free tools that can help.

  1. CrossCheck. It seems to concentrate on verifing the code will run on multiple browsers. Making sure things work on buggy browsers like IE is not big on my list.
  2. JavaScript Assertion Unit. Assertion testing. Might be all I need. Probably not though. I don’t want to complicate the code itself. I’d like to have a separate unit supplying the input and comparing it to expected results that can be used by code coverage tests too.
  3. JSCoverage. This runs the latest Linux and Firefox distros and looks very promising. It only checks coverage though. Nothing else.
  4. JSMock. The documentation is less than clear. I can’t tell if it can be automated, if it runs on Linux, or even what it does. Hopefully it allows test scripts to suppy and perhaps change values within the called functions and compare the results. However if it does do this it does not plainly say it.
  5. JSNUnit. A product made for M$ environments. Does not work in Linux.
  6. JSUnit. Tests multiple browser javascript on multiple OSs. It looks very promising in that you can write test scripts to run the pages, functions, and possibly even alter values. Hopefully allowing the JSCoverage to run at the same time. I’ll probably start with this tool.
  7. JSUnit. I’m not sure how this one differs from the other JSUnit. I’d best compare the two carefully before deciding which one to use.
  8. RhinoUnit. It is tied to ANT. It mentions having integrated support for JSLint.
  9. JSLint. I’m not sure if this can be run standalone. Perhaps this page will explain it better: http://www.jslint.com/rhino/index.html
  10. JavaScript Lint. Hmmm.

Some of the criteria I’m looking for are:

  1. Fully Automatable.
  2. Speed.
  3. Ease.
  4. Runs on Linux.
  5. Coverage Check.
  6. Free.
  7. Actively supported.
  8. RegEx comparisons.

The Lints are the natural place to start. I’ll somehow make some bash scripts to test them and go from there.

March 17, 2009

Sorry state of “agrep”…

Filed under: awk/sed, bash, cli, Linux, ubuntu, vi — Tags: , , , , , , — ioconnor @ 7:27 pm

One very useful tool is “agrep”. Say a customers calls in and they live on “pentrose”. If you had a directory of customers you might be able to do a search for them by typing “agrep -i -2 pentrose *.*”. The “-2” says find any characters that are off by two or less from “pentrose”. So “Penrose”, “pentroose”, “Pentrous” and “Pentrouse” would all have matched. This is very helpful especially considering google maps and thomas brother maps often spell street names slightly different. Unfortunately the “-l” option telling agrep to list the file names does not work. See the following dump:

/customers$ agrep -V

This is agrep version 3.0, 1994.

/customers$ locate agrep
/usr/bin/agrep
/usr/share/doc/agrep
/usr/share/doc/agrep/README.gz
/usr/share/doc/agrep/agrep.algorithms
/usr/share/doc/agrep/agrep.ps.1.gz
/usr/share/doc/agrep/agrep.ps.2.gz
/usr/share/doc/agrep/changelog.Debian.gz
/usr/share/doc/agrep/changelog.gz
/usr/share/doc/agrep/contribution.list
/usr/share/doc/agrep/copyright
/usr/share/man/man1/agrep.1.gz
/var/cache/apt/archives/agrep_4.17-5_i386.deb
/var/lib/dpkg/info/agrep.list
/var/lib/dpkg/info/agrep.md5sums
/customers$ agrep -il -1  biider *.*html
customer_2401.shtml
*** glibc detected *** agrep: double free or corruption (top): 0x0821bf48 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7e8aa85]
/lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7e8e4f0]
agrep[0x804b7df]
agrep[0x805751c]
agrep[0x8055dea]
agrep[0x80571bc]
agrep[0x8057228]
agrep[0x8066519]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7e35450]
agrep[0x8048b81]
======= Memory map: ========
08048000-08068000 r-xp 00000000 08:01 6931968    /usr/bin/agrep
08068000-08069000 rw-p 00020000 08:01 6931968    /usr/bin/agrep
08069000-0823a000 rw-p 08069000 00:00 0          [heap]
b7b00000-b7b21000 rw-p b7b00000 00:00 0
b7b21000-b7c00000 —p b7b21000 00:00 0
b7cdf000-b7ce9000 r-xp 00000000 08:01 5744705    /lib/libgcc_s.so.1
b7ce9000-b7cea000 rw-p 0000a000 08:01 5744705    /lib/libgcc_s.so.1
b7cfd000-b7cfe000 rw-p b7cfd000 00:00 0
b7cfe000-b7d3d000 r–p 00000000 08:01 6964092    /usr/lib/locale/en_US.utf8/LC_CTYPE
b7d3d000-b7e1e000 r–p 00000000 08:01 6964091    /usr/lib/locale/en_US.utf8/LC_COLLATE
b7e1e000-b7e1f000 rw-p b7e1e000 00:00 0
b7e1f000-b7f68000 r-xp 00000000 08:01 4252758    /lib/tls/i686/cmov/libc-2.7.so
b7f68000-b7f69000 r–p 00149000 08:01 4252758    /lib/tls/i686/cmov/libc-2.7.so
b7f69000-b7f6b000 rw-p 0014a000 08:01 4252758    /lib/tls/i686/cmov/libc-2.7.so
b7f6b000-b7f6e000 rw-p b7f6b000 00:00 0
b7f70000-b7f71000 r–p 00000000 08:01 6964097    /usr/lib/locale/en_US.utf8/LC_NUMERIC
b7f71000-b7f72000 r–p 00000000 08:01 6964100    /usr/lib/locale/en_US.utf8/LC_TIME
b7f72000-b7f73000 r–p 00000000 08:01 6964095    /usr/lib/locale/en_US.utf8/LC_MONETARY
b7f73000-b7f74000 r–p 00000000 08:01 6971396    /usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES
b7f74000-b7f75000 r–p 00000000 08:01 6964098    /usr/lib/locale/en_US.utf8/LC_PAPER
b7f75000-b7f76000 r–p 00000000 08:01 6964096    /usr/lib/locale/en_US.utf8/LC_NAME
b7f76000-b7f77000 r–p 00000000 08:01 6964090    /usr/lib/locale/en_US.utf8/LC_ADDRESS
b7f77000-b7f78000 r–p 00000000 08:01 6964099    /usr/lib/locale/en_US.utf8/LC_TELEPHONE
b7f78000-b7f79000 r–p 00000000 08:01 6964094    /usr/lib/locale/en_US.utf8/LC_MEASUREMENT
b7f79000-b7f80000 r–s 00000000 08:01 6947512    /usr/lib/gconv/gconv-modules.cache
b7f80000-b7f81000 r–p 00000000 08:01 6964093    /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION
b7f81000-b7f83000 rw-p b7f81000 00:00 0
b7f83000-b7f84000 r-xp b7f83000 00:00 0          [vdso]
b7f84000-b7f9e000 r-xp 00000000 08:01 5693498    /lib/ld-2.7.so
b7f9e000-b7fa0000 rw-p 00019000 08:01 5693498    /lib/ld-2.7.so
bf89e000-bf8c4000 rw-p bffda000 00:00 0          [stack]
Aborted
customers$

You’d think such a handy utility would be kept up-to-date. Yet it says it is version 3 from 12 years ago. This is not true. The actual version synaptic gives is 4.17-5.

To get around this goofiness and get the documented “-l” option without the core dump use:

/customers$ agrep -i -1 biider *.* | awk ‘{ print $1 }’ | sort | uniq
customer_2401.shtml:
customer_6986.php:
/customers$

I just put it into a script file called “f” so I can simply type “f biider” and view the files…

#!/bin/bash
if [ “1” = “$#” ]; then
time gvim +/$1 $(agrep -1 -i $1 /customers/*.*html /customers/*.php | awk -F”:” ‘{ print $1 }’ | sort -rn | uniq )
elif [ “2” = “$#” ]; then
time gvim +/$1 -n $(agrep -2 -i $2 $(agrep -1 -i $1 /customers/*.*html /customers/*.php | awk -F”:” ‘{ print $1 }’ | sort -rn | uniq) | awk -F”:” ‘{ print $1 }’ | sort -rn | uniq )
else
echo “wrong number of arguments”
fi

agrep is so very useful. Somebody really should fix it. Until then use my workaround.

February 22, 2009

Awk and Sed one liners explained

Filed under: awk/sed, bash, cli, php, Uncategorized — Tags: , , , — ioconnor @ 7:44 pm

There is an excellent article at OS News here http://www.osnews.com/story/21004/Awk_and_Sed_One-Liners_Explained

Much of the stuff presented there is very useful. However… Yes there is a big “however”. Howevery do you really want to use these platform specific arcane relics that do not have the error handling capabilities needed to handle unexpected scenarios? Short answer… NO.

Use PHP instead. It can do everything awk/sed can much more easily. More importantly you can plan for the unexpected since you get errors back instead of just blindly assuming the awk and sed commands worked as they did in your microcosm of a test world.

Sure PHP is not always installed on the platform. Say you are planning to put your code in a debian package and you are afraid to use PHP since it does not come preinstalled. Well simply put the latest release of PHP as a requirement for your package. Done. Before your package is loaded PHP gets loaded so you have all the wonderful PHP tools and perhaps libraries available.

Then there is the matter of running your code run on windows platforms. Same thing. Require PHP to be installed first. You can find it here for free on the M$ world. Sure there are some cooler languages like python and ruby but they simply are not as solid as PHP nor do they have the excellent pear libraries.

Older Posts »

Blog at WordPress.com.