diff --git a/Makefile b/Makefile index 9d58a546..841f14d3 100644 --- a/Makefile +++ b/Makefile @@ -22,8 +22,7 @@ test: test-coverage: cargo llvm-cov clean - cargo llvm-cov --all-features --lcov --output-path lcov.info - cargo llvm-cov --open + cargo llvm-cov --all-features --open precommit: cargo clean diff --git a/src/config.rs b/src/config.rs index 0ce446d2..3eb367d2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,6 +8,7 @@ use crate::languages::{ }; #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct MdsfConfig { #[schemars(skip)] #[serde(rename = "$schema", default = "default_schema_location")] @@ -158,3 +159,25 @@ fn default_schema_location() -> String { "https://raw.githubusercontent.com/hougesen/mdsf/main/schemas/v{package_version}/mdsf.schema.json" ) } + +#[cfg(test)] +mod test_config { + use super::MdsfConfig; + + #[test] + fn schema_should_be_serializable() { + let config = MdsfConfig::default(); + + let json = serde_json::to_string_pretty(&config).expect("it to be serializable"); + + let loaded = serde_json::from_str::(&json).expect("it to be parsed"); + + assert_eq!(config, loaded); + } + + #[test] + fn json_schema_should_be_serializable() { + serde_json::to_string_pretty(&schemars::schema_for!(MdsfConfig)) + .expect("it to be serializable"); + } +} diff --git a/src/formatters/clang_format.rs b/src/formatters/clang_format.rs index 5ff23d35..0fae8288 100644 --- a/src/formatters/clang_format.rs +++ b/src/formatters/clang_format.rs @@ -172,4 +172,31 @@ mod test_clang_format { assert_eq!(expected_output, output); } + + #[test] + fn it_should_format_java() { + let input = "class HelloWorld { + public static void main(String[] args) { + System.out.println(\"Hello\"); + System.out.println(\"World!\"); + } +}"; + + let expected_output = "class HelloWorld { + public static void main(String[] args) { + System.out.println(\"Hello\"); + System.out.println(\"World!\"); + } +}"; + + let snippet = setup_snippet(input, Language::Java.to_file_ext()) + .expect("it to create a snippet file"); + + let output = format_using_clang_format(snippet.path()) + .expect("it to be successful") + .1 + .expect("it to be some"); + + assert_eq!(expected_output, output); + } } diff --git a/src/formatters/gofmt.rs b/src/formatters/gofmt.rs index ea20beb6..0f970046 100644 --- a/src/formatters/gofmt.rs +++ b/src/formatters/gofmt.rs @@ -20,10 +20,10 @@ mod test_gofmt { #[test] fn it_should_format_go() { - let input = "package main + let input = "package main func add(a int , b int ) int { - return a + b + return a + b } "; diff --git a/src/formatters/mod.rs b/src/formatters/mod.rs index 2becd14a..ed211d36 100644 --- a/src/formatters/mod.rs +++ b/src/formatters/mod.rs @@ -1,7 +1,4 @@ -use std::{ - io::Write, - process::{Command, Stdio}, -}; +use std::{io::Write, process::Command}; use tempfile::NamedTempFile; @@ -72,12 +69,12 @@ fn handle_post_execution( } fn spawn_command(cmd: &mut Command) -> std::io::Result { - Ok(cmd - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .spawn()? - .wait()? - .success()) + #[cfg(not(test))] + cmd.stdout(std::process::Stdio::null()); + #[cfg(not(test))] + cmd.stderr(std::process::Stdio::null()); + + Ok(cmd.spawn()?.wait()?.success()) } #[inline] diff --git a/src/formatters/prettier.rs b/src/formatters/prettier.rs index 9c8ee354..57d82fa4 100644 --- a/src/formatters/prettier.rs +++ b/src/formatters/prettier.rs @@ -313,4 +313,50 @@ updates: assert_eq!(expected_output, output); } + + #[test] + fn it_should_format_vue() { + let input = " + + + + +"; + + let expected_output = " + + +"; + + let snippet = + setup_snippet(input, Language::Vue.to_file_ext()).expect("it to create a snippet file"); + + let output = format_using_prettier(snippet.path(), true) + .expect("it to be successful") + .1 + .expect("it to be some"); + + assert_eq!(expected_output, output); + } } diff --git a/src/languages/c.rs b/src/languages/c.rs index bd9536fb..3d4544a6 100644 --- a/src/languages/c.rs +++ b/src/languages/c.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::clang_format::format_using_clan use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum CFormatter { #[default] #[serde(rename = "clang-format")] @@ -12,6 +13,7 @@ pub enum CFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct C { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,59 @@ impl LanguageFormatter for C { } } } + +#[cfg(test)] +mod test_c { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{CFormatter, C}; + + const INPUT: &str = "int add(int a,int b){ + a-b; + return a + b; + }"; + + const EXTENSION: &str = crate::languages::Language::C.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(C::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(C { + enabled: false, + formatter: CFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_clang_format() { + let l = C { + enabled: true, + formatter: CFormatter::ClangFormat, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "int add(int a, int b) { + a - b; + return a + b; +}"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/cpp.rs b/src/languages/cpp.rs index a661dfb7..db237df3 100644 --- a/src/languages/cpp.rs +++ b/src/languages/cpp.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::clang_format::format_using_clan use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum CppFormatter { #[default] #[serde(rename = "clang-format")] @@ -12,6 +13,7 @@ pub enum CppFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Cpp { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,59 @@ impl LanguageFormatter for Cpp { } } } + +#[cfg(test)] +mod test_cpp { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Cpp, CppFormatter}; + + const INPUT: &str = "int add(int a,int b){ + a-b; + return a + b; + }"; + + const EXTENSION: &str = crate::languages::Language::Cpp.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Cpp::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Cpp { + enabled: false, + formatter: CppFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_clang_format() { + let l = Cpp { + enabled: true, + formatter: CppFormatter::ClangFormat, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "int add(int a, int b) { + a - b; + return a + b; +}"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/csharp.rs b/src/languages/csharp.rs index 470af4de..e3498b9e 100644 --- a/src/languages/csharp.rs +++ b/src/languages/csharp.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::clang_format::format_using_clan use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum CSharpFormatter { #[default] #[serde(rename = "clang-format")] @@ -12,6 +13,7 @@ pub enum CSharpFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct CSharp { #[serde(default = "default_enabled")] pub enabled: bool, @@ -43,3 +45,67 @@ impl LanguageFormatter for CSharp { } } } + +#[cfg(test)] +mod test_csharp { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{CSharp, CSharpFormatter}; + + const INPUT: &str = "namespace Mdsf { + class Adder { + public static int add(int a,int b) { + a-b ; + return a + b; + } + } + } "; + + const EXTENSION: &str = crate::languages::Language::CSharp.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(CSharp::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(CSharp { + enabled: false, + formatter: CSharpFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_clang_format() { + let l = CSharp { + enabled: true, + formatter: CSharpFormatter::ClangFormat, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "namespace Mdsf { +class Adder { + public static int add(int a, int b) { + a - b; + return a + b; + } +} +}"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/css.rs b/src/languages/css.rs index 04576565..11797755 100644 --- a/src/languages/css.rs +++ b/src/languages/css.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::prettier::format_using_prettier use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum CssFormatter { #[default] #[serde(rename = "prettier")] @@ -12,6 +13,7 @@ pub enum CssFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Css { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,59 @@ impl LanguageFormatter for Css { } } } + +#[cfg(test)] +mod test_css { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Css, CssFormatter}; + + const INPUT: &str = " h1 {color: blue;} p {color: red;} "; + + const EXTENSION: &str = crate::languages::Language::Css.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Css::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Css { + enabled: false, + formatter: CssFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_prettier() { + let l = Css { + enabled: true, + formatter: CssFormatter::Prettier, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "h1 { + color: blue; +} +p { + color: red; +} +"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/dart.rs b/src/languages/dart.rs index 2919509d..1c8e0ff7 100644 --- a/src/languages/dart.rs +++ b/src/languages/dart.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::dart_format::format_using_dart_ use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum DartFormatter { #[default] #[serde(rename = "dart_format")] @@ -12,6 +13,7 @@ pub enum DartFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Dart { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,58 @@ impl LanguageFormatter for Dart { } } } + +#[cfg(test)] +mod test_dart { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Dart, DartFormatter}; + + const INPUT: &str = "class Adder { int add(int a, int b) { return a + b; } } "; + + const EXTENSION: &str = crate::languages::Language::Dart.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Dart::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Dart { + enabled: false, + formatter: DartFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_dart_format() { + let l = Dart { + enabled: true, + formatter: DartFormatter::DartFormat, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "class Adder { + int add(int a, int b) { + return a + b; + } +} +"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/elixir.rs b/src/languages/elixir.rs index b72fcd7d..850db4dd 100644 --- a/src/languages/elixir.rs +++ b/src/languages/elixir.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::mix_format::format_using_mix_fo use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum ElixirFormatter { #[default] #[serde(rename = "mix_format")] @@ -12,6 +13,7 @@ pub enum ElixirFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Elixir { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,59 @@ impl LanguageFormatter for Elixir { } } } + +#[cfg(test)] +mod test_elixir { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Elixir, ElixirFormatter}; + + const INPUT: &str = " + def add(a , b ) do a + b end + +"; + + const EXTENSION: &str = crate::languages::Language::Elixir.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Elixir::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Elixir { + enabled: false, + formatter: ElixirFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_mix_format() { + let l = Elixir { + enabled: true, + formatter: ElixirFormatter::MixFormat, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "def add(a, b) do + a + b +end +"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/gleam.rs b/src/languages/gleam.rs index 3e9cca25..5adf4955 100644 --- a/src/languages/gleam.rs +++ b/src/languages/gleam.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::gleam_format::format_using_glea use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum GleamFormatter { #[default] #[serde(rename = "gleam_format")] @@ -12,6 +13,7 @@ pub enum GleamFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Gleam { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,56 @@ impl LanguageFormatter for Gleam { } } } + +#[cfg(test)] +mod test_gleam { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Gleam, GleamFormatter}; + + const INPUT: &str = "pub fn add(a:Int,b:Int)->Int{a+b}"; + + const EXTENSION: &str = crate::languages::Language::Gleam.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Gleam::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Gleam { + enabled: false, + formatter: GleamFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_gleam_format() { + let l = Gleam { + enabled: true, + formatter: GleamFormatter::GleamFormat, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "pub fn add(a: Int, b: Int) -> Int { + a + b +} +"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/go.rs b/src/languages/go.rs index a7e6f211..c24a2d9b 100644 --- a/src/languages/go.rs +++ b/src/languages/go.rs @@ -8,6 +8,7 @@ use crate::{ use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum GoFormatter { #[default] #[serde(rename = "gofmt")] @@ -17,6 +18,7 @@ pub enum GoFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Go { #[serde(default = "default_enabled")] pub enabled: bool, @@ -47,3 +49,89 @@ impl LanguageFormatter for Go { } } } + +#[cfg(test)] +mod test_go { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Go, GoFormatter}; + + const INPUT: &str = "package main + + func add(a int , b int ) int { + return a + b + } + + "; + + const EXTENSION: &str = crate::languages::Language::Go.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Go::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Go { + enabled: false, + formatter: GoFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_gofmt() { + let l = Go { + enabled: true, + formatter: GoFormatter::GoFmt, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "package main + +func add(a int, b int) int { +\treturn a + b +} +"; + + assert_eq!(output, expected_output); + } + + #[test] + fn test_gofumpt() { + let l = Go { + enabled: true, + formatter: GoFormatter::GoFumpt, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "package main + +func add(a int, b int) int { +\treturn a + b +} +"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/html.rs b/src/languages/html.rs index 7166733c..72c8f473 100644 --- a/src/languages/html.rs +++ b/src/languages/html.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::prettier::format_using_prettier use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum HtmlFormatter { #[default] #[serde(rename = "prettier")] @@ -12,6 +13,7 @@ pub enum HtmlFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Html { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,73 @@ impl LanguageFormatter for Html { } } } + +#[cfg(test)] +mod test_html { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Html, HtmlFormatter}; + + const INPUT: &str = "

