[ -n ] does not use the -n test.
The -n in [ -n ] is not a test at all. When there is only one argument between [ and ], that argument is a string that is tested to see if it is empty. Even when that string has a leading -, it is still interpreted as an operand, not a test. Since the string -n is not empty--it contains two characters, - and n, not zero characters--[ -n ] evaluates to true.
As Ignacio Vazquez-Abrams says, where string is a single argument, the test performed on string in [ string ] is the same as the test performed on it by [ -n string ]. When string happens to be -n, nothing special happens. The -n in [ -n ] and the second -n in [ -n -n ] are simply strings being tested for emptiness.
When there is only one argument between [ and ], that argument is always a string to be tested for nonemptiness, even if it happens to be named the same as a test. Similarly, when there are two arguments between [ and ] and the first of them is -n, the second one is always a string to be tested for nonemptiness, even if it happens to be named the same as a test. This is simply because the syntax for [ insists that a single argument between [ and ] or after -n is a string operand.
For the same reason that [ -n ] doesn't use the -n test, [ -z ] doesn't use the -z test.
You can learn more about [ in bash by examining the help for it. Notice that is a shell builtin:
$ type [
[ is a shell builtin
Thus you can run help [ to get help on it:
$ help [
[: [ arg... ]
Evaluate conditional expression.
This is a synonym for the "test" builtin, but the last argument must
be a literal `]', to match the opening `['.
For more information, including what tests are supported and how they work, you will have to see the help on test. When you run the command help test, you'll get a detailed list. Rather than reproduce it all, here's the part about string operators:
-z STRING True if string is empty.
-n STRING
STRING True if string is not empty.
STRING1 = STRING2
True if the strings are equal.
STRING1 != STRING2
True if the strings are not equal.
STRING1 < STRING2
True if STRING1 sorts before STRING2 lexicographically.
STRING1 > STRING2
True if STRING1 sorts after STRING2 lexicographically.
Notice that -n STRING and just STRING do the same thing: they test if the string STRING is not empty.