// Span Syntax
// ===========

// test the output of a parsed grid
@mixin test-parsed-span($name, $test, $expect) {
  $expect: map-merge($susy, $expect);

  @each $key, $value in $test {
    $this: map-get($expect, $key);
    @include assert-equal($value, $this,
      '[#{$name}] Returns the correct #{$key}.');
  }
}

@include test-module('Span Syntax') {

  // span [mixin]
  // ------------
  @include output-test('span') {

    // default
    @include assert-setup('default', $grid: 7 .5 after) {
      .test, .expect {
        @include susy-clearfix;
        clear: both;
        .inner { background: rgba(yellow, .25); }
      }
    }
    @include assert-output(
      'Span should set width (75%), float (left), and gutter (5% margin-right)'
    ) {
      .test {
        @include span(5 content-box inspect) { .inner { @include span(2); } }
      }
      .expect {
        -susy-span: 5 content-box inspect;
        @include output((box-sizing: content-box));
        width: 70%;
        float: left;
        margin-right: 5%;
        .inner {
          width: percentage(2.5/7);
          float: left;
          margin-right: percentage(.5/7);
        }
      }
    }

    // inside
    @include assert-setup('inside', $grid: 8 .25 inside) {
      .spacer {
        @include span(2);
        clear: left;
      }
    }
    @include assert-output(
      'Span should set width, float, clear, and inside gutter'
    ) {
      @include border-box-sizing;

      .test { @include span(5 break); }
      .expect {
        clear: both;
        width: 62.5%;
        float: left;
        padding-left: 1.25%;
        padding-right: 1.25%;
      }

      @include original-grid;
    }

    // explicit
    @include assert-setup('explicit', $grid: 8 .25 inside) {
      .test, .expect { clear: both; }
    }
    @include assert-output(
      'Span should set width, float, inside gutter, and border-box'
    ) {
      .test { @include span(80%); }
      .expect {
        @include output((box-sizing: border-box));
        width: 80%;
        float: left;
        padding-left: 1.25%;
        padding-right: 1.25%;
      }
    }

  }

  // Span Nesting
  // ------------
  @include test('[mixin] span') {
    $susy: (columns: 12) !global;

    %span-content-test {
      @include span(8 of 12) {
        $test: susy-get(columns);
        $expect: 8;
        @include assert-equal($test, $expect,
          'Span @content should use nested context');

        @include span(3 of 8) {
          $nest-test: susy-get(columns);
          $nest-expect: 3;
          @include assert-equal($nest-test, $nest-expect,
            'Nested span @content should use new nested context');
        }

        $test: susy-get(columns);
        $expect: 8;
        @include assert-equal($test, $expect,
          'Span @content should return to nested context');
      }

      $test: susy-get(columns);
      $expect: 12;
      @include assert-equal($test, $expect,
        'After nesting, column-count should be restored');
    }

    @include original-grid;
  }

  // span [function]
  // ---------------

  @include test('[function] span') {
    @include layout((
      columns: 7,
      gutters: .5,
      math: fluid,
    ));

    // simple
    $span: 5;
    $test: span($span);
    $expect: 70%;
    @include assert-equal($test, $expect,
      'Span function returns expected width value.');

    @include original-grid;
  }

  // span math
  // ---------

  @include test('[function] span-math') {
    // after
    $span: (
      span: 5,
      location: 2,
      columns: 7,
      gutters: .5,
      column-width: 4em,
      output: float,
      math: fluid,
      flow: ltr,
      gutter-position: after,
    );
    $span: span-math($span);
    $expect: (
      width: 70%,
      float: from,
      margin-before: null,
      margin-after: 5%,
      padding-before: null,
      padding-after: null,
      flow: ltr,
    );
    @include assert-equal($span, $expect,
      'Returns correct span-math with outside gutters.');

    // explicit
    $span: (
      span: 50%,
      columns: 7,
      gutters: .5,
      column-width: 4em,
      output: float,
      math: fluid,
      flow: ltr,
      gutter-position: after,
    );
    $span: span-math($span);
    $expect: (
      width: 50%,
      float: from,
      margin-before: null,
      margin-after: 5%,
      padding-before: null,
      padding-after: null,
      flow: ltr,
    );
    @include assert-equal($span, $expect,
      'Returns correct span-math gutters with explicit span.');

    // split first/last
    $span: (
      span: 8,
      location: 1,
      columns: 8,
      gutters: .25,
      column-width: 4em,
      output: float,
      math: fluid,
      flow: ltr,
      gutter-position: split,
    );
    $span: span-math($span);
    $expect: (
      width: 97.5%,
      float: from,
      margin-before: 1.25%,
      margin-after: 1.25%,
      padding-before: null,
      padding-after: null,
      flow: ltr,
    );
    @include assert-equal($span, $expect,
      'Returns correct span-math with split gutters.');

    // inside (padding)
    $span: (
      span: 5,
      location: 2,
      columns: 8,
      gutters: .25,
      column-width: 4em,
      output: float,
      math: fluid,
      flow: ltr,
      gutter-position: inside,
    );
    $span: span-math($span);
    $padding: map-get($span, padding-before) map-get($span, padding-after);
    $expect: 1.25% 1.25%;
    @include assert-equal($padding, $expect,
      'Returns correct padding for inside gutters.');

    // inside nest (padding)
    $span: (
      span: 5,
      location: 2,
      columns: 7,
      gutters: .5,
      column-width: 4em,
      output: float,
      math: fluid,
      flow: ltr,
      gutter-position: inside,
      role: nest,
    );
    $span: span-math($span);
    $padding: map-get($span, padding-before) map-get($span, padding-after);
    $expect: null null;
    @include assert-equal($padding, $expect,
      'The padding for any "inside nest" should be "null null"');

    // split nest (margin & width)
    $span: (
      span: 5,
      location: 2,
      columns: 8,
      gutters: .25,
      output: float,
      math: fluid,
      flow: ltr,
      gutter-position: split,
      role: nest,
    );
    $span: span-math($span);
    $margin: map-get($span, width) map-get($span, margin-before) map-get($span, margin-after);
    $expect: 62.5% null null;
    @include assert-equal($margin, $expect,
      'Split nest use outer width, and no margins.');

    // isolate (margins)
    $span: (
      span: 3,
      location: 5,
      columns: 7,
      gutters: .5,
      column-width: 4em,
      output: isolate,
      math: fluid,
      flow: ltr,
      gutter-position: after,
    );
    $span: span-math($span);
    $margins: map-get($span, margin-before) map-get($span, margin-after);
    $expect: 60% -100%;
    @include assert-equal($margins, $expect,
      'Returns correction margins for isolation.');

    // after last (margins)
    $span: (
      span: 3,
      location: 5,
      columns: 7,
      gutters: .5,
      column-width: 4em,
      output: float,
      math: static,
      flow: ltr,
      gutter-position: after,
    );
    $span: span-math($span);
    $margins: map-get($span, margin-before) map-get($span, margin-after);
    $float: map-get($span, float);
    $expect: null 0;
    @include assert-equal($margins, $expect,
      'Removes correct margins when last.');

    @include assert-equal($float, to,
      'Sets the correct float when last.');

    // after first (margins)
    $span: (
      span: 3,
      location: 1,
      columns: 6,
      gutter-position: after,
    );
    $span: span-math($span);
    $margins: map-get($span, margin-before);
    $expect: null;
    @include assert-equal($margins, $expect,
      'No special margins for after first.');

    // full (margins & float)
    $span: (
      span: full,
      edge: full,
      columns: 8,
      gutters: .25,
      column-width: 4em,
      layout-method: float,
      layout-math: fluid,
      flow: ltr,
      gutter-position: split,
    );
    $span: span-math($span);
    $margins: map-get($span, margin-before) map-get($span, margin-after);
    $float: map-get($span, float);
    $expect: 1.25% 1.25%;
    @include assert-equal($margins, $expect,
      'Removes correct margins when full.');

    @include assert-equal($float, from,
      'Sets the correct float when full.');

    // before first (margins)
    $span: (
      span: 3,
      location: 1,
      columns: (1 2 3 2 1),
      gutters: .5,
      column-width: 4em,
      output: float,
      math: static,
      flow: ltr,
      gutter-position: before,
    );
    $span: span-math($span);
    $margins: map-get($span, margin-before) map-get($span, margin-after);
    $expect: 0 null;
    @include assert-equal($margins, $expect,
      'Removes correct margins when first.');

    // before last (margins)
    $span: (
      span: 3,
      location: 4,
      columns: 6,
      gutter-position: before,
    );
    $span: span-math($span);
    $margins: map-get($span, margin-after);
    $expect: null;
    @include assert-equal($margins, $expect,
      'No special margins for before last.');

  }

  // get-span-width
  // --------------

  @include test('[function] get-span-width') {
    // explicit
    $span: 30%;
    $map: (span: $span);
    $width: get-span-width($map);
    @include assert-equal($width, $span,
      'Explicit width is returned without changes.');

    // relative
    $map: (
      span: 5,
      location: 1,
      columns: 7,
      gutters: .5,
    );
    $width: get-span-width($map);
    @include assert-equal($width, 70%,
      'Returns correct fluid span width.');

    // full
    $map: (
      span: full,
      location: full,
      columns: 7,
      gutters: .5,
    );
    $width: get-span-width($map);
    @include assert-equal($width, 100%,
      'Returns correct full span width.');

    // relative inside-gutters
    $map: (
      span: 2,
      edge: last,
      columns: (1 2 3 2),
      gutters: .5,
      column-width: null,
      math: fluid,
      gutter-position: inside,
    );
    $width: get-span-width($map);
    @include assert-equal($width, 60%,
      'Returns correct width with inside gutters.');

    // inside no-gutters
    $map: (
      span: 4,
      columns: 8,
      gutters: .25,
      column-width: null,
      math: fluid,
      gutter-position: inside,
      gutter-override: no-gutters,
    );
    $width: get-span-width($map);
    @include assert-equal($width, 50%,
      'Returns correct width with no-gutters.');

    // split-gutters
    $map: (
      span: 4,
      location: 1,
      columns: 8,
      gutters: .25,
      column-width: null,
      math: fluid,
      gutter-position: split,
    );
    $width: get-span-width($map);
    @include assert-equal($width, 47.5%,
      'Returns correct width with split gutters.');

    // static
    $map: (
      span: 5,
      location: 1,
      columns: 7,
      gutters: .5,
      column-width: 4em,
      math: static,
    );
    $width: get-span-width($map);
    @include assert-equal($width, 28em,
      'Returns the correct static span width.');

    // static inside-gutters
    $map: (
      span: 4,
      location: 1,
      columns: 8,
      gutters: .25,
      column-width: 4em,
      math: static,
      gutter-position: inside,
    );
    $width: get-span-width($map);
    @include assert-equal($width, 20em,
      'Returns the correct static width with inside gutters.');

    // wide
    $map: (
      span: 5,
      location: 1,
      columns: 7,
      gutters: .5,
      spread: wide,
    );
    $width: get-span-width($map);
    @include assert-equal($width, 75%,
      'Returns the correct wide span width.');

    // wider
    $map: (
      span: 5,
      location: 1,
      columns: 7,
      gutters: .5,
      spread: wider,
    );
    $width: get-span-width($map);
    @include assert-equal($width, 80%,
      'Returns the correct wider span width.');

    // inside narrow
    $map: (
      span: 5,
      location: 1,
      columns: 8,
      gutters: .25,
      spread: narrow,
      gutter-position: inside,
    );
    $width: get-span-width($map);
    @include assert-equal($width, 60%,
      'Returns the correct narrow inside span width.');

    // inside wider
    $map: (
      span: 5,
      location: 1,
      columns: 8,
      gutters: .25,
      spread: wider,
      gutter-position: inside,
    );
    $width: get-span-width($map);
    @include assert-equal($width, 65%,
      'Returns the correct narrow inside span width.');

  }
}
