libreda-oasis 0.0.2

OASIS input/output for libreda-db.
Documentation

#![cfg(test)]

use std::fs::File;

use libreda_oasis::*;
use libreda_db::prelude::{Chip, HierarchyEdit, HierarchyBase, PropertyValue};

// TODO: Port unittests from KLayout.


fn test_read(test_name: &str) {
    let mut f = File::open(format!("./tests/klayout_test_data/t{}.oas", test_name)).unwrap();
    let mut layout = Chip::new();

    let reader = OASISStreamReader::default();
    let result = reader.read_layout(&mut f, &mut layout);

    dbg!(&layout);
    dbg!(&result);

    assert!(result.is_ok());
}

// TODO: Does not work yet because resolution is expected to be a positive integer value.
// #[test]
// fn test1_empty_file() {
//     test_read("1.1");
//     test_read("1.2");
//     test_read("1.3");
//     test_read("1.4");
//     test_read("1.5");
// }


#[test]
fn test2_cells() {
    test_read("2.1");
    test_read("2.2");
    test_read("2.4");
}

#[test]
#[should_panic]
fn test2_3_cells() {
    test_read("2.3"); // MUST FAIL
}

#[test]
#[should_panic]
fn test2_5_cells() {
    test_read("2.5"); // MUST FAIL
}

#[test]
fn test3_texts() {
    test_read("3.1");
}

#[test]
fn test4_rectangles() {
    test_read("4.1");
}

#[test]
fn test5_polygons() {
    // Test RECTANGLE.
    test_read("5.1");
}

#[test]
fn test6_paths() {
    // Test PATH.
    test_read("6.1");
}

#[test]
fn test8_placements() {
    test_read("8.1");
    test_read("8.2");
    // test_read("8.3");
    // test_read("8.4");
    // test_read("8.5");
    // // test_read("8.6");
    // test_read("8.7");
    // // test_read("8.8");
}

#[test]
fn test11_properties() {
    test_read("11.1");
    test_read("11.2");
    test_read("11.3");
    test_read("11.4");
}


// #[test]
// fn test13_layernames() {
//     test_read("13.1");
// }

#[test]
fn test_load_std_cell() {
    let filename = "INVX1_no_compression.oas";
    dbg!(format!("./tests/data/{}", filename));
    let mut f = File::open(format!("./tests/data/{}", filename)).unwrap();
    let mut layout = Chip::new();

    let result = OASISStreamReader::default()
        .read_layout(&mut f, &mut layout);

    dbg!(&layout);
    dbg!(&result);

    assert!(result.is_ok());
}

#[test]
fn test_load_and_store_std_cell() {
    let filename = "INVX1_no_compression.oas";
    dbg!(format!("./tests/data/{}", filename));
    let mut f = File::open(format!("./tests/data/{}", filename)).unwrap();
    let mut layout = Chip::new();

    let result = OASISStreamReader::default()
        .read_layout(&mut f, &mut layout);

    dbg!(&result);

    assert!(result.is_ok());

    // Write.
    let filename = "INVX1_no_compression_out.oas";
    dbg!(format!("./tests/data/{}", filename));
    let mut f = File::create(format!("./tests/data/{}", filename)).unwrap();

    let writer = OASISStreamWriter::default();
    let write_result = writer.write_layout(&mut f, &layout);

    dbg!(&write_result);
    assert!(write_result.is_ok());
}

#[test]
fn test_load_and_store_hierarchical_cell() {
    let filename = "three_cell_layout.oas";
    dbg!(format!("./tests/data/{}", filename));
    let mut f = File::open(format!("./tests/data/{}", filename)).unwrap();
    let mut layout = Chip::new();

    let result = OASISStreamReader::default()
        .read_layout(&mut f, &mut layout);

    dbg!(&result);

    assert!(result.is_ok());

    // Write.
    let filename = "three_cell_layout_out.oas";
    dbg!(format!("./tests/data/{}", filename));
    let mut f = File::create(format!("./tests/data/{}", filename)).unwrap();

    let write_result = OASISStreamWriter::default()
        .write_layout(&mut f, &layout);

    dbg!(&write_result);
    assert!(write_result.is_ok());
}


