Skip to content

Commit

Permalink
feat: refactor tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Janik-Haag committed Aug 30, 2024
1 parent 6049a02 commit 8a96a00
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 107 deletions.
32 changes: 16 additions & 16 deletions src/commonmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
//! This module implements CommonMark output for a struct
//! representing a single entry in the manual.
use std::io::{Result, Write};

use serde::Serialize;

/// Represent a single function argument name and its (optional)
Expand Down Expand Up @@ -160,29 +158,32 @@ impl ManualEntry {
}

/// Write a single CommonMark entry for a documented Nix function.
pub fn write_section<W: Write>(self, writer: &mut W) -> Result<()> {
pub fn write_section(self, output: &mut String) -> String {
let (ident, title) = self.get_ident_title();
writeln!(writer, "## `{}` {{#function-library-{}}}\n", title, ident)?;
output.push_str(&format!(
"## `{}` {{#function-library-{}}}\n\n",
title, ident
));

// <subtitle> (type signature)
if let Some(t) = &self.fn_type {
if t.lines().count() > 1 {
writeln!(writer, "**Type**:\n```\n{}\n```\n", t)?;
output.push_str(&format!("**Type**:\n```\n{}\n```\n\n", t));
} else {
writeln!(writer, "**Type**: `{}`\n", t)?;
output.push_str(&format!("**Type**: `{}`\n\n", t));
}
}

// Primary doc string
// TODO: Split paragraphs?
for paragraph in &self.description {
writeln!(writer, "{}\n", paragraph)?;
output.push_str(&format!("{}\n\n", paragraph));
}

// Function argument names
if !self.args.is_empty() {
for arg in self.args {
writeln!(writer, "{}", arg.format_argument())?;
output.push_str(&format!("{}\n", arg.format_argument()));
}
}

Expand All @@ -191,19 +192,18 @@ impl ManualEntry {
// TODO: In grhmc's version there are multiple (named)
// examples, how can this be achieved automatically?
if let Some(example) = &self.example {
writeln!(
writer,
"::: {{.example #function-library-example-{}}}",
output.push_str(&format!(
"::: {{.example #function-library-example-{}}}\n",
ident
)?;
writeln!(writer, "# `{}` usage example\n", title)?;
writeln!(writer, "```nix\n{}\n```\n:::\n", example.trim())?;
));
output.push_str(&format!("# `{}` usage example\n\n", title));
output.push_str(&format!("```nix\n{}\n```\n:::\n\n", example.trim()));
}

if let Some(loc) = self.location {
writeln!(writer, "Located at {loc}.\n")?;
output.push_str(&String::from(format!("Located at {loc}.\n\n")));
}

Ok(())
output.to_string()
}
}
21 changes: 11 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ use std::fs;

use serde::Serialize;
use std::collections::HashMap;
use std::io;
use std::io::Write;

use clap::Parser;
use std::path::PathBuf;
Expand Down Expand Up @@ -320,8 +318,7 @@ fn retrieve_description(nix: &rnix::Root, description: &str, category: &str) ->
)
}

