// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`class.js 1`] = `
====================================options=====================================
parsers: ["flow", "babylon"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
/**
 * @flow
 */

var z: number = 123;

class Foo {
  get goodGetterNoAnnotation() { return 4; }
  get goodGetterWithAnnotation(): number { return 4; }

  set goodSetterNoAnnotation(x) { z = x; }
  set goodSetterWithAnnotation(x: number) { z = x; }

  get propWithMatchingGetterAndSetter(): number { return 4; }
  set propWithMatchingGetterAndSetter(x: number) { }

  // The getter and setter need not have the same type - no error
  get propWithSubtypingGetterAndSetter(): ?number { return 4; }
  set propWithSubtypingGetterAndSetter(x: number) { }

  // The getter and setter need not have the same type - no error
  set propWithSubtypingGetterAndSetterReordered(x: number) { }
  get propWithSubtypingGetterAndSetterReordered(): ?number { return 4; }

  get propWithMismatchingGetterAndSetter(): number { return 4; }
  set propWithMismatchingGetterAndSetter(x: string) { } // doesn't match getter (OK)

  propOverriddenWithGetter: number;
  get propOverriddenWithGetter() { return "hello"; }

  propOverriddenWithSetter: number;
  set propOverriddenWithSetter(x: string) { }

  set [z](x: string) {}
  get [z](): string { return string; }
};

var foo = new Foo();

// Test getting properties with getters
var testGetterNoError1: number = foo.goodGetterNoAnnotation;
var testGetterNoError2: number = foo.goodGetterWithAnnotation;

var testGetterWithError1: string = foo.goodGetterNoAnnotation; // Error number ~> string
var testGetterWithError2: string = foo.goodGetterWithAnnotation; // Error number ~> string

// Test setting properties with getters
foo.goodSetterNoAnnotation = 123;
foo.goodSetterWithAnnotation = 123;

// TODO: Why does no annotation mean no error?
foo.goodSetterNoAnnotation = "hello"; // Error string ~> number
foo.goodSetterWithAnnotation = "hello"; // Error string ~> number

var testSubtypingGetterAndSetter: number = foo.propWithSubtypingGetterAndSetter; // Error ?number ~> number

var testPropOverridenWithGetter: number = foo.propOverriddenWithGetter; // Error string ~> number
foo.propOverriddenWithSetter = 123; // Error number ~> string

=====================================output=====================================
/**
 * @flow
 */

var z: number = 123;

class Foo {
  get goodGetterNoAnnotation() {
    return 4;
  }
  get goodGetterWithAnnotation(): number {
    return 4;
  }

  set goodSetterNoAnnotation(x) {
    z = x;
  }
  set goodSetterWithAnnotation(x: number) {
    z = x;
  }

  get propWithMatchingGetterAndSetter(): number {
    return 4;
  }
  set propWithMatchingGetterAndSetter(x: number) {}

  // The getter and setter need not have the same type - no error
  get propWithSubtypingGetterAndSetter(): ?number {
    return 4;
  }
  set propWithSubtypingGetterAndSetter(x: number) {}

  // The getter and setter need not have the same type - no error
  set propWithSubtypingGetterAndSetterReordered(x: number) {}
  get propWithSubtypingGetterAndSetterReordered(): ?number {
    return 4;
  }

  get propWithMismatchingGetterAndSetter(): number {
    return 4;
  }
  set propWithMismatchingGetterAndSetter(x: string) {} // doesn't match getter (OK)

  propOverriddenWithGetter: number;
  get propOverriddenWithGetter() {
    return "hello";
  }

  propOverriddenWithSetter: number;
  set propOverriddenWithSetter(x: string) {}

  set [z](x: string) {}
  get [z](): string {
    return string;
  }
}

var foo = new Foo();

// Test getting properties with getters
var testGetterNoError1: number = foo.goodGetterNoAnnotation;
var testGetterNoError2: number = foo.goodGetterWithAnnotation;

var testGetterWithError1: string = foo.goodGetterNoAnnotation; // Error number ~> string
var testGetterWithError2: string = foo.goodGetterWithAnnotation; // Error number ~> string

// Test setting properties with getters
foo.goodSetterNoAnnotation = 123;
foo.goodSetterWithAnnotation = 123;

// TODO: Why does no annotation mean no error?
foo.goodSetterNoAnnotation = "hello"; // Error string ~> number
foo.goodSetterWithAnnotation = "hello"; // Error string ~> number

var testSubtypingGetterAndSetter: number = foo.propWithSubtypingGetterAndSetter; // Error ?number ~> number

var testPropOverridenWithGetter: number = foo.propOverriddenWithGetter; // Error string ~> number
foo.propOverriddenWithSetter = 123; // Error number ~> string

================================================================================
`;

exports[`declare_class.js 1`] = `
====================================options=====================================
parsers: ["flow", "babylon"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
/**
 * @flow
 */

var z: number = 123;

declare class Foo {
  get goodGetterWithAnnotation(): number;
  set goodSetterWithAnnotation(x: number): void;

  get propWithMatchingGetterAndSetter(): number;
  set propWithMatchingGetterAndSetter(x: number): void;

  // The getter and setter need not have the same type - no error
  get propWithSubtypingGetterAndSetter(): ?number;
  set propWithSubtypingGetterAndSetter(x: number): void;

  // The getter and setter need not have the same type - no error
  set propWithSubtypingGetterAndSetterReordered(x: number): void;
  get propWithSubtypingGetterAndSetterReordered(): ?number;

  get propWithMismatchingGetterAndSetter(): number;
  set propWithMismatchingGetterAndSetter(x: string): void; // doesn't match getter (OK)

  propOverriddenWithGetter: number;
  get propOverriddenWithGetter(): string;

  propOverriddenWithSetter: number;
  set propOverriddenWithSetter(x: string): void;
};

var foo = new Foo();

// Test getting properties with getters
var testGetterNoError2: number = foo.goodGetterWithAnnotation;

var testGetterWithError2: string = foo.goodGetterWithAnnotation; // Error number ~> string

// Test setting properties with getters
foo.goodSetterWithAnnotation = 123;

foo.goodSetterWithAnnotation = "hello"; // Error string ~> number

var testSubtypingGetterAndSetter: number = foo.propWithSubtypingGetterAndSetter; // Error ?number ~> number

var testPropOverridenWithGetter: number = foo.propOverriddenWithGetter; // Error string ~> number
foo.propOverriddenWithSetter = 123; // Error number ~> string

=====================================output=====================================
/**
 * @flow
 */

var z: number = 123;

declare class Foo {
  get goodGetterWithAnnotation(): number;
  set goodSetterWithAnnotation(x: number): void;

  get propWithMatchingGetterAndSetter(): number;
  set propWithMatchingGetterAndSetter(x: number): void;

  // The getter and setter need not have the same type - no error
  get propWithSubtypingGetterAndSetter(): ?number;
  set propWithSubtypingGetterAndSetter(x: number): void;

  // The getter and setter need not have the same type - no error
  set propWithSubtypingGetterAndSetterReordered(x: number): void;
  get propWithSubtypingGetterAndSetterReordered(): ?number;

  get propWithMismatchingGetterAndSetter(): number;
  set propWithMismatchingGetterAndSetter(x: string): void; // doesn't match getter (OK)

  propOverriddenWithGetter: number;
  get propOverriddenWithGetter(): string;

  propOverriddenWithSetter: number;
  set propOverriddenWithSetter(x: string): void;
}

var foo = new Foo();

// Test getting properties with getters
var testGetterNoError2: number = foo.goodGetterWithAnnotation;

var testGetterWithError2: string = foo.goodGetterWithAnnotation; // Error number ~> string

// Test setting properties with getters
foo.goodSetterWithAnnotation = 123;

foo.goodSetterWithAnnotation = "hello"; // Error string ~> number

var testSubtypingGetterAndSetter: number = foo.propWithSubtypingGetterAndSetter; // Error ?number ~> number

var testPropOverridenWithGetter: number = foo.propOverriddenWithGetter; // Error string ~> number
foo.propOverriddenWithSetter = 123; // Error number ~> string

================================================================================
`;

exports[`object.js 1`] = `
====================================options=====================================
parsers: ["flow", "babylon"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
/**
 * @flow
 */

var z: number = 123;

class A {}
class B extends A {}
class C extends A {}

var obj = {
  get goodGetterNoAnnotation() { return 4; },
  get goodGetterWithAnnotation(): number { return 4; },

  set goodSetterNoAnnotation(x) { z = x; },
  set goodSetterWithAnnotation(x: number) { z = x; },

  get propWithMatchingGetterAndSetter(): number { return 4; },
  set propWithMatchingGetterAndSetter(x: number) { },

  // The getter and setter need not have the same type
  get propWithSubtypingGetterAndSetter(): ?number { return 4; }, // OK
  set propWithSubtypingGetterAndSetter(x: number) { },

  set propWithSubtypingGetterAndSetterReordered(x: number) { }, // OK
  get propWithSubtypingGetterAndSetterReordered(): ?number { return 4; },

  get exampleOfOrderOfGetterAndSetter(): A { return new A(); },
  set exampleOfOrderOfGetterAndSetter(x: B) {},

  set exampleOfOrderOfGetterAndSetterReordered(x: B) {},
  get exampleOfOrderOfGetterAndSetterReordered(): A { return new A(); },

  set [z](x: string) {},
  get [z](): string { return string; },
};



// Test getting properties with getters
var testGetterNoError1: number = obj.goodGetterNoAnnotation;
var testGetterNoError2: number = obj.goodGetterWithAnnotation;

var testGetterWithError1: string = obj.goodGetterNoAnnotation; // Error number ~> string
var testGetterWithError2: string = obj.goodGetterWithAnnotation; // Error number ~> string

// Test setting properties with getters
obj.goodSetterNoAnnotation = 123;
obj.goodSetterWithAnnotation = 123;

obj.goodSetterNoAnnotation = "hello"; // Error string ~> number
obj.goodSetterWithAnnotation = "hello"; // Error string ~> number

var testSubtypingGetterAndSetter: number = obj.propWithSubtypingGetterAndSetter; // Error ?number ~> number

// When building this feature, it was tempting to flow the setter into the
// getter and then use either the getter or setter as the type of the property.
// This example shows the danger of using the getter's type
obj.exampleOfOrderOfGetterAndSetter = new C(); // Error C ~> B

// And this example shows the danger of using the setter's type.
var testExampleOrOrderOfGetterAndSetterReordered: number =
  obj.exampleOfOrderOfGetterAndSetterReordered; // Error A ~> B

=====================================output=====================================
/**
 * @flow
 */

var z: number = 123;

class A {}
class B extends A {}
class C extends A {}

var obj = {
  get goodGetterNoAnnotation() {
    return 4;
  },
  get goodGetterWithAnnotation(): number {
    return 4;
  },

  set goodSetterNoAnnotation(x) {
    z = x;
  },
  set goodSetterWithAnnotation(x: number) {
    z = x;
  },

  get propWithMatchingGetterAndSetter(): number {
    return 4;
  },
  set propWithMatchingGetterAndSetter(x: number) {},

  // The getter and setter need not have the same type
  get propWithSubtypingGetterAndSetter(): ?number {
    return 4;
  }, // OK
  set propWithSubtypingGetterAndSetter(x: number) {},

  set propWithSubtypingGetterAndSetterReordered(x: number) {}, // OK
  get propWithSubtypingGetterAndSetterReordered(): ?number {
    return 4;
  },

  get exampleOfOrderOfGetterAndSetter(): A {
    return new A();
  },
  set exampleOfOrderOfGetterAndSetter(x: B) {},

  set exampleOfOrderOfGetterAndSetterReordered(x: B) {},
  get exampleOfOrderOfGetterAndSetterReordered(): A {
    return new A();
  },

  set [z](x: string) {},
  get [z](): string {
    return string;
  }
};

// Test getting properties with getters
var testGetterNoError1: number = obj.goodGetterNoAnnotation;
var testGetterNoError2: number = obj.goodGetterWithAnnotation;

var testGetterWithError1: string = obj.goodGetterNoAnnotation; // Error number ~> string
var testGetterWithError2: string = obj.goodGetterWithAnnotation; // Error number ~> string

// Test setting properties with getters
obj.goodSetterNoAnnotation = 123;
obj.goodSetterWithAnnotation = 123;

obj.goodSetterNoAnnotation = "hello"; // Error string ~> number
obj.goodSetterWithAnnotation = "hello"; // Error string ~> number

var testSubtypingGetterAndSetter: number = obj.propWithSubtypingGetterAndSetter; // Error ?number ~> number

// When building this feature, it was tempting to flow the setter into the
// getter and then use either the getter or setter as the type of the property.
// This example shows the danger of using the getter's type
obj.exampleOfOrderOfGetterAndSetter = new C(); // Error C ~> B

// And this example shows the danger of using the setter's type.
var testExampleOrOrderOfGetterAndSetterReordered: number =
  obj.exampleOfOrderOfGetterAndSetterReordered; // Error A ~> B

================================================================================
`;

exports[`object_type.js 1`] = `
====================================options=====================================
parsers: ["flow", "babylon"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
/**
 * @flow
 */

var z: number = 123;

class A {}
class B extends A {}
class C extends A {}

type T = {
  get goodGetterWithAnnotation(): number,
  set goodSetterWithAnnotation(x: number): void,

  get propWithMatchingGetterAndSetter(): number,
  set propWithMatchingGetterAndSetter(x: number): void,

  // The getter and setter need not have the same type
  get propWithSubtypingGetterAndSetter(): ?number, // OK
  set propWithSubtypingGetterAndSetter(x: number): void,

  set propWithSubtypingGetterAndSetterReordered(x: number): void, // OK
  get propWithSubtypingGetterAndSetterReordered(): ?number,

  get exampleOfOrderOfGetterAndSetter(): A,
  set exampleOfOrderOfGetterAndSetter(x: B): void,

  set exampleOfOrderOfGetterAndSetterReordered(x: B): void,
  get exampleOfOrderOfGetterAndSetterReordered(): A,
};

function test(obj: T) {
  // Test getting properties with getters
  var testGetterNoError2: number = obj.goodGetterWithAnnotation;

  var testGetterWithError2: string = obj.goodGetterWithAnnotation; // Error number ~> string

  // Test setting properties with getters
  obj.goodSetterWithAnnotation = 123;

  obj.goodSetterWithAnnotation = "hello"; // Error string ~> number

  var testSubtypingGetterAndSetter: number = obj.propWithSubtypingGetterAndSetter; // Error ?number ~> number

  // When building this feature, it was tempting to flow the setter into the
  // getter and then use either the getter or setter as the type of the
  // property. This example shows the danger of using the getter's type
  obj.exampleOfOrderOfGetterAndSetter = new C(); // Error C ~> B

  // And this example shows the danger of using the setter's type.
  var testExampleOrOrderOfGetterAndSetterReordered: number =
    obj.exampleOfOrderOfGetterAndSetterReordered; // Error A ~> B
}

=====================================output=====================================
/**
 * @flow
 */

var z: number = 123;

class A {}
class B extends A {}
class C extends A {}

type T = {
  get goodGetterWithAnnotation(): number,
  set goodSetterWithAnnotation(x: number): void,

  get propWithMatchingGetterAndSetter(): number,
  set propWithMatchingGetterAndSetter(x: number): void,

  // The getter and setter need not have the same type
  get propWithSubtypingGetterAndSetter(): ?number, // OK
  set propWithSubtypingGetterAndSetter(x: number): void,

  set propWithSubtypingGetterAndSetterReordered(x: number): void, // OK
  get propWithSubtypingGetterAndSetterReordered(): ?number,

  get exampleOfOrderOfGetterAndSetter(): A,
  set exampleOfOrderOfGetterAndSetter(x: B): void,

  set exampleOfOrderOfGetterAndSetterReordered(x: B): void,
  get exampleOfOrderOfGetterAndSetterReordered(): A
};

function test(obj: T) {
  // Test getting properties with getters
  var testGetterNoError2: number = obj.goodGetterWithAnnotation;

  var testGetterWithError2: string = obj.goodGetterWithAnnotation; // Error number ~> string

  // Test setting properties with getters
  obj.goodSetterWithAnnotation = 123;

  obj.goodSetterWithAnnotation = "hello"; // Error string ~> number

  var testSubtypingGetterAndSetter: number =
    obj.propWithSubtypingGetterAndSetter; // Error ?number ~> number

  // When building this feature, it was tempting to flow the setter into the
  // getter and then use either the getter or setter as the type of the
  // property. This example shows the danger of using the getter's type
  obj.exampleOfOrderOfGetterAndSetter = new C(); // Error C ~> B

  // And this example shows the danger of using the setter's type.
  var testExampleOrOrderOfGetterAndSetterReordered: number =
    obj.exampleOfOrderOfGetterAndSetterReordered; // Error A ~> B
}

================================================================================
`;

exports[`react.js 1`] = `
====================================options=====================================
parsers: ["flow", "babylon"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
/**
 * @flow
 */

import React from "react";

const Example = React.createClass({
  propTypes: {
    get a() { return React.PropTypes.number.isRequired; },
    set b(x: number) { this.c = x; },
    c: React.PropTypes.string,
  }
});

(<Example />); // error: property \`a\` not found
(<Example a={0} />); // ok
(<Example a="bad" />); // error: number ~> string
(<Example a={0} c={0} />); // error: number ~> string

=====================================output=====================================
/**
 * @flow
 */

import React from "react";

const Example = React.createClass({
  propTypes: {
    get a() {
      return React.PropTypes.number.isRequired;
    },
    set b(x: number) {
      this.c = x;
    },
    c: React.PropTypes.string
  }
});

<Example />; // error: property \`a\` not found
<Example a={0} />; // ok
<Example a="bad" />; // error: number ~> string
<Example a={0} c={0} />; // error: number ~> string

================================================================================
`;

exports[`variance.js 1`] = `
====================================options=====================================
parsers: ["flow", "babylon"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
/* @flow */

class A {}
class B extends A {}
class C extends B {}

declare var a: A;
declare var b: B;
declare var c: C;

class Base {
  x: B;
  +pos: B;
  -neg: B;
  get get(): B { return this.x };
  set set(value: B): void { this.x = value };
  get getset(): B { return this.x };
  set getset(value: B): void { this.x = value };
}

(class extends Base {
  // error: getter incompatible with read/write property
  get x(): B { return b }
});

(class extends Base {
  // error: setter incompatible with read/write property
  set x(value: B): void {}
});

(class extends Base {
  // ok: get/set co/contra with read/write property, resp.
  get x(): C { return c }
  set x(value: A): void {}
});

(class extends Base {
  // error: setter incompatible with read-only property
  set pos(value: B): void {}
});

(class extends Base {
  // ok: getter covariant with read-only property
  get pos(): C { return c }
});

(class extends Base {
  // error: getter incompatible with write-only property
  get neg(): B { return b }
});

(class extends Base {
  // ok: setter contravariant with write-only property
  set neg(value: A): void {}
});

(class extends Base {
  // ok: read/write covariant with getter
  get: C;
});

(class extends Base {
  // ok: read/write contravariant with setter
  set: A;
});

(class extends Base {
  // ok: read/write invariant with get/set
  getset: B;
});

=====================================output=====================================
/* @flow */

class A {}
class B extends A {}
class C extends B {}

declare var a: A;
declare var b: B;
declare var c: C;

class Base {
  x: B;
  +pos: B;
  -neg: B;
  get get(): B {
    return this.x;
  }
  set set(value: B): void {
    this.x = value;
  }
  get getset(): B {
    return this.x;
  }
  set getset(value: B): void {
    this.x = value;
  }
}

(class extends Base {
  // error: getter incompatible with read/write property
  get x(): B {
    return b;
  }
});

(class extends Base {
  // error: setter incompatible with read/write property
  set x(value: B): void {}
});

(class extends Base {
  // ok: get/set co/contra with read/write property, resp.
  get x(): C {
    return c;
  }
  set x(value: A): void {}
});

(class extends Base {
  // error: setter incompatible with read-only property
  set pos(value: B): void {}
});

(class extends Base {
  // ok: getter covariant with read-only property
  get pos(): C {
    return c;
  }
});

(class extends Base {
  // error: getter incompatible with write-only property
  get neg(): B {
    return b;
  }
});

(class extends Base {
  // ok: setter contravariant with write-only property
  set neg(value: A): void {}
});

(class extends Base {
  // ok: read/write covariant with getter
  get: C;
});

(class extends Base {
  // ok: read/write contravariant with setter
  set: A;
});

(class extends Base {
  // ok: read/write invariant with get/set
  getset: B;
});

================================================================================
`;
