Registry / RepositoryTypeScriptRustPython
Rollpie
ReadmeFiles
Versions
Info
Download
0.1.023.4 KB2026-09-14
Version
0.1.0
Copyright
Rollpie, Irohabook
Publisher
math
Published
2026-09-14
Size
23.4 KB
Downloads
1
Checksum
298d198fbc3fc0aecbe6668651a0d3beefb7ff2d1a098483af80cc924d925bdd
Dependencies
None

format.rs

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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//! 整形の結果を確かめる。
//!
//! 原型の jsonfmt の format.rs にあったテストを移し、変えたところのテストを足している。

use simple_json_formatter::{Indent, Options, format};


fn compact() -> Options {
	Options {
		indent: Indent::Compact,
		..Options::default()
	}
}


fn width(max_width: usize) -> Options {
	Options {
		max_width,
		..Options::default()
	}
}


#[test]
fn default_two_spaces() {
	let text = format(r#"{"a":[1,2]}"#, &Options::default()).unwrap();
	assert_eq!(text, "{\n  \"a\": [\n    1,\n    2\n  ]\n}");
}


#[test]
fn tab_indent() {
	let options = Options {
		indent: Indent::Tab,
		..Options::default()
	};
	assert_eq!(format(r#"{"a":1}"#, &options).unwrap(), "{\n\t\"a\": 1\n}");
}


#[test]
fn compact_removes_whitespace() {
	assert_eq!(format(r#"{ "a" : [ 1, 2 ] }"#, &compact()).unwrap(), r#"{"a":[1,2]}"#);
}


#[test]
fn sort_keys_is_recursive() {
	let options = Options {
		sort_keys: true,
		..compact()
	};
	let text = format(r#"{"b":1,"a":{"z":0,"y":0}}"#, &options).unwrap();
	assert_eq!(text, r#"{"a":{"y":0,"z":0},"b":1}"#);
}


#[test]
fn key_order_is_preserved_by_default() {
	assert_eq!(format(r#"{"b":1,"a":2}"#, &compact()).unwrap(), r#"{"b":1,"a":2}"#);
}


#[test]
fn duplicate_keys_are_kept() {
	assert_eq!(format(r#"{"a":1,"a":2}"#, &compact()).unwrap(), r#"{"a":1,"a":2}"#);

	let options = Options {
		sort_keys: true,
		..compact()
	};
	assert_eq!(format(r#"{"b":0,"a":1,"a":2}"#, &options).unwrap(), r#"{"a":1,"a":2,"b":0}"#);
}


#[test]
fn ascii_escape_with_surrogate_pair() {
	let options = Options {
		ensure_ascii: true,
		..compact()
	};
	assert_eq!(format(r#"["あ","𝄞"]"#, &options).unwrap(), "[\"\\u3042\",\"\\ud834\\udd1e\"]");
}


#[test]
fn escapes_are_rewritten() {
	// エスケープは一度解いてから書き直す。\u で書いた文字はその文字になり、\/ は / になる
	assert_eq!(format("[\"\\u3042\"]", &compact()).unwrap(), r#"["あ"]"#);
	assert_eq!(format("[\"\\ud834\\udd1e\"]", &compact()).unwrap(), r#"["𝄞"]"#);
	assert_eq!(format(r#"["\/\"\\"]"#, &compact()).unwrap(), r#"["/\"\\"]"#);
}


#[test]
fn control_chars_are_escaped() {
	assert_eq!(format("[\"a\\u0001b\\n\"]", &compact()).unwrap(), "[\"a\\u0001b\\n\"]");
}


#[test]
fn number_literals_are_preserved() {
	// 原型は 1E5 を 1e+5 にするとしていたが、ここでは元の書き方のまま出す
	let source = r#"[1.50,0.1000,12345678901234567890123,-0.0,1E5,1e+5,-2.5E-3]"#;
	assert_eq!(format(source, &compact()).unwrap(), source);
}


#[test]
fn empty_containers_stay_inline() {
	let text = format(r#"{"a":[],"b":{}}"#, &Options::default()).unwrap();
	assert_eq!(text, "{\n  \"a\": [],\n  \"b\": {}\n}");
}


#[test]
fn scalar_at_top_level() {
	assert_eq!(format("  42  ", &Options::default()).unwrap(), "42");
	assert_eq!(format(r#""abc""#, &Options::default()).unwrap(), r#""abc""#);
	assert_eq!(format("null", &Options::default()).unwrap(), "null");
}


#[test]
fn bom_is_removed() {
	assert_eq!(format("\u{feff}[1]", &compact()).unwrap(), "[1]");
}


#[test]
fn crlf_input_is_read() {
	let text = format("{\r\n  \"a\": 1\r\n}\r\n", &Options::default()).unwrap();
	assert_eq!(text, "{\n  \"a\": 1\n}");
}


#[test]
fn max_width_inlines_small_containers() {
	// 全体が幅に収まるときは、まるごと 1 行になる
	assert_eq!(format(r#"{"a":[1,2,3]}"#, &width(40)).unwrap(), r#"{"a": [1, 2, 3]}"#);
}


#[test]
fn max_width_inlines_only_inner_containers() {
	// 外側は収まらないので展開し、内側の配列だけを 1 行にする。"alpha" の行はちょうど 21 桁
	let text = format(r#"{"alpha":[1,2,3],"beta":[4,5,6]}"#, &width(21)).unwrap();
	assert_eq!(text, "{\n  \"alpha\": [1, 2, 3],\n  \"beta\": [4, 5, 6]\n}");
}


#[test]
fn max_width_counts_key_and_comma() {
	// 原型はキーの長さを数えず、幅 20 でも 21 桁の "alpha" の行を作っていた
	let text = format(r#"{"alpha":[1,2,3],"beta":[4,5,6]}"#, &width(20)).unwrap();
	assert_eq!(text, "{\n  \"alpha\": [\n    1,\n    2,\n    3\n  ],\n  \"beta\": [4, 5, 6]\n}");
}


#[test]
fn max_width_expands_when_too_long() {
	let text = format(r#"{"key":[100,200,300]}"#, &width(10)).unwrap();
	assert_eq!(text, "{\n  \"key\": [\n    100,\n    200,\n    300\n  ]\n}");
}


#[test]
fn max_width_counts_tab_as_four() {
	let options = Options {
		indent: Indent::Tab,
		max_width: 16,
		..Options::default()
	};
	// "ab" の行は後ろにカンマが付くので 17 桁になり、収まらない。"cd" の行は 16 桁で収まる
	let text = format(r#"{"ab":[1,2],"cd":[3,4]}"#, &options).unwrap();
	assert_eq!(text, "{\n\t\"ab\": [\n\t\t1,\n\t\t2\n\t],\n\t\"cd\": [3, 4]\n}");
}


#[test]
fn full_width_chars_count_as_two_columns() {
	// ["あいうえお"] は 9 文字だが 14 桁として扱う
	assert_eq!(format(r#"["あいうえお"]"#, &width(13)).unwrap(), "[\n  \"あいうえお\"\n]");
	assert_eq!(format(r#"["あいうえお"]"#, &width(14)).unwrap(), r#"["あいうえお"]"#);
}