xcpretty 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +3 -1
- data/CHANGELOG.md +24 -0
- data/README.md +3 -1
- data/Rakefile +6 -1
- data/bin/xcpretty +51 -16
- data/features/custom_formatter.feature +15 -0
- data/features/junit_report.feature +9 -1
- data/features/simple_format.feature +68 -4
- data/features/steps/formatting_steps.rb +87 -4
- data/features/steps/junit_steps.rb +18 -6
- data/features/steps/xcpretty_steps.rb +7 -0
- data/features/support/env.rb +18 -15
- data/features/test_format.feature +1 -0
- data/features/xcpretty.feature +12 -0
- data/lib/xcpretty.rb +25 -3
- data/lib/xcpretty/ansi.rb +1 -0
- data/lib/xcpretty/formatters/formatter.rb +90 -0
- data/lib/xcpretty/formatters/rspec.rb +22 -0
- data/lib/xcpretty/formatters/simple.rb +137 -0
- data/lib/xcpretty/parser.rb +283 -0
- data/lib/xcpretty/printer.rb +7 -112
- data/lib/xcpretty/reporters/junit.rb +53 -45
- data/lib/xcpretty/syntax.rb +22 -0
- data/lib/xcpretty/version.rb +1 -1
- data/spec/fixtures/constants.rb +63 -15
- data/spec/fixtures/custom_formatter.rb +17 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/matchers/colors.rb +1 -1
- data/spec/xcpretty/formatters/formatter_spec.rb +56 -0
- data/spec/xcpretty/formatters/rspec_spec.rb +46 -0
- data/spec/xcpretty/formatters/simple_spec.rb +132 -0
- data/spec/xcpretty/parser_spec.rb +258 -0
- data/spec/xcpretty/printer_spec.rb +39 -74
- data/spec/xcpretty/syntax_spec.rb +35 -0
- data/xcpretty.gemspec +1 -1
- metadata +40 -25
- data/lib/xcpretty/printers/rspec.rb +0 -23
- data/lib/xcpretty/printers/simple.rb +0 -153
- data/spec/xcpretty/printers/printer_spec.rb +0 -117
- data/spec/xcpretty/printers/rspec_spec.rb +0 -52
- data/spec/xcpretty/printers/simple_spec.rb +0 -125
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06619c3a83d263be409e3bee7dc0a009109cf64b
|
4
|
+
data.tar.gz: 8db1bce60835effe0b001a1830ee5ed0ba329674
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35cb3372bbb59ce200426ac5004600fc9baa075d5521828b1251d5da537eece20e8f3ba56743b50ff23295d7a33ce8e3c15311ca2e0e8ccc387bf30c87e56f16
|
7
|
+
data.tar.gz: ba72fb7e9c12f1c7570a20c38b1e08a3d93968af21ceb1adf41c2c676ec282e6fce5748e53617c4de9915cae63dfc544fb06d4b664a3a61fcd438a56f1fdbf4c
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## master
|
4
|
+
|
5
|
+
###### Enhancements
|
6
|
+
|
7
|
+
* exit(1) if xcodebuild failure detected
|
8
|
+
|
9
|
+
* Print compile errors nicely. Currently we support compiler erorrs,
|
10
|
+
and Pods-not-installed errors. Missing mach-o-linker failures
|
11
|
+
|
12
|
+
* Added support for loading arbitrary custom printers (experimental) |
|
13
|
+
[Eloy Durán](https://github.com/alloy) |
|
14
|
+
[#29](https://github.com/mneorr/xcpretty/pulls/29)
|
15
|
+
|
16
|
+
* Show help banner in case no data is piped in |
|
17
|
+
[Eloy Durán](https://github.com/alloy) |
|
18
|
+
[#29](https://github.com/mneorr/xcpretty/pulls/29)
|
19
|
+
|
20
|
+
## 0.0.6
|
21
|
+
|
22
|
+
###### Enhancements
|
23
|
+
|
24
|
+
* Added support for reporters
|
25
|
+
* Added JUnit reporter
|
26
|
+
|
3
27
|
## 0.0.5
|
4
28
|
|
5
29
|
###### Bug Fixes
|
data/README.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
# XCPretty
|
1
|
+
# XCPretty
|
2
2
|
|
3
3
|
__XCPretty is a fast and flexible formatter for `xcodebuild`__.<br/>
|
4
4
|
It does one thing, and it should do it well.
|
5
5
|
|
6
|
+
[](https://travis-ci.org/mneorr/XCPretty)
|
7
|
+
[](https://codeclimate.com/github/mneorr/XCPretty)
|
6
8
|
## Installation
|
7
9
|
|
8
10
|
$ gem install xcpretty
|
data/Rakefile
CHANGED
@@ -5,14 +5,19 @@ task :kick do
|
|
5
5
|
end
|
6
6
|
|
7
7
|
task :spec do
|
8
|
-
sh 'rspec spec'
|
8
|
+
sh 'rspec spec --color --format nested'
|
9
9
|
end
|
10
10
|
|
11
11
|
task :cucumber do
|
12
12
|
sh 'cucumber'
|
13
13
|
end
|
14
14
|
|
15
|
+
task :install_tools do
|
16
|
+
sh 'sudo pip install Pygments'
|
17
|
+
end
|
18
|
+
|
15
19
|
task :ci do
|
20
|
+
Rake::Task[:install_tools].invoke
|
16
21
|
Rake::Task[:spec].invoke
|
17
22
|
Rake::Task[:cucumber].invoke
|
18
23
|
end
|
data/bin/xcpretty
CHANGED
@@ -1,49 +1,84 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
$:.unshift File.expand_path('../../lib', __FILE__)
|
3
|
-
require 'xcpretty'
|
4
|
-
require 'optparse'
|
5
2
|
|
6
3
|
if RUBY_VERSION < '1.8.7'
|
7
4
|
abort "error: XCPretty requires Ruby 1.8.7 or higher."
|
8
5
|
end
|
9
6
|
|
7
|
+
if $0 == __FILE__
|
8
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
9
|
+
end
|
10
|
+
require 'xcpretty'
|
11
|
+
require 'optparse'
|
12
|
+
|
13
|
+
def class_from_path(path)
|
14
|
+
source = File.read(path)
|
15
|
+
klass = eval(source, nil, path)
|
16
|
+
raise unless klass.is_a?(Class)
|
17
|
+
klass
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_custom_formatter(path)
|
21
|
+
begin
|
22
|
+
$:.unshift File.dirname(path)
|
23
|
+
class_from_path(path)
|
24
|
+
rescue SyntaxError => e
|
25
|
+
$stderr.puts "[!] Expected formatter source file to return a class. #{e}"
|
26
|
+
exit 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
10
30
|
report_formats = {
|
11
31
|
"junit" => XCPretty::JUnit
|
12
32
|
}
|
13
33
|
|
34
|
+
constructor = {
|
35
|
+
:unicode => true,
|
36
|
+
:colorize => false,
|
37
|
+
:formatter => XCPretty::Simple
|
38
|
+
}
|
39
|
+
|
40
|
+
reporter_classes = []
|
41
|
+
|
14
42
|
OptionParser.new do |opts|
|
15
|
-
@report_formats = []
|
16
43
|
opts.banner = "Usage: xcodebuild [options] | xcpretty"
|
17
44
|
opts.on('-t', '--test', 'Use RSpec style output') do
|
18
|
-
|
45
|
+
constructor[:formatter] = XCPretty::RSpec
|
19
46
|
end
|
20
47
|
opts.on('-s', '--simple', 'Use simple output (default)') do
|
21
|
-
|
48
|
+
constructor[:formatter] = XCPretty::Simple
|
49
|
+
end
|
50
|
+
opts.on('-f', '--formatter PATH', 'Use formatter returned from evaluating the specified Ruby file') do |path|
|
51
|
+
constructor[:formatter] = load_custom_formatter(path)
|
22
52
|
end
|
23
53
|
opts.on('-c', '--color', 'Use colorized output') do
|
24
|
-
|
54
|
+
constructor[:colorize] = true
|
25
55
|
end
|
26
56
|
opts.on('--no-utf', 'Disable unicode characters in output') do
|
27
|
-
|
57
|
+
constructor[:unicode] = false
|
28
58
|
end
|
29
59
|
opts.on("-r", "--report FORMAT", "Run FORMAT reporter",
|
30
60
|
" Choices: #{report_formats.keys.join(', ')}") do |format|
|
31
|
-
|
61
|
+
reporter_classes << report_formats[format]
|
32
62
|
end
|
33
63
|
opts.on_tail('-h', '--help', 'Show this message') { puts opts; exit }
|
34
64
|
opts.on_tail("-v", "--version", "Show version") { puts XCPretty::VERSION; exit }
|
35
|
-
opts.parse!
|
36
|
-
end
|
37
65
|
|
38
|
-
|
39
|
-
|
40
|
-
|
66
|
+
if STDIN.tty?
|
67
|
+
$stderr.puts opts.help
|
68
|
+
exit 1
|
69
|
+
else
|
70
|
+
opts.parse!
|
71
|
+
end
|
72
|
+
end
|
41
73
|
|
42
|
-
|
74
|
+
printer = XCPretty::Printer.new(constructor)
|
75
|
+
reporters = reporter_classes.compact.map(&:new)
|
43
76
|
|
44
77
|
ARGF.each_line do |line|
|
78
|
+
XCPretty::ExitStatus.handle(line)
|
45
79
|
printer.pretty_print(line)
|
46
|
-
reporters.each {|r| r.handle(line) }
|
80
|
+
reporters.each { |r| r.handle(line) }
|
47
81
|
end
|
48
82
|
|
49
83
|
reporters.each(&:finish)
|
84
|
+
exit(XCPretty::ExitStatus.code)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: Loading an arbitrary Ruby file as a formatter
|
2
|
+
|
3
|
+
Scenario: The file loaded does not contain a Ruby class
|
4
|
+
When I pipe to xcpretty with "--formatter /bin/bash"
|
5
|
+
Then the exit status code should be 1
|
6
|
+
|
7
|
+
Scenario: The file loaded contains a Ruby class
|
8
|
+
Given I have a file to compile
|
9
|
+
When I pipe to xcpretty with a custom formatter
|
10
|
+
Then the exit status code should be 0
|
11
|
+
|
12
|
+
Scenario: Showing output using a custom formatter
|
13
|
+
Given I have a file to compile
|
14
|
+
When I pipe to xcpretty with a custom formatter
|
15
|
+
Then I should see a custom compilation message
|
@@ -4,6 +4,7 @@ Feature: Creating a JUnit test report
|
|
4
4
|
Given the tests have started running
|
5
5
|
|
6
6
|
Scenario: Showing a test suite
|
7
|
+
Given I have a passing test in my suite
|
7
8
|
When I pipe to xcpretty with "--report junit"
|
8
9
|
Then I should see a test suite node
|
9
10
|
|
@@ -20,5 +21,12 @@ Feature: Creating a JUnit test report
|
|
20
21
|
Scenario: Counting tests
|
21
22
|
Given I have a passing test in my suite
|
22
23
|
And I have a failing test in my suite
|
24
|
+
And the test suite has finished
|
25
|
+
When I pipe to xcpretty with "--report junit"
|
26
|
+
Then I should see 2 tests in my report
|
27
|
+
|
28
|
+
Scenario: Having many test classes
|
29
|
+
Given I have tests in my suite from 2 classes
|
23
30
|
When I pipe to xcpretty with "--report junit"
|
24
|
-
Then I should see 2
|
31
|
+
Then I should see 2 test suites
|
32
|
+
|
@@ -5,6 +5,11 @@ Feature: Showing build output in simple format
|
|
5
5
|
When I pipe to xcpretty with "--simple"
|
6
6
|
Then I should see a successful compilation message
|
7
7
|
|
8
|
+
Scenario: Showing xib compilation
|
9
|
+
Given I have a xib to compile
|
10
|
+
When I pipe to xcpretty with "--simple"
|
11
|
+
Then I should see a successful compilation message
|
12
|
+
|
8
13
|
Scenario: Showing precompilation
|
9
14
|
Given I have a precompiled header
|
10
15
|
When I pipe to xcpretty with "--simple"
|
@@ -15,11 +20,36 @@ Feature: Showing build output in simple format
|
|
15
20
|
When I pipe to xcpretty with "--simple --color"
|
16
21
|
Then I should see a yellow completion icon
|
17
22
|
|
23
|
+
Scenario: Showing xib compilation with color
|
24
|
+
Given I have a xib to compile
|
25
|
+
When I pipe to xcpretty with "--simple --color"
|
26
|
+
Then I should see a yellow completion icon
|
27
|
+
|
18
28
|
Scenario: Showing precompilation
|
19
29
|
Given I have a precompiled header
|
20
30
|
When I pipe to xcpretty with "--simple --color"
|
21
31
|
Then I should see a yellow completion icon
|
22
32
|
|
33
|
+
Scenario: Showing analyze
|
34
|
+
Given I have a file to analyze
|
35
|
+
When I pipe to xcpretty with "--simple"
|
36
|
+
Then I should see a successful analyze message
|
37
|
+
|
38
|
+
Scenario: Showing shallow analyze
|
39
|
+
Given I have a file to shallow analyze
|
40
|
+
When I pipe to xcpretty with "--simple"
|
41
|
+
Then I should see a successful analyze message
|
42
|
+
|
43
|
+
Scenario: Showing analyze with color
|
44
|
+
Given I have a file to analyze
|
45
|
+
When I pipe to xcpretty with "--simple --color"
|
46
|
+
Then I should see a yellow completion icon
|
47
|
+
|
48
|
+
Scenario: Showing shallow analyze with color
|
49
|
+
Given I have a file to shallow analyze
|
50
|
+
When I pipe to xcpretty with "--simple --color"
|
51
|
+
Then I should see a yellow completion icon
|
52
|
+
|
23
53
|
Scenario: Showing the start of a test run
|
24
54
|
Given the tests have started running
|
25
55
|
When I pipe to xcpretty with "--simple"
|
@@ -31,12 +61,13 @@ Feature: Showing build output in simple format
|
|
31
61
|
Then I should see the name of suite only
|
32
62
|
|
33
63
|
Scenario: Showing the end of a test suite
|
34
|
-
Given
|
64
|
+
Given the test suite has finished
|
35
65
|
When I pipe to xcpretty with "--simple"
|
36
66
|
Then I should see that the test suite finished
|
37
67
|
|
38
68
|
Scenario: Showing failed test output
|
39
69
|
Given I have a failing test in my suite
|
70
|
+
And the test suite has finished
|
40
71
|
When I pipe to xcpretty with "--simple"
|
41
72
|
Then I should see the name of a failed test
|
42
73
|
And I should see the path of a failed test
|
@@ -50,18 +81,51 @@ Feature: Showing build output in simple format
|
|
50
81
|
|
51
82
|
Scenario: Showing failed test output with color
|
52
83
|
Given I have a failing test in my suite
|
53
|
-
And
|
84
|
+
And the test suite has finished
|
54
85
|
When I pipe to xcpretty with "--simple --color"
|
55
86
|
Then I should see a red failed test mark
|
56
87
|
And the final execution message should be red
|
57
88
|
|
58
89
|
Scenario: Showing successful test output with color
|
59
90
|
Given I have a passing test in my suite
|
60
|
-
And
|
91
|
+
And the test suite has finished
|
61
92
|
When I pipe to xcpretty with "--simple --color"
|
62
93
|
Then I should see a green passing test mark
|
63
94
|
|
64
95
|
Scenario: Running tests without UTF-8 support
|
65
96
|
Given I have a passing test in my suite
|
66
|
-
And I pipe to xcpretty with "--no-utf"
|
97
|
+
And I pipe to xcpretty with "--no-utf --color"
|
67
98
|
Then I should see a non-utf prefixed output
|
99
|
+
|
100
|
+
Scenario: Showing code signing
|
101
|
+
Given I have a file to code sign
|
102
|
+
When I pipe to xcpretty with "--simple"
|
103
|
+
Then I should see a successful code signing message
|
104
|
+
|
105
|
+
Scenario: Showing code signing a framework
|
106
|
+
Given I have a framework to code sign
|
107
|
+
When I pipe to xcpretty with "--simple"
|
108
|
+
Then I should see a successful code signing message
|
109
|
+
|
110
|
+
Scenario: Showing preprocess
|
111
|
+
Given I have a file to preprocess
|
112
|
+
When I pipe to xcpretty with "--simple"
|
113
|
+
Then I should see a successful preprocessing message
|
114
|
+
|
115
|
+
Scenario: Showing a PBXCp copy
|
116
|
+
Given I have a file to copy with PBXCp
|
117
|
+
When I pipe to xcpretty with "--simple"
|
118
|
+
Then I should see a successful copying message
|
119
|
+
|
120
|
+
Scenario: Build fails when Pod install hasn't been run
|
121
|
+
Given podfile.lock wasn't in sync
|
122
|
+
When I pipe to xcpretty with "--simple --color"
|
123
|
+
Then I should see a red error message
|
124
|
+
|
125
|
+
Scenario: Compilation fails because of syntax errors
|
126
|
+
Given there was a syntax error
|
127
|
+
When I pipe to xcpretty with "--simple --color"
|
128
|
+
Then I should see a red compilation error
|
129
|
+
And I should see a failed line
|
130
|
+
And I should see a cyan cursor
|
131
|
+
|
@@ -3,10 +3,22 @@ Given(/^I have a file to compile$/) do
|
|
3
3
|
add_run_input SAMPLE_COMPILE
|
4
4
|
end
|
5
5
|
|
6
|
+
Given(/^I have a xib to compile$/) do
|
7
|
+
add_run_input SAMPLE_COMPILE_XIB
|
8
|
+
end
|
9
|
+
|
6
10
|
Given(/^I have a precompiled header$/) do
|
7
11
|
add_run_input SAMPLE_PRECOMPILE
|
8
12
|
end
|
9
13
|
|
14
|
+
Given(/^I have a file to analyze$/) do
|
15
|
+
add_run_input SAMPLE_ANALYZE
|
16
|
+
end
|
17
|
+
|
18
|
+
Given(/^I have a file to shallow analyze$/) do
|
19
|
+
add_run_input SAMPLE_ANALYZE_SHALLOW
|
20
|
+
end
|
21
|
+
|
10
22
|
Given(/^I have a failing test in my suite$/) do
|
11
23
|
add_run_input SAMPLE_SPECTA_FAILURE
|
12
24
|
end
|
@@ -27,14 +39,54 @@ Given(/^I start a test suite$/) do
|
|
27
39
|
add_run_input SAMPLE_OCUNIT_SUITE_BEGINNING
|
28
40
|
end
|
29
41
|
|
30
|
-
Given(/^
|
42
|
+
Given(/^the test suite has finished$/) do
|
31
43
|
add_run_input SAMPLE_OCUNIT_SUITE_COMPLETION
|
44
|
+
add_run_input SAMPLE_EXECUTED_TESTS
|
45
|
+
end
|
46
|
+
|
47
|
+
Given(/^I have a file to code sign$/) do
|
48
|
+
add_run_input SAMPLE_CODESIGN
|
49
|
+
end
|
50
|
+
|
51
|
+
Given(/^I have a framework to code sign$/) do
|
52
|
+
add_run_input SAMPLE_CODESIGN_FRAMEWORK
|
53
|
+
end
|
54
|
+
|
55
|
+
Given(/^I have a file to preprocess$/) do
|
56
|
+
add_run_input SAMPLE_PREPROCESS
|
57
|
+
end
|
58
|
+
|
59
|
+
Given(/^I have a file to copy with PBXCp/) do
|
60
|
+
add_run_input SAMPLE_PBXCP
|
61
|
+
end
|
62
|
+
|
63
|
+
Given(/^podfile.lock wasn't in sync$/) do
|
64
|
+
add_run_input SAMPLE_PODS_ERROR
|
65
|
+
end
|
66
|
+
|
67
|
+
Given(/^there was a syntax error$/) do
|
68
|
+
SAMPLE_COMPILE_ERROR.split("\n").each do |line|
|
69
|
+
add_run_input(line)
|
70
|
+
end
|
32
71
|
end
|
33
72
|
|
34
73
|
When(/^I pipe to xcpretty with "(.*?)"$/) do |flags|
|
35
74
|
run_xcpretty(flags)
|
36
75
|
end
|
37
76
|
|
77
|
+
When(/^I pipe to xcpretty with a custom formatter$/) do
|
78
|
+
formatter_path = File.expand_path('../../../spec/fixtures/custom_formatter.rb', __FILE__)
|
79
|
+
run_xcpretty("-f #{formatter_path}")
|
80
|
+
end
|
81
|
+
|
82
|
+
When(/^I pipe to xcpretty$/) do
|
83
|
+
run_xcpretty("")
|
84
|
+
end
|
85
|
+
|
86
|
+
Then(/^I should see a custom compilation message$/) do
|
87
|
+
run_output.should start_with("😎 Compilation party time")
|
88
|
+
end
|
89
|
+
|
38
90
|
Then(/^I should see a successful compilation message$/) do
|
39
91
|
run_output.should start_with("▸ Compiling")
|
40
92
|
end
|
@@ -43,6 +95,22 @@ Then(/^I should see a successful precompilation message$/) do
|
|
43
95
|
run_output.should start_with("▸ Precompiling")
|
44
96
|
end
|
45
97
|
|
98
|
+
Then(/^I should see a successful analyze message$/) do
|
99
|
+
run_output.should start_with("▸ Analyzing")
|
100
|
+
end
|
101
|
+
|
102
|
+
Then(/^I should see a successful code signing message$/) do
|
103
|
+
run_output.should start_with("▸ Signing")
|
104
|
+
end
|
105
|
+
|
106
|
+
Then(/^I should see a successful preprocessing message$/) do
|
107
|
+
run_output.should start_with("▸ Preprocessing")
|
108
|
+
end
|
109
|
+
|
110
|
+
Then(/^I should see a successful copying message$/) do
|
111
|
+
run_output.should start_with("▸ Copying")
|
112
|
+
end
|
113
|
+
|
46
114
|
Then(/^I should see a yellow completion icon$/) do
|
47
115
|
run_output.should start_with(yellow("▸"))
|
48
116
|
end
|
@@ -105,11 +173,26 @@ Then(/^I should see a green passing test mark$/) do
|
|
105
173
|
end
|
106
174
|
|
107
175
|
Then(/^I should see a non-utf prefixed output$/) do
|
108
|
-
run_output.should start_with(".")
|
176
|
+
run_output.should start_with(green("."))
|
109
177
|
end
|
110
178
|
|
179
|
+
Then(/^I should not see the name of the test group$/) do
|
180
|
+
run_output.should_not include("RACTupleSpec")
|
181
|
+
end
|
111
182
|
|
183
|
+
Then(/^I should see a red error message$/) do
|
184
|
+
run_output.should include(red("⌦ ") + " " + red(SAMPLE_PODS_ERROR.gsub('error: ', '')))
|
185
|
+
end
|
112
186
|
|
113
|
-
Then(/^I should
|
114
|
-
run_output.
|
187
|
+
Then(/^I should see a red compilation error$/) do
|
188
|
+
run_output.should include(red("expected identifier"))
|
115
189
|
end
|
190
|
+
|
191
|
+
Then(/^I should see a failed line$/) do
|
192
|
+
run_output.should include("[[thread.lastMessage should] equal:thread.];")
|
193
|
+
end
|
194
|
+
|
195
|
+
Then(/^I should see a cyan cursor$/) do
|
196
|
+
run_output.should include(cyan(" ^"))
|
197
|
+
end
|
198
|
+
|