stof 0.3.24

Stof is a unified data interface and interchange format for creating, sharing, and manipulating data. Stof removes the fragile and cumbersome parts of combining and using data in applications.
Documentation
//
// 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)');
    }
}