#[test]
fn test_load_layout_with_properties() {
    let filename = "simple_with_properties.oas";
    dbg!(format!("./tests/data/{}", filename));
    let mut f = File::open(format!("./tests/data/{}", filename)).unwrap();
    let mut layout = Chip::new();

    let result = OASISStreamReader::default()
        .read_layout(&mut f, &mut layout);

    dbg!(&result);

    assert!(result.is_ok());

    // TODO:
    // Get GDS standard property from the layout.
    let top_cell_name = layout.get_chip_property(&"S_TOP_CELL".into()).unwrap();

    if let PropertyValue::String(name) = top_cell_name {
        assert_eq!(name.as_str(), "TOP");
    } else {
        assert!(false);
    }

    //
    // let top = layout.cell_by_name("TOP").unwrap();
    // let sub = layout.cell_by_name("SUB").unwrap();
    //
    // // Test accessing the properties.
    // assert!(sub.property("name").is_some());
    // assert_eq!(sub.property_str("name").unwrap(), Rc::new("MySubCell1".to_string()));
    //
    // for inst in top.each_inst() {
    //     assert!(inst.property("name").is_some())
    // }
    //
    // // The shapes in the cell 'SUB' should all have a property 'name'.
    // let layer = layout.find_layer(1, 0).unwrap();
    // for shape in sub.each_shape(layer) {
    //     assert!(shape.property("name").is_some())
    // }
}

// #[test]
// fn test_load_and_store_big_layout() {
//     // This test could be very slow because of the debug output.
//
//     let filename = "big_layout.oas";
//     dbg!(format!("./tests/data/{}", filename));
//     let mut f = File::open(format!("./tests/data/{}", filename)).unwrap();
//     let mut layout = Layout::new();
//     let mut buf = BufReader::new(f);
//     let result = read_layout(&mut buf, &mut layout);
//
//     dbg!(&result);
//
//     assert!(result.is_ok());
//
//     // Write.
//     let filename = "big_layout.out.oas";
//     dbg!(format!("./tests/data/{}", filename));
//     let mut f = File::create(format!("./tests/data/{}", filename)).unwrap();
//     let mut buf = BufWriter::new(&mut f);
//     let write_result = write_layout(&mut buf, &layout, &WriterConfig::default());
//
//     dbg!(&write_result);
//     assert!(write_result.is_ok());
// }

/// Create a layout containing some paths, write it to the OASIS format, read it back and check that the result is correct.
#[test]
fn test_write_read_path() {
    use libreda_db::prelude::*;

    let mut layout = Chip::new();
    layout.set_dbu(1);
    let layer = layout.find_or_create_layer(1, 0);
    let top_cell = layout.create_cell("TOP".into());

    // Add path to the top cell.
    let path = Path::new_extended(vec![(0, 0), (1, 1)], 4, 3, 7);
    layout.insert_shape(&top_cell, &layer, path.into());


    let mut buffer = Vec::new();
    OASISStreamWriter::default().
        write_layout(&mut buffer, &layout).unwrap();

    let mut layout2 = Chip::new();
    OASISStreamReader::default().
        read_layout(&mut buffer[..].as_ref(), &mut layout2).unwrap();

    let mut paths2 = vec![];
    layout2.for_each_shape(&layout2.cell_by_name("TOP").unwrap(), &layer,
                           |_id, g| paths2.push(g.clone()));

    let mut paths1 = vec![];
    layout.for_each_shape(&layout.cell_by_name("TOP").unwrap(), &layer,
                           |_id, g| paths1.push(g.clone()));

    assert_eq!(paths2, paths1);
}