This is a heading

This is a paragraph.

"; + + const EXTENSION: &str = crate::languages::Language::Html.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Html::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Html { + enabled: false, + formatter: HtmlFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_prettier() { + let expected_output = " + + + + + +

This is a heading

+

This is a paragraph.

+ + +"; + + let l = Html { + enabled: true, + formatter: HtmlFormatter::Prettier, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/java.rs b/src/languages/java.rs index bd98b5b1..9b72250a 100644 --- a/src/languages/java.rs +++ b/src/languages/java.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::clang_format::format_using_clan use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum JavaFormatter { #[default] #[serde(rename = "clang-format")] @@ -12,6 +13,7 @@ pub enum JavaFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Java { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,62 @@ impl LanguageFormatter for Java { } } } + +#[cfg(test)] +mod test_java { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Java, JavaFormatter}; + + const INPUT: &str = "class HelloWorld { + public static void main(String[] args) { + System.out.println(\"Hello\"); + System.out.println(\"World!\"); + } +}"; + + const EXTENSION: &str = crate::languages::Language::Java.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Java::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Java { + enabled: false, + formatter: JavaFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_clang_format() { + let expected_output = "class HelloWorld { + public static void main(String[] args) { + System.out.println(\"Hello\"); + System.out.println(\"World!\"); + } +}"; + let l = Java { + enabled: true, + formatter: JavaFormatter::ClangFormat, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(expected_output, output); + } +} diff --git a/src/languages/javascript.rs b/src/languages/javascript.rs index 83d0169a..18249f5f 100644 --- a/src/languages/javascript.rs +++ b/src/languages/javascript.rs @@ -11,6 +11,7 @@ use crate::{ use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum JavaScriptFormatter { #[default] #[serde(rename = "prettier")] @@ -22,6 +23,7 @@ pub enum JavaScriptFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct JavaScript { #[serde(default = "default_enabled")] pub enabled: bool, @@ -57,3 +59,124 @@ impl LanguageFormatter for JavaScript { } } } + +#[cfg(test)] +mod test_javascript { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{JavaScript, JavaScriptFormatter}; + + const INPUT: &str = " + async function asyncAddition( + a,b + ) + { + return a+b + } + + "; + + const EXTENSION: &str = crate::languages::Language::JavaScript.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(JavaScript::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let prettier = JavaScript { + enabled: false, + formatter: JavaScriptFormatter::Prettier, + }; + + assert!(prettier + .format(snippet_path) + .expect("it to not fail") + .is_none()); + + let biome = JavaScript { + enabled: false, + formatter: JavaScriptFormatter::Biome, + }; + + assert!(biome + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_prettier() { + let l = JavaScript { + enabled: true, + formatter: JavaScriptFormatter::Prettier, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "async function asyncAddition(a, b) { + return a + b; +} +"; + + assert_eq!(output, expected_output); + } + + #[test] + fn test_biome() { + let l = JavaScript { + enabled: true, + formatter: JavaScriptFormatter::Biome, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "async function asyncAddition(a, b) { +\treturn a + b; +} +"; + + assert_eq!(output, expected_output); + } + + #[test] + fn test_clang_format() { + let input = " async function asyncAddition( a,b) { + a * b; + return a+b + } "; + + let expected_output = "async function asyncAddition(a, b) {\n a * b;\n return a + b\n}"; + + let l = JavaScript { + enabled: true, + formatter: JavaScriptFormatter::ClangFormat, + }; + + let snippet = setup_snippet(input, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(expected_output, output); + } +} diff --git a/src/languages/json.rs b/src/languages/json.rs index 2e43822e..4afd4be8 100644 --- a/src/languages/json.rs +++ b/src/languages/json.rs @@ -11,6 +11,7 @@ use crate::{ use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum JsonFormatter { #[default] #[serde(rename = "prettier")] @@ -22,6 +23,7 @@ pub enum JsonFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Json { #[serde(default = "default_enabled")] pub enabled: bool, @@ -53,3 +55,111 @@ impl LanguageFormatter for Json { } } } + +#[cfg(test)] +mod test_json { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Json, JsonFormatter}; + + const INPUT: &str = " + { + \"key\": \"value\", + \"key2\": [ + \"value2\", + \"value3\", + 1 + , null] + } + "; + + const EXTENSION: &str = crate::languages::Language::Json.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Json::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Json { + enabled: false, + formatter: JsonFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_prettier() { + let l = Json { + enabled: true, + formatter: JsonFormatter::Prettier, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "{ + \"key\": \"value\", + \"key2\": [\"value2\", \"value3\", 1, null], +} +"; + + assert_eq!(output, expected_output); + } + + #[test] + fn test_biome() { + let l = Json { + enabled: true, + formatter: JsonFormatter::Biome, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "{ +\t\"key\": \"value\", +\t\"key2\": [\"value2\", \"value3\", 1, null] +} +"; + + assert_eq!(output, expected_output); + } + + #[test] + fn test_clang_format() { + let l = Json { + enabled: true, + formatter: JsonFormatter::ClangFormat, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = + "\n{ \"key\" : \"value\", \"key2\" : [ \"value2\", \"value3\", 1, null ] }\n"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/lua.rs b/src/languages/lua.rs index c705ed40..5098b4a5 100644 --- a/src/languages/lua.rs +++ b/src/languages/lua.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::stylua::format_using_stylua}; use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum LuaFormatter { #[default] #[serde(rename = "stylua")] @@ -12,6 +13,7 @@ pub enum LuaFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Lua { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,63 @@ impl LanguageFormatter for Lua { } } } + +#[cfg(test)] +mod test_lua { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Lua, LuaFormatter}; + + const INPUT: &str = " + + local function add ( a , b +) + +return a +b + + +end + + "; + + const EXTENSION: &str = crate::languages::Language::Lua.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Lua::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Lua { + enabled: false, + formatter: LuaFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_stylua() { + let expected_output = "local function add(a, b)\n\treturn a + b\nend\n"; + + let l = Lua { + enabled: true, + formatter: LuaFormatter::Stylua, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/markdown.rs b/src/languages/markdown.rs index 0a80b74c..f5aba484 100644 --- a/src/languages/markdown.rs +++ b/src/languages/markdown.rs @@ -5,6 +5,7 @@ use crate::formatters::prettier::format_using_prettier; use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum MarkdownFormatter { #[default] #[serde(rename = "prettier")] @@ -12,6 +13,7 @@ pub enum MarkdownFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Markdown { #[serde(default = "bool::default")] pub enabled: bool, @@ -43,3 +45,61 @@ impl LanguageFormatter for Markdown { } } } + +#[cfg(test)] +mod test_markdown { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Markdown, MarkdownFormatter}; + + const INPUT: &str = " +# mads was here + + + the whitespace should be removed +"; + + const EXTENSION: &str = crate::languages::Language::Markdown.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(!Markdown::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Markdown { + enabled: false, + formatter: MarkdownFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_prettier() { + let expected_output = "# mads was here + +the whitespace should be removed +"; + + let l = Markdown { + enabled: true, + formatter: MarkdownFormatter::Prettier, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/nim.rs b/src/languages/nim.rs index 4957edd3..6e6d9df0 100644 --- a/src/languages/nim.rs +++ b/src/languages/nim.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::nimpretty::format_using_nimpret use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum NimFormatter { #[default] #[serde(rename = "nimpretty")] @@ -12,6 +13,7 @@ pub enum NimFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Nim { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,56 @@ impl LanguageFormatter for Nim { } } } + +#[cfg(test)] +mod test_nim { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Nim, NimFormatter}; + + const INPUT: &str = "proc add( a :int , b:int ) : int = + return a + b "; + + const EXTENSION: &str = crate::languages::Language::Nim.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Nim::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Nim { + enabled: false, + formatter: NimFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_clang_format() { + let l = Nim { + enabled: true, + formatter: NimFormatter::Nimpretty, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "proc add(a: int, b: int): int = + return a + b +"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/objective_c.rs b/src/languages/objective_c.rs index 51b6905c..e5dc0bd5 100644 --- a/src/languages/objective_c.rs +++ b/src/languages/objective_c.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::clang_format::format_using_clan use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum ObjectiveCFormatter { #[default] #[serde(rename = "clang-format")] @@ -12,6 +13,7 @@ pub enum ObjectiveCFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct ObjectiveC { #[serde(default = "default_enabled")] pub enabled: bool, @@ -43,3 +45,59 @@ impl LanguageFormatter for ObjectiveC { } } } + +#[cfg(test)] +mod test_objective_c { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{ObjectiveC, ObjectiveCFormatter}; + + const INPUT: &str = "int add(int a,int b){ + a - a ; + return a + b; + }"; + + const EXTENSION: &str = crate::languages::Language::ObjectiveC.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(ObjectiveC::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(ObjectiveC { + enabled: false, + formatter: ObjectiveCFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_clang_format() { + let expected_output = "int add(int a, int b) { + a - a; + return a + b; +}"; + + let l = ObjectiveC { + enabled: true, + formatter: ObjectiveCFormatter::ClangFormat, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/protobuf.rs b/src/languages/protobuf.rs index 4e1842f5..2a45bb59 100644 --- a/src/languages/protobuf.rs +++ b/src/languages/protobuf.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::clang_format::format_using_clan use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum ProtobufFormatter { #[default] #[serde(rename = "clang-format")] @@ -12,6 +13,7 @@ pub enum ProtobufFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Protobuf { #[serde(default = "default_enabled")] pub enabled: bool, @@ -43,3 +45,56 @@ impl LanguageFormatter for Protobuf { } } } + +#[cfg(test)] +mod test_protobuf { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Protobuf, ProtobufFormatter}; + + const INPUT: &str = "service SearchService { + rpc Search (SearchRequest) returns (SearchResponse); + }"; + + const EXTENSION: &str = crate::languages::Language::Protobuf.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Protobuf::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Protobuf { + enabled: false, + formatter: ProtobufFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_clang_format() { + let expected_output = + "service SearchService { rpc Search(SearchRequest) returns (SearchResponse); }"; + + let l = Protobuf { + enabled: true, + formatter: ProtobufFormatter::ClangFormat, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/python.rs b/src/languages/python.rs index 7f604b48..94a28490 100644 --- a/src/languages/python.rs +++ b/src/languages/python.rs @@ -11,6 +11,7 @@ use crate::{ use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum PythonFormatter { #[default] #[serde(rename = "ruff")] @@ -26,6 +27,7 @@ pub enum PythonFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Python { #[serde(default = "default_enabled")] pub enabled: bool, @@ -59,3 +61,133 @@ impl LanguageFormatter for Python { } } } + +#[cfg(test)] +mod test_python { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Python, PythonFormatter}; + + const INPUT: &str = "def add( a: int , b:int)->int: return a+b"; + + const EXTENSION: &str = crate::languages::Language::Python.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Python::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Python { + enabled: false, + formatter: PythonFormatter::default(), + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_black() { + let expected_output = "def add(a: int, b: int) -> int:\n return a + b\n"; + + let l = Python { + enabled: true, + formatter: PythonFormatter::Black, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } + + #[test] + fn test_blue() { + let expected_output = "def add(a: int, b: int) -> int:\n return a + b\n"; + + let l = Python { + enabled: true, + formatter: PythonFormatter::Blue, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } + + #[test] + fn test_ruff() { + let expected_output = "def add(a: int, b: int) -> int:\n return a + b\n"; + + let l = Python { + enabled: true, + formatter: PythonFormatter::Ruff, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } + + #[test] + fn test_autopep8() { + let expected_output = "def add(a: int, b: int) -> int: return a+b\n"; + + let l = Python { + enabled: true, + formatter: PythonFormatter::Autopep8, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } + + #[test] + fn test_yapf() { + let expected_output = "def add(a: int, b: int) -> int:\n return a + b\n"; + + let l = Python { + enabled: true, + formatter: PythonFormatter::Yapf, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/ruby.rs b/src/languages/ruby.rs index 8068c4ed..c8a41fec 100644 --- a/src/languages/ruby.rs +++ b/src/languages/ruby.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::rubocop::format_using_rubocop}; use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum RubyFormatter { #[default] #[serde(rename = "rubocop")] @@ -12,6 +13,7 @@ pub enum RubyFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Ruby { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,59 @@ impl LanguageFormatter for Ruby { } } } + +#[cfg(test)] +mod test_ruby { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Ruby, RubyFormatter}; + + const INPUT: &str = + "def add( a , b ) + return a + b + end"; + + const EXTENSION: &str = crate::languages::Language::Ruby.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Ruby::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Ruby { + enabled: false, + formatter: RubyFormatter::RuboCop, + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_rubocop() { + let expected_output = "def add(a, b) + return a + b +end +"; + + let l = Ruby { + enabled: true, + formatter: RubyFormatter::RuboCop, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/rust.rs b/src/languages/rust.rs index f0fb1182..28e169b4 100644 --- a/src/languages/rust.rs +++ b/src/languages/rust.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::rustfmt::format_using_rustfmt}; use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum RustFormatter { #[default] #[serde(rename = "rustfmt")] @@ -12,6 +13,7 @@ pub enum RustFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Rust { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,57 @@ impl LanguageFormatter for Rust { } } } + +#[cfg(test)] +mod test_rust { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Rust, RustFormatter}; + + const INPUT: &str = "pub + async + fn add( a: i32, + b:i32 )-> i32 {a+b} + "; + + const EXTENSION: &str = crate::languages::Language::Rust.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Rust::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Rust { + enabled: false, + formatter: RustFormatter::RustFmt, + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_rustfmt() { + let expected_output = "pub async fn add(a: i32, b: i32) -> i32 {\n a + b\n}\n"; + + let l = Rust { + enabled: true, + formatter: RustFormatter::RustFmt, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/shell.rs b/src/languages/shell.rs index 2301c8ca..c59b84d5 100644 --- a/src/languages/shell.rs +++ b/src/languages/shell.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::shfmt::format_using_shfmt}; use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum ShellFormatter { #[default] #[serde(rename = "shfmt")] @@ -12,6 +13,7 @@ pub enum ShellFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Shell { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,76 @@ impl LanguageFormatter for Shell { } } } + +#[cfg(test)] +mod test_shell { + use crate::{ + formatters::setup_snippet, + languages::{shell::ShellFormatter, Language, LanguageFormatter}, + }; + + use super::Shell; + + const INPUT: &str = " + +#!/bin/sh + + add () { + echo \"$1\" + \"$2\" + } + + + + + + + + +"; + + const EXTENSION: &str = Language::Shell.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Shell::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Shell { + enabled: false, + formatter: ShellFormatter::Shfmt, + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_shfmt() { + let expected_output = "#!/bin/sh + +add() { +\techo \"$1\" + \"$2\" +} +"; + + let l = Shell { + enabled: true, + formatter: ShellFormatter::Shfmt, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/sql.rs b/src/languages/sql.rs index 1c65ac8c..f6448a75 100644 --- a/src/languages/sql.rs +++ b/src/languages/sql.rs @@ -8,6 +8,7 @@ use crate::{ use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum SqlFormatter { #[default] #[serde(rename = "sqlfluff")] @@ -17,6 +18,7 @@ pub enum SqlFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Sql { #[serde(default = "default_enabled")] pub enabled: bool, @@ -47,3 +49,93 @@ impl LanguageFormatter for Sql { } } } + +#[cfg(test)] +mod test_sql { + use crate::{ + formatters::setup_snippet, + languages::{sql::SqlFormatter, Language, LanguageFormatter}, + }; + + use super::Sql; + + const INPUT: &str = "SELECT * FROM tbl + WHERE foo = 'bar'; "; + + const EXTENSION: &str = Language::Sql.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Sql::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(Sql { + enabled: false, + formatter: SqlFormatter::SQLFormatter, + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + + assert!(Sql { + enabled: false, + formatter: SqlFormatter::Sqlfluff, + } + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_sql_formatter() { + let expected_output = "SELECT + * +FROM + tbl +WHERE + foo = 'bar'; +"; + + let l = Sql { + enabled: true, + formatter: SqlFormatter::SQLFormatter, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } + + #[test] + fn test_sqlfluff() { + let expected_output = "SELECT * FROM tbl +WHERE foo = 'bar'; +"; + + let l = Sql { + enabled: true, + formatter: SqlFormatter::Sqlfluff, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/toml.rs b/src/languages/toml.rs index c67da44e..4acf73c3 100644 --- a/src/languages/toml.rs +++ b/src/languages/toml.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::taplo::format_using_taplo}; use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum TomlFormatter { #[default] #[serde(rename = "taplo")] @@ -12,6 +13,7 @@ pub enum TomlFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Toml { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,56 @@ impl LanguageFormatter for Toml { } } } + +#[cfg(test)] +mod test_toml { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Toml, TomlFormatter}; + + const INPUT: &str = " package = \"mdsf\" + author = \"Mads Hougesen\" + "; + + const EXTENSION: &str = crate::languages::Language::Toml.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Toml::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let l = Toml { + enabled: false, + formatter: TomlFormatter::Taplo, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(l.format(snippet_path).expect("it to not fail").is_none()); + } + + #[test] + fn test_taplo() { + let l = Toml { + enabled: true, + formatter: TomlFormatter::Taplo, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "package = \"mdsf\" +author = \"Mads Hougesen\" +"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/typescript.rs b/src/languages/typescript.rs index 1519429c..86745f0f 100644 --- a/src/languages/typescript.rs +++ b/src/languages/typescript.rs @@ -8,6 +8,7 @@ use crate::{ use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum TypeScriptFormatter { #[default] #[serde(rename = "prettier")] @@ -17,6 +18,7 @@ pub enum TypeScriptFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct TypeScript { #[serde(default = "default_enabled")] pub enabled: bool, @@ -49,3 +51,102 @@ impl LanguageFormatter for TypeScript { } } } + +#[cfg(test)] +mod test_typescript { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{TypeScript, TypeScriptFormatter}; + + const INPUT: &str = " + async function asyncAddition( + a:number,b:number + ) :Promise< +number> + { + return a+b + } + + "; + + const EXTENSION: &str = crate::languages::Language::TypeScript.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(TypeScript::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let prettier = TypeScript { + enabled: false, + formatter: TypeScriptFormatter::Prettier, + }; + + assert!(prettier + .format(snippet_path) + .expect("it to not fail") + .is_none()); + + let biome = TypeScript { + enabled: false, + formatter: TypeScriptFormatter::Biome, + }; + + assert!(biome + .format(snippet_path) + .expect("it to not fail") + .is_none()); + } + + #[test] + fn test_prettier() { + let l = TypeScript { + enabled: true, + formatter: TypeScriptFormatter::Prettier, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = + "async function asyncAddition(a: number, b: number): Promise { + return a + b; +} +"; + + assert_eq!(output, expected_output); + } + + #[test] + fn test_biome() { + let l = TypeScript { + enabled: true, + formatter: TypeScriptFormatter::Biome, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = + "async function asyncAddition(a: number, b: number): Promise { +\treturn a + b; +} +"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/vue.rs b/src/languages/vue.rs index 8099d11f..c0434594 100644 --- a/src/languages/vue.rs +++ b/src/languages/vue.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::prettier::format_using_prettier use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum VueFormatter { #[default] #[serde(rename = "prettier")] @@ -12,6 +13,7 @@ pub enum VueFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Vue { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,81 @@ impl LanguageFormatter for Vue { } } } + +#[cfg(test)] +mod test_vue { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Vue, VueFormatter}; + + const INPUT: &str = " + + + + +"; + + const EXTENSION: &str = crate::languages::Language::Vue.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Vue::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let l = Vue { + enabled: false, + formatter: VueFormatter::Prettier, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(l.format(snippet_path).expect("it to not fail").is_none()); + } + + #[test] + fn test_prettier() { + let l = Vue { + enabled: true, + formatter: VueFormatter::Prettier, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = " + + +"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/yaml.rs b/src/languages/yaml.rs index eb5f58b8..c7808849 100644 --- a/src/languages/yaml.rs +++ b/src/languages/yaml.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::prettier::format_using_prettier use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum YamlFormatter { #[default] #[serde(rename = "prettier")] @@ -12,6 +13,7 @@ pub enum YamlFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Yaml { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,91 @@ impl LanguageFormatter for Yaml { } } } + +#[cfg(test)] +mod test_yaml { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Yaml, YamlFormatter}; + + const INPUT: &str = " + + +version: 2 +updates: + - package-ecosystem: \"cargo\" + directory: \"/\" + schedule: + interval: \"monthly\" + assignees: + - \"hougesen\" + open-pull-requests-limit: 25 + + - package-ecosystem: \"github-actions\" + directory: \"/\" + schedule: + interval: \"monthly\" + assignees: + - \"hougesen\" + open-pull-requests-limit: 25 + + + "; + + const EXTENSION: &str = crate::languages::Language::Yaml.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Yaml::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let l = Yaml { + enabled: false, + formatter: YamlFormatter::Prettier, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(l.format(snippet_path).expect("it to not fail").is_none()); + } + + #[test] + fn test_prettier() { + let l = Yaml { + enabled: true, + formatter: YamlFormatter::Prettier, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "version: 2 +updates: + - package-ecosystem: \"cargo\" + directory: \"/\" + schedule: + interval: \"monthly\" + assignees: + - \"hougesen\" + open-pull-requests-limit: 25 + + - package-ecosystem: \"github-actions\" + directory: \"/\" + schedule: + interval: \"monthly\" + assignees: + - \"hougesen\" + open-pull-requests-limit: 25 +"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/zig.rs b/src/languages/zig.rs index bd15a41c..95fd0798 100644 --- a/src/languages/zig.rs +++ b/src/languages/zig.rs @@ -5,6 +5,7 @@ use crate::{config::default_enabled, formatters::zigfmt::format_using_zigfmt}; use super::LanguageFormatter; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub enum ZigFormatter { #[default] #[serde(rename = "zigfmt")] @@ -12,6 +13,7 @@ pub enum ZigFormatter { } #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct Zig { #[serde(default = "default_enabled")] pub enabled: bool, @@ -41,3 +43,60 @@ impl LanguageFormatter for Zig { } } } + +#[cfg(test)] +mod test_zig { + use crate::{formatters::setup_snippet, languages::LanguageFormatter}; + + use super::{Zig, ZigFormatter}; + + const INPUT: &str = " + fn add (a : i32 , b : i32 ) i32 { + return a + b ; + + } + "; + + const EXTENSION: &str = crate::languages::Language::Zig.to_file_ext(); + + #[test] + fn it_should_be_enabled_by_default() { + assert!(Zig::default().enabled); + } + + #[test] + fn it_should_not_format_when_enabled_is_false() { + let l = Zig { + enabled: false, + formatter: ZigFormatter::ZigFmt, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + assert!(l.format(snippet_path).expect("it to not fail").is_none()); + } + + #[test] + fn test_zigfmt() { + let l = Zig { + enabled: true, + formatter: ZigFormatter::ZigFmt, + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "fn add(a: i32, b: i32) i32 { + return a + b; +} +"; + + assert_eq!(output, expected_output); + } +} diff --git a/src/lib.rs b/src/lib.rs index 5537ff45..4b4d6e65 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,7 +51,7 @@ pub fn format_file(config: &MdsfConfig, path: &std::path::Path) -> Result<(), Md // NOTE: should be removed once `pulldown-cmark-to-cmark` is upgraded to `v0.10.0` of `pulldown-cmark` let (frontmatter, markdown_input) = - matter(&input).unwrap_or_else(|| (String::new(), input.to_owned())); + matter(&input).unwrap_or_else(|| (String::new(), input.clone())); let parser = pulldown_cmark::Parser::new_ext(&markdown_input, pulldown_cmark::Options::all()); @@ -65,21 +65,25 @@ pub fn format_file(config: &MdsfConfig, path: &std::path::Path) -> Result<(), Md for event in parser { let ev = match event { - pulldown_cmark::Event::Start(start) => { - if let pulldown_cmark::Tag::CodeBlock(pulldown_cmark::CodeBlockKind::Fenced(l)) = - &start - { - codeblock_language = Language::maybe_from_str(l); - } - - pulldown_cmark::Event::Start(start) + pulldown_cmark::Event::Start(pulldown_cmark::Tag::CodeBlock( + pulldown_cmark::CodeBlockKind::Fenced(l), + )) => { + codeblock_language = Language::maybe_from_str(&l); + + pulldown_cmark::Event::Start(pulldown_cmark::Tag::CodeBlock( + pulldown_cmark::CodeBlockKind::Fenced(l), + )) } - pulldown_cmark::Event::End(end) => { + pulldown_cmark::Event::End(pulldown_cmark::Tag::CodeBlock( + pulldown_cmark::CodeBlockKind::Fenced(s), + )) => { if codeblock_language.is_some() { codeblock_language = None; } - pulldown_cmark::Event::End(end) + pulldown_cmark::Event::End(pulldown_cmark::Tag::CodeBlock( + pulldown_cmark::CodeBlockKind::Fenced(s), + )) } pulldown_cmark::Event::Text(text) => { if let Some(language) = &codeblock_language { diff --git a/tests/vue.md b/tests/vue.md new file mode 100644 index 00000000..a9d9f45e --- /dev/null +++ b/tests/vue.md @@ -0,0 +1,20 @@ +```vue + + + + + + +```