The various tests that [[ ... ]] and [ ... ] use in if and while loops are from the Unix test command itself. An easy way to see what these various tests are is to look the test manpage.
In Unix, the /bin/[ command is actually a hard link to the /bin/test command. In early Unix systems, you would write this:
if test -n $parameter
then
echo "Parameter has a value"
fi
or
if test $foo = $bar
then
echo "Foo and Bar are equal"
fi
The /bin/[ was created, so you could do this:
if [ -n $parameter ]
then
echo "Parameter has a value"
fi
and this
if [ $foo = $bar ]
then
echo "Foo and Bar are equal"
fi
This explains why the funny syntax and why you need a space between the square brackets and the parameters inside.
The [[ ... ]] is actually a Korn shellism ... I mean a POSIX shellism that BASH has taken borrowed. It was introduced to allow pattern matching tests ([[ $foo == bar* ]]) and is internal to the shell, so its less sensitive to shell command line expansion issues. For example:
if [ $foo = $bar ]
will fail if either $foo or $bar is not set while:
if [[ $foo = $bar ]]
will work even if one of those two variables aren't set.
The [[ ... ]] syntax takes all of the same testing parameters that [ ... ] does and is now preferred.