1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! IR regression tests
//!
//! Tests for IR formatting differences between nixfmt-rs and reference nixfmt
use crate::oracle_tests;
use crate::tests_common::test_ir_format;
oracle_tests! {
test_ir_format;
/// Regression test: let expression should wrap letPart and inPart in groups
test_let_expression_groups => [
"{ pinnedJson ? ./pinned.json, }: let pinned = (builtins.fromJSON (builtins.readFile pinnedJson)).pins; in pinned",
],
/// Regression test: function arguments should use Priority groups
test_function_arguments_priority => [
"fetchTarball { url = \"x\"; }",
"lib.filterAttrs (x: y)",
],
/// Regression test: transparent groups in parentheses need Break spacing
test_transparent_in_parens_break => ["(lib.filterAttrs (x: y))"],
/// Regression test: application in assignment RHS should group space with application
///
/// Issue: `nixfmt` groups the space before the application INSIDE the application group,
/// whereas `nixfmt-rs` was putting the space outside.
test_assignment_rhs_application_grouping => ["{ x = f { }; }"],
// `isAbsorbable` / `isAbsorbableExpr` / `absorbExpr` parity with Haskell nixfmt.
// Each test exercises one clause of the Haskell definitions and asserts our IR
// matches `nixfmt --ir -` exactly.
/// `absorbExpr True (Term t)` must use `prettyTermWide`, i.e. force-expand the
/// attrset on the RHS of an assignment.
test_absorb_rhs_set_wide => ["{ x = { a = 1; }; }"],
/// `absorbExpr` on a `with ...; { ... }` must go through `prettyWith True`.
test_absorb_rhs_with_set => ["{ x = with p; { a = 1; }; }"],
/// `isAbsorbableExpr` accepts `Abstraction (IDParameter _) _ (Term t)` when
/// the body is an absorbable term.
test_absorb_rhs_lambda_set => ["{ x = a: { b = 1; }; }"],
/// `isAbsorbableExpr` recurses through chained `IDParameter` abstractions.
test_absorb_rhs_lambda_chain_set => ["{ x = a: b: { c = 1; }; }"],
/// `isAbsorbable (Parenthesized (LoneAnn _) (Term t) _)` recurses into the
/// inner term.
test_absorb_rhs_paren_set => ["{ x = ({ a = 1; }); }"],
/// `isAbsorbable` on an empty set whose braces span multiple source lines.
test_absorb_rhs_empty_set_multiline => ["{ x = {\n}; }"],
/// `isAbsorbable` on a list that contains only comment items.
test_absorb_rhs_comment_only_list => ["{ x = [\n# c\n]; }"],
/// `isAbsorbable` on a multi-line indented string.
test_absorb_rhs_indented_string => ["{ x = ''\n a\n b\n''; }"],
/// Single-`inherit` attrset on the RHS goes through `absorbExpr False` and
/// must not be force-expanded.
test_absorb_rhs_single_inherit => ["{ x = { inherit a; }; }"],
/// Regression test: middle arguments in application should use `absorbLast` logic (`Regular` if not absorbable)
test_middle_arg_grouping => ["lib.pipe pkgs.lixPackageSets [ ]"],
/// Regression test: With expression in assignment RHS should be grouped with the leading space
test_with_grouping => ["{ x = with p; y; }"],
/// Regression test: small simple list as inner application argument uses soft `line` separators
test_inner_arg_simple_list => ["f [ 1 2 3 ] x"],
/// Regression test: list rendering must match Haskell `renderList`/`prettyTerm (List ..)`
test_list_rendering => [
"[ ]",
"[\n]",
"[ # c\n]",
"[ 1 2 ]",
"[\n1 2\n]",
],
/// Regression test: language annotation inside an inner-argument list stays
/// attached to its string with a hardspace (nixfmt f4bbd8c).
test_inner_arg_list_language_annotation => [r#"f [ /* bash */ "x" ] y"#],
/// Regression test: empty lists/sets containing only a comment must be
/// absorbable and rendered with hardlines so formatting is idempotent.
/// <https://github.com/NixOS/nixfmt/issues/362>
test_empty_container_with_comment_idempotent => [
"{ x = [ /* foo */ ]; }",
"{ x = { /* foo */ }; }",
"{ x = [\n# foo\n]; }",
],
/// Regression test: comments after the last attr in a parameter set must be
/// nested like comments between attrs (nixfmt 0f6eb2b).
test_param_set_trailing_comment_nesting => ["{ a,\n# c\n}: x"],
/// Regression: `with` followed by an attrset body
test_with_set_body => ["with p; { a = 1; }"],
/// Regression: `if` nested inside an attrset binding
test_if_in_set => ["{ x = if c then a else b; }"],
/// Regression: `else if` chains are flattened by `prettyIf` instead of nesting
test_if_else_if_chain => ["if c then a else if d then e else f"],
/// Regression: string selectors (`x."y"`) must render their actual content,
/// not a `"..."` placeholder.
test_string_selector_pretty => [r#"x."hello""#],
/// `absorbLast`/`absorbExpr False` must call `prettyTerm`, which (unlike
/// `instance Pretty Term`) does *not* wrap a `List` in an extra group.
/// Haskell: `Nixfmt.Pretty.absorbLast` / `absorbExpr`.
test_absorb_uses_pretty_term_for_list => [
"f [ a ]",
"(x: [ a ])",
],
/// Set-pattern abstraction with an absorbable body wraps the body in
/// `group (prettyTermWide t)`. Haskell: `Nixfmt.Pretty` `Abstraction` clause.
test_set_param_abstraction_absorbs_body => ["{ lib }: { a = 1; }"],
}