//
// Copyright 2024 Formata, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import './geometry_import.stof' as self.Geometry;
fields: {
super.Geometry.Point point: {
x: +2cm
y: +1cm
z: +3cm
}
point2: {
x: 2cm
y: 1cm
z: 3cm
}
#[test]
fn typed_point_field() {
let point = self.point;
assertEq(point.Point2D::len().round(2), 2.24cm);
assertEq(point.len().round(2), 3.74cm);
}
#[test]
fn untyped_point_field_as() {
let point2 = self.point2 as super.Geometry.Point;
assertEq(point2.Point2D::len().round(2), 2.24cm);
assertEq(point2.len().round(2), 3.74cm);
}
#[test]
fn untyped_point_field() {
let point2: super.Geometry.Point = self.point2;
assertEq(point2.Point2D::len().round(2), 2.24cm);
assertEq(point2.len().round(2), 3.74cm);
}
#[test]
fn instance_of() {
assert(self.point.instanceOf("Point"));
assert(self.point.instanceOf("Point2D"));
assertEq(self.point.typename(), 'Point');
assertEq(typename self.point, 'Point');
let pt = new Point2D {};
assert(pt.instanceOf("Point2D"));
assertNot(pt.instanceOf("Point"));
assertEq(pt.typename(), 'Point2D');
assertEq(typename pt, 'Point2D');
}
#[test]
fn typestack() {
let stack = self.point.typestack();
assertEq(stack, ['Point', 'Point2D']);
}
}
defaults: {
#[test]
fn default_point_values() {
let point = new super.Geometry.Point {};
assertEq(point.x, 0);
assertEq(point.y, 0);
assertEq(point.z, 0);
}
#[test]
fn default_2d_values() {
let point = new super.Geometry.Point2D {};
assertEq(point.x, 0);
assertEq(point.y, 0);
assertEq(point.z, null);
}
}
local: {
#[test]
fn create_local_point() {
let point = new super.Geometry.Point {
x: 2cm
y: 1cm
z: 3cm
};
assertEq(point.Point2D::len().round(2), 2.24cm);
assertEq(point.len().round(2), 3.74cm);
}
#[test]
fn create_local_point_type() {
let point: super.Geometry.Point = new {
x: 2cm
y: 1cm
z: 3cm
};
assertEq(point.Point2D::len().round(2), 2.24cm);
assertEq(point.len().round(2), 3.74cm);
}
#[test]
fn create_local_point_as() {
let point = new {
x: 2cm
y: 1cm
z: 3cm
} as super.Geometry.Point;
assertEq(point.Point2D::len().round(2), 2.24cm);
assertEq(point.Point::len().round(2), 3.74cm);
}
}
private: {
dec: {
// Private here means we can only construct this type from this object/scope
#[private]
type Point {
val: m;
fn getVal(): m { return self.val; }
}
#[test]
fn can_create_point() {
// Types are searched for in the current scope first, then upwards..
let pt = new Point { val: 3m; };
assertEq(pt.getVal(), 3m);
}
}
/* Uncommenting this will result in a "compile-time" error because the type is private
#[test]
fn cannot_find_point() {
let pt = new dec.Point { val: 3m; };
assertEq(pt.getVal(), 3m);
}
*/
}
extends: {
#[private]
type MyType extends super.Geometry.Point {
message: str = 'My Message'
fn print(): str {
return `(${self.x}, ${self.y}, ${self.z})`;
}
}
#[test]
fn my_type() {
let instance = new MyType { x: 22m, y: 3 };
assertEq(instance.x, 22);
assertEq(instance.y, 3);
assertEq(instance.z, 0);
assertEq(instance.message, 'My Message');
assertEq(typename instance, 'MyType');
assertEq(typeof instance, 'obj');
assertEq(instance.len().round(4), 22.2036);
assertEq(instance.print(), '(22m, 3, 0)');
}
}