Skip to content

Commit

Permalink
Fix #47: Implement 's' conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
gzm0 committed Dec 26, 2013
1 parent 9a25b7f commit 7718807
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 6 deletions.
5 changes: 5 additions & 0 deletions javalib/source/src/java/util/Formattable.scala
@@ -0,0 +1,5 @@
package java.util

trait Formattable {
def formatTo(formatter: Formatter, flags: Int, width: Int, precision: Int): Unit
}
7 changes: 7 additions & 0 deletions javalib/source/src/java/util/FormattableFlags.scala
@@ -0,0 +1,7 @@
package java.util

object FormattableFlags {
val ALTERNATE = 4
val LEFT_JUSTIFY = 1
val UPPERCASE = 2
}
23 changes: 18 additions & 5 deletions javalib/source/src/java/util/Formatter.scala
Expand Up @@ -72,8 +72,9 @@ final class Formatter(private val dest: Appendable) extends Closeable with Flush
def hasFlag(flag: js.String) = flags.indexOf(flag) >= 0

val widthStr = matchResult(3)
val hasWidth = !(!widthStr)
val width =
if (!(!widthStr)) js.parseInt(widthStr)
if (hasWidth) js.parseInt(widthStr)
else (0: js.Number)

val precisionStr = matchResult(4)
Expand Down Expand Up @@ -175,10 +176,22 @@ final class Formatter(private val dest: Appendable) extends Closeable with Flush
if (arg eq null) "null"
else Integer.toHexString(arg.hashCode)
}
case 's' | 'S' => pad {
val s: js.String = if (arg eq null) "null" else arg.toString()
if (hasPrecision) s.substring(0, precision)
else s
case 's' | 'S' => arg match {
case null if !hasFlag("#") => pad("null")
case formattable: Formattable =>
val flags = (
(if (hasFlag("-")) FormattableFlags.LEFT_JUSTIFY else 0) |
(if (hasFlag("#")) FormattableFlags.ALTERNATE else 0) |
(if (conversion.isUpper) FormattableFlags.UPPERCASE else 0)
)

formattable.formatTo(this, flags,
if (hasWidth) width.toInt else -1,
if (hasPrecision) precision.toInt else -1)
None // no further processing
case t: AnyRef if !hasFlag("#") => pad(t.toString)
case _ =>
throw new FormatFlagsConversionMismatchException("#", 's')
}
case 'c' | 'C' =>
pad(js.String.fromCharCode(numberArg))
Expand Down
Expand Up @@ -11,7 +11,7 @@ package javalib
import scala.scalajs.js
import scala.scalajs.test.ScalaJSTest

import java.util.{ Formatter, Formattable }
import java.util.{ Formatter, Formattable, FormattableFlags }

import java.lang.{
Double => JDouble,
Expand All @@ -27,6 +27,28 @@ import java.lang.{
object FormatterTest extends ScalaJSTest {

class HelperClass
class FormattableClass extends Formattable {
var frm: Formatter = _
var flags: Int = _
var width: Int = _
var precision: Int = _
var calls = 0
def formatTo(frm: Formatter, flags: Int, width: Int, precision: Int) = {
this.calls += 1
this.flags = flags
this.width = width
this.precision = precision
frm.out().append("foobar")
}

def expectCalled(times: Int, flags: Int, width: Int, precision: Int) = {
expect(this.calls).toEqual(times)
expect(this.flags).toEqual(flags)
expect(this.width).toEqual(width)
expect(this.precision).toEqual(precision)
}

}

def expectF(format: String, args: AnyRef*) = {
val fmt = new Formatter()
Expand All @@ -35,6 +57,13 @@ object FormatterTest extends ScalaJSTest {
expect(res)
}

def expectFC(format: String, flags: Int, width: Int, precision: Int) = {
val fc = new FormattableClass
val exp = expectF(format, fc)
fc.expectCalled(1, flags, width, precision)
exp
}

describe("java.util.Formatter") {

it("should provide 'b' conversion") {
Expand All @@ -51,6 +80,19 @@ object FormatterTest extends ScalaJSTest {
expectF("%h", null).toEqual("null")
}

it("should provide 's' conversion") {
expectFC("%s", 0, -1, -1).toEqual("foobar")
expectFC("%-s", FormattableFlags.LEFT_JUSTIFY, -1, -1).toEqual("foobar")
expectFC("%-10s", FormattableFlags.LEFT_JUSTIFY, 10, -1).toEqual("foobar")
expectFC("%#-10.2s", FormattableFlags.LEFT_JUSTIFY |
FormattableFlags.ALTERNATE, 10, 2).toEqual("foobar")
expectFC("%#10.2S", FormattableFlags.UPPERCASE |
FormattableFlags.ALTERNATE, 10, 2).toEqual("foobar")
expectF("%10s", "hello").toEqual(" hello")
expectF("%-10s", "hello").toEqual("hello ")
expectThrow("%#s", "hello")
}

it("should provide 'c' conversion") {
expectF("%-5c", new Character('!')).toEqual("! ")
}
Expand Down

0 comments on commit 7718807

Please sign in to comment.