'use strict';

suite('Text', function() {
  // ======================================================
  test('text with empty config is allowed', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    stage.add(layer);
    var text = new Konva.Text();

    layer.add(text);
    layer.draw();
  });

  // ======================================================
  test('text with undefined text property should not throw an error', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    stage.add(layer);
    var text = new Konva.Text({ text: undefined });

    layer.add(text);
    layer.draw();

    assert.equal(text.getWidth(), 0);
  });

  test('add text with shadows', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var rect = new Konva.Rect({
      x: stage.getWidth() / 2,
      y: stage.getHeight() / 2,
      stroke: '#555',
      strokeWidth: 5,
      fill: '#ddd',
      width: 400,
      height: 100,
      shadowColor: 'black',
      shadowBlur: 1,
      shadowOffset: [10, 10],
      shadowOpacity: 0.2,
      cornerRadius: 10
    });

    var text = new Konva.Text({
      x: stage.getWidth() / 2,
      y: stage.getHeight() / 2,
      text: 'Hello World!',
      fontSize: 50,
      fontFamily: 'Calibri',
      fontStyle: 'normal',
      fill: '#888',
      stroke: '#333',
      align: 'right',
      lineHeight: 1.2,
      width: 400,
      height: 100,
      padding: 10,
      shadowColor: 'red',
      shadowBlur: 1,
      shadowOffset: [10, 10],
      shadowOpacity: 0.2
    });

    var group = new Konva.Group({
      draggable: true
    });

    // center text box
    rect.offset(text.getWidth() / 2, text.getHeight() / 2);
    text.offset(text.getWidth() / 2, text.getHeight() / 2);

    group.add(rect);
    group.add(text);
    layer.add(group);
    stage.add(layer);

    assert.equal(text.getClassName(), 'Text', 'getClassName should be Text');
  });

  test('text with fill and shadow', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      x: 10,
      y: 10,
      text: 'Hello World!',
      fontSize: 50,
      fill: 'black',
      shadowColor: 'darkgrey',
      shadowOffsetX: 0,
      shadowOffsetY: 50,
      shadowBlur: 0
    });

    layer.add(text);
    stage.add(layer);

    var canvas = createCanvas();
    var context = canvas.getContext('2d');
    context.textBaseline = 'middle';
    context.font = 'normal normal 50px Arial';
    context.fillStyle = 'darkgrey';
    context.fillText('Hello World!', 10, 10 + 50 + 25);
    context.fillStyle = 'black';
    context.fillText('Hello World!', 10, 10 + 25);

    compareLayerAndCanvas(layer, canvas, 254);
  });

  test('text cache with fill and shadow', function() {
    var stage = addStage();
    var layer1 = new Konva.Layer();
    layer1.getCanvas().setPixelRatio(1);
    stage.add(layer1);

    var text1 = new Konva.Text({
      x: 10,
      y: 10,
      text: 'some text',
      fontSize: 50,
      fill: 'black',
      shadowColor: 'black',
      shadowOffsetX: 0,
      shadowOffsetY: 50,
      opacity: 1,
      shadowBlur: 10,
      draggable: true
    });
    layer1.add(text1);

    var layer2 = new Konva.Layer();
    layer2.getCanvas().setPixelRatio(1);

    layer2.add(text1.clone().cache({ pixelRatio: 2 }));
    stage.add(layer1, layer2);

    if (!window.isPhantomJS) {
      compareLayers(layer1, layer2, 220);
    }
  });

  test('text cache with fill and shadow and some scale', function() {
    var stage = addStage();
    var layer1 = new Konva.Layer();
    stage.add(layer1);

    var text1 = new Konva.Text({
      x: 10,
      y: 10,
      text: 'some text',
      fontSize: 50,
      fill: 'black',
      shadowColor: 'black',
      shadowOffsetX: 0,
      shadowOffsetY: 50,
      opacity: 1,
      shadowBlur: 10,
      draggable: true
    });
    layer1.add(text1);

    var layer2 = new Konva.Layer({
      scaleX: 0.5,
      scaleY: 0.5
    });
    stage.add(layer2);

    var group = new Konva.Group();
    layer2.add(group);

    var text2 = text1.clone();
    group.add(text2);

    text2.cache();
    group.scale({ x: 2, y: 2 });

    stage.draw();

    compareLayers(layer1, layer2, 200);
  });

  // ======================================================
  test('add text with letter spacing', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    stage.add(layer);
    var text = new Konva.Text({
      text: 'hello'
    });
    layer.add(text);
    layer.draw();

    var oldWidth = text.width();
    text.letterSpacing(10);

    assert.equal(text.width(), oldWidth + 40);
    layer.draw();
  });
  // ======================================================
  test('text getters and setters', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      x: stage.getWidth() / 2,
      y: stage.getHeight() / 2,
      text: 'Hello World!',
      fontSize: 50,
      fontFamily: 'Calibri',
      fontStyle: 'normal',
      fontVariant: 'normal',
      fill: '#888',
      stroke: '#333',
      align: 'right',
      lineHeight: 1.2,
      width: 400,
      height: 100,
      padding: 10,
      shadowColor: 'black',
      shadowBlur: 1,
      shadowOffset: [10, 10],
      shadowOpacity: 0.2,
      draggable: true
    });

    // center text box
    text.offset(text.getWidth() / 2, text.getHeight() / 2);

    layer.add(text);
    stage.add(layer);

    /*
     * test getters and setters
     */

    assert.equal(text.getX(), stage.getWidth() / 2);
    assert.equal(text.getY(), stage.getHeight() / 2);
    assert.equal(text.getText(), 'Hello World!');
    assert.equal(text.getFontSize(), 50);
    assert.equal(text.getFontFamily(), 'Calibri');
    assert.equal(text.getFontStyle(), 'normal');
    assert.equal(text.getFontVariant(), 'normal');
    assert.equal(text.getFill(), '#888');
    assert.equal(text.getStroke(), '#333');
    assert.equal(text.getAlign(), 'right');
    assert.equal(text.getLineHeight(), 1.2);
    assert.equal(text.getWidth(), 400);
    assert.equal(text.getHeight(), 100);
    assert.equal(text.getPadding(), 10);
    assert.equal(text.getShadowColor(), 'black');
    assert.equal(text.getDraggable(), true);
    assert.equal(text.getWidth(), 400);
    assert.equal(text.getHeight(), 100);
    assert(text.getTextWidth() > 0, 'text width should be greater than 0');
    assert(text.getTextHeight() > 0, 'text height should be greater than 0');

    text.setX(1);
    text.setY(2);
    text.setText('bye world!');
    text.setFontSize(10);
    text.setFontFamily('Arial');
    text.setFontStyle('bold');
    text.setFontVariant('small-caps');
    text.setFill('green');
    text.setStroke('yellow');
    text.setAlign('left');
    text.setWidth(300);
    text.setHeight(75);
    text.setPadding(20);
    text.setShadowColor('green');
    text.setDraggable(false);

    assert.equal(text.getX(), 1);
    assert.equal(text.getY(), 2);
    assert.equal(text.getText(), 'bye world!');
    assert.equal(text.getFontSize(), 10);
    assert.equal(text.getFontFamily(), 'Arial');
    assert.equal(text.getFontStyle(), 'bold');
    assert.equal(text.getFontVariant(), 'small-caps');
    assert.equal(text.getFill(), 'green');
    assert.equal(text.getStroke(), 'yellow');
    assert.equal(text.getAlign(), 'left');
    assert.equal(text.getWidth(), 300);
    assert.equal(text.getHeight(), 75);
    assert.equal(text.getPadding(), 20);
    assert.equal(text.getShadowColor(), 'green');
    assert.equal(text.getDraggable(), false);

    // test set text to integer
    text.setText(5);

    //document.body.appendChild(layer.bufferCanvas.element)

    //layer.setListening(false);
    layer.drawHit();
  });

  // ======================================================
  test('reset text auto width', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      text: 'Hello World!',
      fontSize: 50,
      draggable: true,
      width: 10
    });

    assert.equal(text.width(), 10);
    text.setAttr('width', undefined);
    assert.equal(text.width() > 100, true);

    layer.add(text);
    stage.add(layer);
  });

  // ======================================================
  test('text multi line', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var rect = new Konva.Rect({
      x: 10,
      y: 10,
      width: 380,
      height: 300,
      fill: 'red'
    });

    var text = new Konva.Text({
      x: 10,
      y: 10,
      text:
        "HEADING\n\nAll the world's a stage, merely players. They have their exits and their entrances; And one man in his time plays many parts.",
      //text: 'HEADING\n\nThis is a really cool paragraph. \n And this is a footer.',
      fontSize: 14,
      fontFamily: 'Calibri',
      fontStyle: 'normal',
      fill: '#555',
      //width: 20,
      width: 380,
      //width: 200,
      padding: 10,
      lineHeight: 20,
      align: 'center',
      draggable: true,
      wrap: 'WORD'
    });

    rect.height(text.getHeight());
    // center text box
    //text.setOffset(text.getBoxWidth() / 2, text.getBoxHeight() / 2);

    layer.add(rect).add(text);
    stage.add(layer);

    assert.equal(text.getLineHeight(), 20);
  });

  // ======================================================
  test('text single line with ellipsis', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var rect = new Konva.Rect({
      x: 10,
      y: 10,
      width: 380,
      height: 300,
      fill: 'red'
    });

    var text = new Konva.Text({
      x: 10,
      y: 10,
      text:
        "HEADING\n\nAll the world's a stage, merely players. They have their exits and their entrances; And one man in his time plays many parts.",
      fontSize: 14,
      fontFamily: 'Calibri',
      fontStyle: 'normal',
      fill: '#555',
      width: 100,
      padding: 0,
      lineHeight: 20,
      align: 'center',
      wrap: 'none',
      ellipsis: true
    });

    layer.add(rect).add(text);
    stage.add(layer);

    assert.equal(text.textArr.length, 3);
    assert.equal(text.textArr[2].text.slice(-1), '…');
  });

  // ======================================================
  test('text multi line with justify align', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var rect = new Konva.Rect({
      x: 10,
      y: 10,
      width: 380,
      height: 300,
      fill: 'yellow'
    });

    var text = new Konva.Text({
      x: 10,
      y: 10,
      text:
        "HEADING\n\n    All the world's a stage, merely players. They have their exits and their entrances; And one man in his time plays many parts.",
      fontSize: 14,
      fontFamily: 'Calibri',
      fontStyle: 'normal',
      fill: '#555',
      width: 380,
      align: 'justify',
      letterSpacing: 5,
      draggable: true
    });

    rect.height(text.getHeight());
    layer.add(rect).add(text);

    stage.add(layer);

    var trace =
      'translate();fillStyle;fillText();translate();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();restore();translate();save();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();restore();translate();restore();';

    assert.equal(layer.getContext().getTrace(true), trace);
  });

  // ======================================================
  test('text multi line with justify align and decoration', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var rect = new Konva.Rect({
      x: 10,
      y: 10,
      width: 380,
      height: 300,
      fill: 'yellow'
    });

    var text = new Konva.Text({
      x: 10,
      y: 10,
      text:
        "HEADING\n\n    All the world's a stage, merely players. They have their exits and their entrances; And one man in his time plays many parts.",
      fontSize: 14,
      fontFamily: 'Calibri',
      fontStyle: 'normal',
      fill: '#555',
      width: 380,
      align: 'justify',
      letterSpacing: 5,
      textDecoration: 'underline',
      padding: 20,
      draggable: true
    });

    rect.height(text.getHeight());

    layer.add(rect).add(text);

    stage.add(layer);

    var trace =
      'fillText();translate();fillStyle;fillText();translate();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();restore();translate();save();save();beginPath();moveTo();lineTo();stroke();restore();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();fillStyle;fillText();translate();restore();translate();restore();';

    assert.equal(layer.getContext().getTrace(true), trace);
  });

  // ======================================================
  test('text multi line with shadows', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      x: 10,
      y: 10,
      //stroke: '#555',
      //strokeWidth: 5,
      text:
        "HEADING\n\nAll the world's a stage, and all the men and women merely players. They have their exits and their entrances; And one man in his time plays many parts.",
      //text: 'HEADING\n\nThis is a really cool paragraph. \n And this is a footer.',
      fontSize: 16,
      fontFamily: 'Calibri',
      fontStyle: 'normal',
      fill: '#555',
      //width: 20,
      width: 380,
      //width: 200,
      padding: 20,
      align: 'center',
      shadowColor: 'red',
      shadowBlur: 1,
      shadowOffset: [10, 10],
      shadowOpacity: 0.5,
      draggable: true
    });

    layer.add(text);
    stage.add(layer);
    //console.log(layer.getContext().getTrace());
  });

  // ======================================================
  test('text multi line with underline and spacing', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      x: 10,
      y: 10,
      text: 'hello\nworld',
      fontSize: 80,
      fill: 'red',
      letterSpacing: 5,
      textDecoration: 'underline',
      draggable: true
    });

    layer.add(text);
    stage.add(layer);

    var trace =
      'clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 80px Arial;textBaseline=middle;textAlign=left;translate(0,40);save();save();beginPath();moveTo(0,40);lineTo(189,40);stroke();restore();fillStyle=red;fillText(h,0,0);translate(49,0);fillStyle=red;fillText(e,0,0);translate(49,0);fillStyle=red;fillText(l,0,0);translate(23,0);fillStyle=red;fillText(l,0,0);translate(23,0);fillStyle=red;fillText(o,0,0);translate(49,0);restore();translate(0,80);save();save();beginPath();moveTo(0,40);lineTo(211,40);stroke();restore();fillStyle=red;fillText(w,0,0);translate(63,0);fillStyle=red;fillText(o,0,0);translate(49,0);fillStyle=red;fillText(r,0,0);translate(32,0);fillStyle=red;fillText(l,0,0);translate(23,0);fillStyle=red;fillText(d,0,0);translate(49,0);restore();translate(0,80);restore();';

    assert.equal(layer.getContext().getTrace(), trace);
  });

  test('text multi line with strike', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      x: 10,
      y: 10,
      text: 'hello\nworld',
      fontSize: 80,
      fill: 'red',
      textDecoration: 'line-through'
    });

    layer.add(text);
    stage.add(layer);

    var trace =
      'clearRect();save();transform();font;textBaseline;textAlign;translate();save();save();beginPath();moveTo();lineTo();stroke();restore();fillStyle;fillText();restore();translate();save();save();beginPath();moveTo();lineTo();stroke();restore();fillStyle;fillText();restore();translate();restore();';
    // console.log(layer.getContext().getTrace(true));
    // console.log(trace);
    assert.equal(layer.getContext().getTrace(true), trace);
  });

  test('text multi line with underline and strike', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      x: 10,
      y: 10,
      text: 'hello\nworld',
      fontSize: 80,
      fill: 'red',
      textDecoration: 'underline line-through'
    });

    layer.add(text);
    stage.add(layer);

    var trace =
      'clearRect();save();transform();font;textBaseline;textAlign;translate();save();save();beginPath();moveTo();lineTo();stroke();restore();save();beginPath();moveTo();lineTo();stroke();restore();fillStyle;fillText();restore();translate();save();save();beginPath();moveTo();lineTo();stroke();restore();save();beginPath();moveTo();lineTo();stroke();restore();fillStyle;fillText();restore();translate();restore();';
    assert.equal(layer.getContext().getTrace(true), trace);
  });

  // ======================================================
  test('change font size should update text data', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      x: 10,
      y: 10,
      text: 'Some awesome text',
      fontSize: 16,
      fontFamily: 'Calibri',
      fontStyle: 'normal',
      fill: '#555',
      align: 'center',
      padding: 5,
      draggable: true
    });

    var width = text.getWidth();
    var height = text.getHeight();

    layer.add(text);
    stage.add(layer);

    text.setFontSize(30);
    layer.draw();

    //console.log(text.getHeight() + ',' + height);

    assert(text.getWidth() > width, 'width should have increased');
    assert(text.getHeight() > height, 'height should have increased');
  });

  test('text vertical align', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var rect = new Konva.Rect({
      x: 10,
      y: 10,
      width: 200,
      height: 100,
      stroke: 'black'
    });
    layer.add(rect);

    var text = new Konva.Text({
      x: rect.x(),
      y: rect.y(),
      width: rect.width(),
      height: rect.height(),
      text: 'Some awesome text',
      fontSize: 16,
      fill: '#555',
      align: 'center',
      padding: 10,
      draggable: true
    });

    assert.equal(text.verticalAlign(), 'top');

    text.verticalAlign('middle');

    layer.add(text);
    stage.add(layer);

    var trace =
      'clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);beginPath();rect(0,0,200,100);closePath();lineWidth=2;strokeStyle=black;stroke();restore();save();transform(1,0,0,1,10,10);font=normal normal 16px Arial;textBaseline=middle;textAlign=left;translate(10,0);translate(0,50);save();translate(17.523,0);fillStyle=#555;fillText(Some awesome text,0,0);restore();restore();';

    assert.equal(layer.getContext().getTrace(), trace);
  });

  test('get text width', function() {
    var stage = addStage();
    var layer = new Konva.Layer();
    stage.add(layer);
    var text = new Konva.Text({
      text: 'hello asd fasdf asdf asd fasdf asdfasd fa sds helloo',
      fill: 'black',
      width: 100
    });

    layer.add(text);
    layer.draw();
    assert.equal(text.getTextWidth() > 0 && text.getTextWidth() < 100, true);
  });

  test('default text color should be black', function() {
    var text = new Konva.Text();
    assert.equal(text.fill(), 'black');
  });

  test('text with stoke and strokeScaleEnabled', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      fontSize: 50,
      y: 50,
      x: 50,
      fill: 'black',
      text: 'text',
      stroke: 'red',
      strokeScaleEnabled: false,
      strokeWidth: 2,
      scaleX: 2
    });
    layer.add(text);
    stage.add(layer);

    var canvas = createCanvas();
    var context = canvas.getContext('2d');
    context.translate(50, 50);
    context.lineWidth = 2;
    context.font = '50px Arial';
    context.strokeStyle = 'red';
    context.scale(2, 1);
    context.textBaseline = 'middle';
    context.fillText('text', 0, 25);
    context.strokeText('text', 0, 25);
    compareLayerAndCanvas(layer, canvas);
  });

  test('text getSelfRect', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      fontSize: 50,
      y: 50,
      x: 50,
      fill: 'black',
      text: 'text'
    });

    layer.add(text);
    stage.add(layer);

    var rect = text.getSelfRect();

    assert.deepEqual(rect, {
      x: 0,
      y: 0,
      width: text.width(),
      height: 50
    });
  });

  test('linear gradient', function() {
    Konva.pixelRatio = 1;
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      fontSize: 50,
      y: 10,
      x: 10,
      fillLinearGradientStartPoint: { x: 0, y: 0 },
      fillLinearGradientEndPoint: { x: 300, y: 0 },
      fillLinearGradientColorStops: [0, 'yellow', 0.5, 'yellow', 1, 'red'],
      text: 'Text with gradient!!',
      draggable: true
    });
    layer.add(text);
    stage.add(layer);

    var canvas = createCanvas();
    var ctx = canvas.getContext('2d');

    ctx.fillStyle = 'green';
    ctx.font = 'normal 50px Arial';
    ctx.textBaseline = 'middle';

    var start = { x: 0, y: 0 };
    var end = { x: 300, y: 0 };
    var colorStops = [0, 'yellow', 0.5, 'yellow', 1, 'red'];
    var grd = ctx.createLinearGradient(start.x, start.y, end.x, end.y);

    // build color stops
    for (var n = 0; n < colorStops.length; n += 2) {
      grd.addColorStop(colorStops[n], colorStops[n + 1]);
    }
    ctx.fillStyle = grd;

    ctx.fillText(text.text(), text.x(), text.y() + text.fontSize() / 2);

    compareLayerAndCanvas(layer, canvas, 200);

    var data = layer.getContext().getImageData(25, 41, 1, 1).data;
    delete Konva.pixelRatio;
    assert.equal(data[0], 255, 'full green');
    assert.equal(data[1], 255, 'full red');
    assert.equal(data[2], 0, 'no blue');
    assert.equal(data[3], 255, '255 alpha - fully visible');
  });

  // TODO: how to make correct behavior?
  test.skip('linear gradient multiline', function() {
    Konva.pixelRatio = 1;
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      fontSize: 50,
      fillLinearGradientStartPoint: { x: 0, y: 0 },
      fillLinearGradientEndPoint: { x: 0, y: 100 },
      fillLinearGradientColorStops: [0, 'yellow', 1, 'red'],
      text: 'Text with gradient!!\nText with gradient!!',
      draggable: true
    });
    layer.add(text);
    stage.add(layer);

    var canvas = createCanvas();
    var ctx = canvas.getContext('2d');

    ctx.fillStyle = 'green';
    ctx.font = 'normal 50px Arial';
    ctx.textBaseline = 'middle';

    var start = { x: 0, y: 0 };
    var end = { x: 0, y: 100 };
    var colorStops = [0, 'yellow', 1, 'red'];
    var grd = ctx.createLinearGradient(start.x, start.y, end.x, end.y);

    // build color stops
    for (var n = 0; n < colorStops.length; n += 2) {
      grd.addColorStop(colorStops[n], colorStops[n + 1]);
    }
    ctx.fillStyle = grd;

    ctx.fillText(text.text(), text.x(), text.y() + text.fontSize() / 2);
    ctx.fillText(
      text.text(),
      text.x(),
      text.y() + text.fontSize() / 2 + text.fontSize()
    );

    compareLayerAndCanvas(layer, canvas, 200);

    var data = layer.getContext().getImageData(25, 41, 1, 1).data;
    delete Konva.pixelRatio;
    assert.equal(data[0], 255, 'full green');
    assert.equal(data[1], 255, 'full red');
    assert.equal(data[2], 0, 'no blue');
    assert.equal(data[3], 255, '255 alpha - fully visible');
  });

  test('radial gradient', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      fontSize: 50,
      y: 0,
      x: 0,
      fillRadialGradientStartPoint: { x: 100, y: 0 },
      fillRadialGradientStartRadius: 0,
      fillRadialGradientEndRadius: 100,
      fillRadialGradientEndPoint: { x: 100, y: 0 },
      fillRadialGradientColorStops: [0, 'yellow', 1, 'red'],
      text: 'Text with gradient!!',
      draggable: true
    });
    layer.add(text);
    stage.add(layer);

    var canvas = createCanvas();
    var ctx = canvas.getContext('2d');

    ctx.fillStyle = 'green';
    ctx.font = 'normal 50px Arial';
    ctx.textBaseline = 'middle';

    var start = { x: 100, y: 0 };
    var end = { x: 100, y: 0 };
    var colorStops = [0, 'yellow', 1, 'red'];
    var grd = ctx.createRadialGradient(start.x, start.y, 0, end.x, end.y, 100);

    // build color stops
    for (var n = 0; n < colorStops.length; n += 2) {
      grd.addColorStop(colorStops[n], colorStops[n + 1]);
    }
    ctx.fillStyle = grd;

    ctx.translate(0, 25);

    ctx.fillText(text.text(), 0, 0);

    compareLayerAndCanvas(layer, canvas, 200);
  });

  test('text should be centered in line height', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      fontSize: 40,
      text: 'Some good text',
      lineHeight: 3,
      draggable: true
    });
    layer.add(text);
    stage.add(layer);

    // this text should look like it is positioned in y = 40

    var trace =
      'clearRect(0,0,578,200);save();transform(1,0,0,1,0,0);font=normal normal 40px Arial;textBaseline=middle;textAlign=left;translate(0,60);save();fillStyle=black;fillText(Some good text,0,0);restore();restore();';

    assert.equal(layer.getContext().getTrace(), trace);
  });

  test('check wrapping', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      fontSize: 40,
      text: 'Hello, this is some good text',
      width: 185,
      draggable: true
    });
    layer.add(text);
    stage.add(layer);

    var lines = text.textArr;

    // first line should fit "Hello, this"
    // I faced this issue in large app
    // we should draw as much text in one line, as possible
    // so Konva.Text + textarea editing works better
    assert.equal(lines[0].text, 'Hello, this');
  });

  test('check trip when go to new line', function() {
    var stage = addStage();
    var layer = new Konva.Layer();

    var text = new Konva.Text({
      text: 'Hello, this is some good text',
      fontSize: 30
    });
    layer.add(text);
    stage.add(layer);

    text.setWidth(245);

    var lines = text.textArr;

    // remove all trimming spaces
    // it also looks better in many cases
    // it will work as text in div
    assert.equal(lines[0].text, 'Hello, this is some');
    assert.equal(lines[1].text, 'good text');

    text.setWidth(261);
    var lines = text.textArr;

    assert.equal(lines[0].text, 'Hello, this is some');
    assert.equal(lines[1].text, 'good text');
    layer.draw();
  });

  test('image gradient for text', function(done) {
    Konva.pixelRatio = 1;
    var imageObj = new Image();
    imageObj.onload = function() {
      var stage = addStage();
      var layer = new Konva.Layer();

      var text = new Konva.Text({
        text: 'Hello, this is some good text',
        fontSize: 30,
        fillPatternImage: imageObj
      });
      layer.add(text);
      stage.add(layer);

      var canvas = createCanvas();
      var ctx = canvas.getContext('2d');

      ctx.fillStyle = 'green';
      ctx.font = 'normal normal 30px Arial';
      ctx.textBaseline = 'middle';

      var grd = ctx.createPattern(imageObj, 'repeat');
      ctx.translate(0, 15);
      ctx.fillStyle = grd;

      ctx.fillText(text.text(), 0, 0);

      compareLayerAndCanvas(layer, canvas, 200);
      delete Konva.pixelRatio;
      done();
    };
    imageObj.src = 'assets/darth-vader.jpg';
  });
});