Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
ubruhin committed Jan 7, 2025
1 parent 3325908 commit cd610af
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 7 deletions.
1 change: 1 addition & 0 deletions .reuse/dep5
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Files:
README.md
src/**.rs
src/web/version.txt
tests/**.rs
update_web_files.sh
Copyright: LibrePCB Developers
License: MIT
Expand Down
21 changes: 14 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,13 @@ impl ToJson for RefMap {
/// // Add BOM rows (designators and their footprint IDs).
/// ibom.bom_front.push(vec![RefMap::new("R1", id)]);
/// ```
///
/// <div class="warning">
/// Please note that this struct is not completely fool-proof regarding as
/// it does not validate lots of the added data, so make sure you add only
/// valid BOM data. Only the most important things are validated: Footprint IDs
/// in BOM rows, and number of fields in footprints.
/// </div>
#[non_exhaustive]
pub struct InteractiveHtmlBom {
// Metadata
Expand All @@ -537,29 +544,29 @@ pub struct InteractiveHtmlBom {
/// Custom field names, listed as columns
pub fields: Vec<String>,

/// User-defined JavaScript
/// User-defined HTML header
///
/// <div class="warning">
/// This should be used carefully as we neither guarantee forward- nor
/// backward-compatibility.
/// </div>
pub user_js: String,
pub user_header: String,

/// User-defined HTML header
/// User-defined HTML footer
///
/// <div class="warning">
/// This should be used carefully as we neither guarantee forward- nor
/// backward-compatibility.
/// </div>
pub user_header: String,
pub user_footer: String,

/// User-defined HTML footer
/// User-defined JavaScript
///
/// <div class="warning">
/// This should be used carefully as we neither guarantee forward- nor
/// backward-compatibility.
/// </div>
pub user_footer: String,
pub user_js: String,

/// Drawings (PCB edges, silkscreen, fabrication)
pub drawings: Vec<Drawing>,
Expand Down Expand Up @@ -651,7 +658,7 @@ impl InteractiveHtmlBom {
}

/// Generate HTML
pub fn generate(&self) -> Result<String, String> {
pub fn generate_html(&self) -> Result<String, String> {
// Validate footprint IDs.
for bom in [&self.bom_back, &self.bom_front, &self.bom_both] {
for row in bom {
Expand Down
181 changes: 181 additions & 0 deletions tests/integration_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
use interactive_html_bom::*;

#[test]
fn test_empty() {
let bom = InteractiveHtmlBom::new(
"Test Title",
"Test Company",
"Test Revision",
"Test Date",
(0.0, 0.0),
(0.0, 0.0),
);

let html = bom.generate_html().unwrap();
assert!(html.contains("<html"));
}

#[test]
fn test_simple() {
let mut bom = InteractiveHtmlBom::new(
"Test Title",
"Test Company",
"Test Revision",
"Test Date",
(0.0, 0.0),
(100.0, 100.0),
);

bom.dark_mode = true;
bom.show_silkscreen = false;
bom.show_fabrication = false;
bom.checkboxes = vec!["Foo".into(), "Bar".into()];
bom.fields = vec!["Field 1".into(), "Field 2".into()];
bom.user_header = "<!-- header -->".into();
bom.user_footer = "<!-- footer -->".into();
bom.user_js = "<!-- js -->".into();

bom
.drawings
.push(Drawing::new(DrawingLayer::Edge, "", 0.1, false));
bom.drawings.push(Drawing::new(
DrawingLayer::SilkscreenFront,
"M 0 0",
0.1,
false,
));
bom
.drawings
.push(Drawing::new(DrawingLayer::SilkscreenBack, "", 0.1, false));
bom.drawings.push(Drawing::new(
DrawingLayer::FabricationFront,
"M 0 0",
0.1,
false,
));
bom.drawings.push(Drawing::new(
DrawingLayer::FabricationBack,
"M 0 0",
0.1,
false,
));

bom.tracks.push(Track::new(
Layer::Front,
(0.0, 0.0),
(100.0, 100.0),
1.0,
None,
));
bom.tracks.push(Track::new(
Layer::Back,
(0.0, 0.0),
(100.0, 100.0),
1.0,
Some("net 1"),
));

bom
.vias
.push(Via::new(&[Layer::Front], (50.0, 50.0), 1.0, 0.5, None));
bom.vias.push(Via::new(
&[Layer::Front, Layer::Back],
(50.0, 50.0),
1.0,
0.5,
Some("net 2"),
));

bom.zones.push(Zone::new(Layer::Front, "M 0 0", None));
bom
.zones
.push(Zone::new(Layer::Back, "M 0 0", Some("net 3")));

bom.footprints.push(Footprint::new(
Layer::Front,
(50.0, 50.0),
45.0,
(-5.0, -5.0),
(5.0, 5.0),
&["Value 1".into(), "Value 2".into()],
&[],
false,
));
bom.footprints.push(Footprint::new(
Layer::Front,
(50.0, 50.0),
45.0,
(-5.0, -5.0),
(5.0, 5.0),
&["Value 1".into(), "Value 2".into()],
&[
Pad::new(&[Layer::Front], (0.0, -5.0), 45.0, "M 0 0", None, None),
Pad::new(
&[Layer::Front, Layer::Back],
(0.0, 5.0),
45.0,
"M 0 0",
Some((0.5, 1.0)),
Some("net 4"),
),
],
true,
));

bom
.bom_front
.push(vec![RefMap::new("R1", 0), RefMap::new("R2", 1)]);
bom
.bom_back
.push(vec![RefMap::new("R1", 0), RefMap::new("R2", 1)]);
bom.bom_both.push(vec![RefMap::new("R1", 0)]);
bom.bom_both.push(vec![RefMap::new("R2", 1)]);

let html = bom.generate_html().unwrap();
assert!(html.contains("<html"));
}

#[test]
fn test_invalid_footprint_id() {
let mut bom = InteractiveHtmlBom::new(
"Test Title",
"Test Company",
"Test Revision",
"Test Date",
(0.0, 0.0),
(100.0, 100.0),
);

bom.bom_both.push(vec![RefMap::new("R1", 0)]);

let err = bom.generate_html().unwrap_err();
assert_eq!(err, "Invalid footprint ID.");
}

#[test]
fn test_inconsistent_fields() {
let mut bom = InteractiveHtmlBom::new(
"Test Title",
"Test Company",
"Test Revision",
"Test Date",
(0.0, 0.0),
(100.0, 100.0),
);

bom.fields = vec!["Field 1".into()];

bom.footprints.push(Footprint::new(
Layer::Front,
(50.0, 50.0),
45.0,
(-5.0, -5.0),
(5.0, 5.0),
&["Value 1".into(), "Value 2".into()],
&[],
false,
));

let err = bom.generate_html().unwrap_err();
assert_eq!(err, "Inconsistent number of fields.");
}

0 comments on commit cd610af

Please sign in to comment.