yuescript-src 0.13.6

Sources of Yuescript and logic to build them.
Documentation

describe "class", ->
  it "should make a class with constructor", ->
    class Thing
      new: =>
        @color = "blue"

    instance = Thing!

    assert.same instance, { color: "blue" }

  it "should have instance methods", ->
    class Thing
      get_color: => @color

      new: =>
        @color = "blue"

    instance = Thing!
    assert.same instance\get_color!, "blue"

  it "should have base properies from class", ->
    class Thing
      color: "blue"
      get_color: => @color

    instance = Thing!
    assert.same instance\get_color!, "blue"
    assert.same Thing.color, "blue"

  it "should inherit another class", ->
    class Base
      get_property: => @[@property]

      new: (@property) =>

    class Thing extends Base
      color: "green"

    instance = Thing "color"
    assert.same instance\get_property!, "green"


  it "should have class properties", ->
    class Base
    class Thing extends Base

    instance = Thing!

    assert.same Base.__name, "Base"
    assert.same Thing.__name, "Thing"
    assert.is_true Thing.__parent == Base

    assert.is_true instance.__class == Thing

  it "should have name when assigned", ->
    Thing = class
    assert.same Thing.__name, "Thing"

  it "should not expose class properties on instance", ->
    class Thing
      @height: 10

    Thing.color = "blue"

    instance = Thing!
    assert.same instance.color, nil
    assert.same instance.height, nil

  it "should expose new things added to __base", ->
    class Thing

    instance = Thing!
    Thing.__base.color = "green"

    assert.same instance.color, "green"

  it "should call with correct receiver", ->
    local instance

    class Thing
      is_class: => assert.is_true @ == Thing
      is_instance: => assert.is_true @ == instance

      go: =>
        @@is_class!
        @is_instance!

    instance = Thing!
    instance\go!

  it "should have class properies take precedence over base properties", ->
    class Thing
      @prop: "hello"
      prop: "world"

    assert.same "hello", Thing.prop

  describe "super", ->
    it "should call super constructor", ->
      class Base
        new: (@property) =>

      class Thing extends Base
        new: (@name) =>
          super "name"

      instance = Thing "the_thing"

      assert.same instance.property, "name"
      assert.same instance.name, "the_thing"

    it "should call super method", ->
      class Base
        _count: 111
        counter: => @_count

      class Thing extends Base
        counter: => "%08d"\format super!

      instance = Thing!
      assert.same instance\counter!, "00000111"

    it "should call other method from super", ->
      class Base
        _count: 111
        counter: =>
          @_count

      class Thing extends Base
        other_method: => super\counter!

      instance = Thing!
      assert.same instance\other_method!, 111

    it "should get super class", ->
      class Base
      class Thing extends Base
        get_super: => super

      instance = Thing!
      assert.is_true instance\get_super! == Base

    it "should get a bound method from super", ->
      class Base
        count: 1
        get_count: => @count

      class Thing extends Base
        get_count: => "this is wrong"
        get_method: => super\get_count

      instance = Thing!
      assert.same instance\get_method!!, 1

    it "class properties take precedence in super class over base", ->
      class Thing
        @prop: "hello"
        prop: "world"

      class OtherThing extends Thing

      assert.same "hello", OtherThing.prop

    it "gets value from base in super class", ->
      class Thing
        prop: "world"

      class OtherThing extends Thing
      assert.same "world", OtherThing.prop

    it "should let parent be replaced on class", ->
      class A
        @prop: "yeah"
        cool: => 1234
        plain: => "a"

      class B
        @prop: "okay"
        cool: => 9999
        plain: => "b"

      class Thing extends A
        cool: =>
          super! + 1

        get_super: =>
          super

      instance = Thing!

      assert.same "a", instance\plain!
      assert.same 1235, instance\cool!
      assert A == instance\get_super!, "expected super to be B"

      Thing.__parent = B
      setmetatable Thing.__base, B.__base

      assert.same "b", instance\plain!
      assert.same 10000, instance\cool!
      assert B == instance\get_super!, "expected super to be B"

    it "should resolve many levels of super", ->
      class One
        a: =>
          1

      class Two extends One
        a: =>
          super! + 2

      class Three extends Two
        a: =>
          super! + 3

      i = Three!

      assert.same 6, i\a!


    it "should resolve many levels of super with a gap", ->
      class One
        a: =>
          1

      class Two extends One

      class Three extends Two
        a: =>
          super! + 3

      class Four extends Three
        a: =>
          super! + 4

      i = Four!

      assert.same 8, i\a!


    it "should call correct class/instance super methods", ->
      class Base
        doit: =>
          "instance"

        @doit: =>
          "class"

      class One extends Base
        doit: => super!
        @doit: => super!

      assert.same "instance", One!\doit!
      assert.same "class", One\doit!


    it "should resolve many levels of super on class methods", ->
      class One
        @a: =>
          1

      class Two extends One

      class Three extends Two
        @a: =>
          super! + 3

      class Four extends Three
        @a: =>
          super! + 4

      assert.same 8, Four\a!

    it "super should still work when method wrapped", ->
      add_some = (opts) ->
        => opts.amount + opts[1] @

      class Base
        value: => 1

      class Sub extends Base
        value: add_some {
          amount: 12
          =>
            super! + 100
        }

      class OtherSub extends Base
        value: if true
          => 5 + super!
        else
          => 2 + super!

      assert.same 1 + 100 + 12, Sub!\value!
      assert.same 6, OtherSub!\value!