fn main() {
let opts = Options::parse();
fn main_with_options(opts: Options) -> String {
let src = fs::read_to_string(&opts.file).unwrap();
let locs = match opts.locs {
None => Default::default(),
Expand All @@ -343,16 +340,20 @@ fn main() {
Ok(json) => json,
Err(error) => panic!("Problem converting entries to JSON: {error:?}"),
};
println!("{}", json_string);
json_string
} else {
// TODO: move this to commonmark.rs
let mut output = io::stdout();
writeln!(output, "{}", description).expect("Failed to write header");
let mut output = description + "\n";

for entry in entries {
entry
.write_section(&mut output)
.expect("Failed to write section")
entry.write_section(&mut output);
}
output
}
}

fn main() {
let opts = Options::parse();
let output = main_with_options(opts);
println!("{}", output)
}
6 changes: 6 additions & 0 deletions src/snapshots/nixdoc__test__json_output.snap

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/snapshots/nixdoc__test__main.snap
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
---
source: src/main.rs
source: src/test.rs
assertion_line: 23
expression: output
---
# string manipulation functions {#sec-functions-library-strings}
String manipulation functions.

## `lib.strings.concatStrings` {#function-library-lib.strings.concatStrings}

Expand Down Expand Up @@ -1693,5 +1695,3 @@ levenshteinAtMost 3 "This is a sentence" "this is a sentense."
:::
Located at [lib/strings.nix:1183](https://github.com/NixOS/nixpkgs/blob/580dd2124db98c13c3798af23c2ecf6277ec7d9e/lib/strings.nix#L1183) in `<nixpkgs>`.
124 changes: 46 additions & 78 deletions src/test.rs
Original file line number Diff line number Diff line change
@@ -1,154 +1,132 @@
use rnix;
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;

use std::io::Write;

use crate::{collect_entries, format::shift_headings, retrieve_description, ManualEntry};
use crate::{
collect_entries, format::shift_headings, main_with_options, retrieve_description, ManualEntry,
Options,
};

#[test]
fn test_main() {
let mut output = Vec::new();
let src = fs::read_to_string("test/strings.nix").unwrap();
let locs: HashMap<String, String> =
serde_json::from_str(&fs::read_to_string("test/strings.json").unwrap()).unwrap();
let nix = rnix::Root::parse(&src).ok().expect("failed to parse input");
let desc = "string manipulation functions";
let prefix = "lib";
let category = "strings";

// TODO: move this to commonmark.rs
writeln!(
output,
"# {} {{#sec-functions-library-{}}}\n",
desc, category
)
.expect("Failed to write header");

for entry in collect_entries(nix, prefix, category, &locs) {
entry
.write_section(&mut output)
.expect("Failed to write section")
}
let options = Options {
prefix: String::from("lib"),
json_output: false,
category: String::from("strings"),
description: String::from("string manipulation functions"),
file: PathBuf::from("test/strings.nix"),
locs: Some(PathBuf::from("test/strings.json")),
};

let output = main_with_options(options);

insta::assert_snapshot!(output);
}

#[test]
fn test_json_output() {
let options = Options {
prefix: String::from("lib"),
json_output: true,
category: String::from("strings"),
description: String::from("string manipulation functions"),
file: PathBuf::from("test/strings.nix"),
locs: Some(PathBuf::from("test/strings.json")),
};

let output = String::from_utf8(output).expect("not utf8");
let output = main_with_options(options);

insta::assert_snapshot!(output);
}

#[test]
fn test_description_of_lib_debug() {
let mut output = Vec::new();
let src = fs::read_to_string("test/lib-debug.nix").unwrap();
let nix = rnix::Root::parse(&src).ok().expect("failed to parse input");
let prefix = "lib";
let category = "debug";
let desc = retrieve_description(&nix, &"Debug", category);
writeln!(output, "{}", desc).expect("Failed to write header");
let mut output = String::from(desc) + "\n";

for entry in collect_entries(nix, prefix, category, &Default::default()) {
entry
.write_section(&mut output)
.expect("Failed to write section")
entry.write_section(&mut output);
}

let output = String::from_utf8(output).expect("not utf8");

insta::assert_snapshot!(output);
}

#[test]
fn test_arg_formatting() {
let mut output = Vec::new();
let mut output = String::from("");
let src = fs::read_to_string("test/arg-formatting.nix").unwrap();
let nix = rnix::Root::parse(&src).ok().expect("failed to parse input");
let prefix = "lib";
let category = "options";

for entry in collect_entries(nix, prefix, category, &Default::default()) {
entry
.write_section(&mut output)
.expect("Failed to write section")
entry.write_section(&mut output);
}

let output = String::from_utf8(output).expect("not utf8");

insta::assert_snapshot!(output);
}

#[test]
fn test_inherited_exports() {
let mut output = Vec::new();
let mut output = String::from("");
let src = fs::read_to_string("test/inherited-exports.nix").unwrap();
let nix = rnix::Root::parse(&src).ok().expect("failed to parse input");
let prefix = "lib";
let category = "let";

for entry in collect_entries(nix, prefix, category, &Default::default()) {
entry
.write_section(&mut output)
.expect("Failed to write section")
entry.write_section(&mut output);
}

let output = String::from_utf8(output).expect("not utf8");

insta::assert_snapshot!(output);
}

#[test]
fn test_line_comments() {
let mut output = Vec::new();
let mut output = String::from("");
let src = fs::read_to_string("test/line-comments.nix").unwrap();
let nix = rnix::Root::parse(&src).ok().expect("failed to parse input");
let prefix = "lib";
let category = "let";

for entry in collect_entries(nix, prefix, category, &Default::default()) {
entry
.write_section(&mut output)
.expect("Failed to write section")
entry.write_section(&mut output);
}

let output = String::from_utf8(output).expect("not utf8");

insta::assert_snapshot!(output);
}

#[test]
fn test_multi_line() {
let mut output = Vec::new();
let mut output = String::from("");
let src = fs::read_to_string("test/multi-line.nix").unwrap();
let nix = rnix::Root::parse(&src).ok().expect("failed to parse input");
let prefix = "lib";
let category = "let";

for entry in collect_entries(nix, prefix, category, &Default::default()) {
entry
.write_section(&mut output)
.expect("Failed to write section")
entry.write_section(&mut output);
}

let output = String::from_utf8(output).expect("not utf8");

insta::assert_snapshot!(output);
}

#[test]
fn test_doc_comment() {
let mut output = Vec::new();
let mut output = String::from("");
let src = fs::read_to_string("test/doc-comment.nix").unwrap();
let nix = rnix::Root::parse(&src).ok().expect("failed to parse input");
let prefix = "lib";
let category = "debug";

for entry in collect_entries(nix, prefix, category, &Default::default()) {
entry
.write_section(&mut output)
.expect("Failed to write section")
entry.write_section(&mut output);
}

let output = String::from_utf8(output).expect("not utf8");

insta::assert_snapshot!(output);
}

Expand All @@ -172,43 +150,33 @@ fn test_headings() {

#[test]
fn test_doc_comment_section_description() {
let mut output = Vec::new();
let src = fs::read_to_string("test/doc-comment-sec-heading.nix").unwrap();
let nix = rnix::Root::parse(&src).ok().expect("failed to parse input");
let prefix = "lib";
let category = "debug";
let desc = retrieve_description(&nix, &"Debug", category);
writeln!(output, "{}", desc).expect("Failed to write header");
let mut output = String::from(desc) + "\n";

for entry in collect_entries(nix, prefix, category, &Default::default()) {
entry
.write_section(&mut output)
.expect("Failed to write section")
entry.write_section(&mut output);
}

let output = String::from_utf8(output).expect("not utf8");

insta::assert_snapshot!(output);
}

#[test]
fn test_doc_comment_no_duplicate_arguments() {
let mut output = Vec::new();
let src = fs::read_to_string("test/doc-comment-arguments.nix").unwrap();
let nix = rnix::Root::parse(&src).ok().expect("failed to parse input");
let prefix = "lib";
let category = "debug";
let desc = retrieve_description(&nix, &"Debug", category);
writeln!(output, "{}", desc).expect("Failed to write header");
let mut output = String::from(desc) + "\n";

for entry in collect_entries(nix, prefix, category, &Default::default()) {
entry
.write_section(&mut output)
.expect("Failed to write section")
entry.write_section(&mut output);
}

let output = String::from_utf8(output).expect("not utf8");

insta::assert_snapshot!(output);
}

Expand Down

0 comments on commit 8a96a00

Please sign in to comment.