Skip to content

Commit f99e393

Browse files
Merge pull request #66 from fabianoflorentino/development
Development to Main
2 parents c816c8a + ebcef07 commit f99e393

File tree

5 files changed

+358
-10
lines changed

5 files changed

+358
-10
lines changed

internal/exercicios_ninja_nivel_3/resolution_exercises_test.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,23 @@ func TestResolucaoExercicioNaPratica3(t *testing.T) {
9090
if year == currentYear {
9191
yearsCount += fmt.Sprintf("%d\n", year)
9292
} else {
93+
if year%11 == 0 {
94+
yearsCount = strings.TrimSuffix(yearsCount, ", ") + ",\n"
95+
}
9396
yearsCount += fmt.Sprintf("%d, ", year)
9497
}
9598
}
9699

97100
age := fmt.Sprintf("%v\nSua idade: %v", yearsCount, currentYear-birthYear)
98101

99102
expect := `
100-
1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024
103+
1985, 1986, 1987, 1988, 1989, 1990,
104+
1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
105+
2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
106+
2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023,
107+
2024, 2025
101108
102-
Sua idade: 39
109+
Sua idade: 40
103110
`
104111

105112
if strings.TrimSpace(age) != strings.TrimSpace(expect) {

internal/exercicios_ninja_nivel_4/resolution_exercises.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ func ResolucaoNaPraticaExercicio7() {
140140
var resolucao string
141141

142142
pessoas := [][]string{
143-
{"Fábio", "Florentino", "Programar"},
143+
{"Fabiano", "Florentino", "Programar"},
144144
{"Fulano", "de Tal", "Jogar bola"},
145145
{"Ciclano", "da Silva", "Assistir filmes"},
146146
}
@@ -161,9 +161,9 @@ func ResolucaoNaPraticaExercicio8() {
161161
var resolucao string
162162

163163
pessoas := map[string][]string{
164-
"florentino_fabio": {"Programar", "Jogar bola", "Assistir filmes"},
165-
"de_tal_fulano": {"Programar", "Jogar bola", "Assistir filmes"},
166-
"da_silva_ciclano": {"Programar 2", "Jogar bola 2", "Assistir filmes 2"},
164+
"florentino_fabiano": {"Programar", "Jogar bola", "Assistir filmes"},
165+
"de_tal_fulano": {"Programar", "Jogar bola", "Assistir filmes"},
166+
"da_silva_ciclano": {"Programar 2", "Jogar bola 2", "Assistir filmes 2"},
167167
}
168168

169169
for sobrenome_nome, hobbies := range pessoas {
@@ -185,10 +185,10 @@ func ResolucaoNaPraticaExercicio9() {
185185
var resolucao string
186186

187187
pessoas := map[string][]string{
188-
"florentino_fabio": {"Programar", "Jogar bola", "Assistir filmes"},
189-
"de_tal_fulano": {"Programar", "Jogar bola", "Assistir filmes"},
190-
"da_silva_ciclano": {"Programar 2", "Jogar bola 2", "Assistir filmes 2"},
191-
"de_tal_ciclano": {"Programar 3", "Jogar bola 3", "Assistir filmes 3"},
188+
"florentino_fabiano": {"Programar", "Jogar bola", "Assistir filmes"},
189+
"de_tal_fulano": {"Programar", "Jogar bola", "Assistir filmes"},
190+
"da_silva_ciclano": {"Programar 2", "Jogar bola 2", "Assistir filmes 2"},
191+
"de_tal_ciclano": {"Programar 3", "Jogar bola 3", "Assistir filmes 3"},
192192
}
193193

194194
for sobrenome_nome, hobbies := range pessoas {
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
// Package exercicios_ninja_nivel_4 contains solutions and tests for exercises
2+
// aimed at practicing and improving Go programming skills. The exercises cover
3+
// various topics and concepts, providing hands-on experience and reinforcing
4+
// understanding of the language.
5+
package exercicios_ninja_nivel_4
6+
7+
import (
8+
"strings"
9+
"testing"
10+
11+
"github.com/fabianoflorentino/aprendago/pkg/output"
12+
"github.com/fabianoflorentino/aprendago/pkg/trim"
13+
)
14+
15+
// testTemplate is a constant string used for formatting test output.
16+
// It provides a template for displaying the expected and actual values
17+
// in test results, making it easier to compare them.
18+
const (
19+
expectTemplate = "\nwant:\n%s\n, \ngot:\n%s\n"
20+
)
21+
22+
// TestResolucaoNaPraticaExercicio1 tests the functionality of iterating over an array of integers,
23+
// concatenating each integer to a string with a comma and space separator, and comparing the result
24+
// to an expected string. If the resulting string does not match the expected string, the test fails.
25+
func TestResolucaoNaPraticaExercicio1(t *testing.T) {
26+
output := output.New()
27+
result := output.Capture(ResolucaoNaPraticaExercicio1)
28+
29+
expect := `
30+
Resolução:
31+
1, 2, 3, 4, 5
32+
`
33+
34+
trim := trim.New()
35+
36+
if !strings.Contains(trim.String(result), trim.String(expect)) {
37+
t.Errorf(expectTemplate, expect, result)
38+
}
39+
}
40+
41+
// TestResolucaoNaPraticaExercicio2 tests the function ResolucaoNaPraticaExercicio2
42+
// by capturing its output and comparing it to the expected output. It uses a
43+
// deferred function to recover from any panic that might occur during the execution
44+
// of ResolucaoNaPraticaExercicio2 and captures the panic message if it happens.
45+
// The test checks if the captured output contains the expected string, ignoring
46+
// leading and trailing whitespace, and reports an error if it does not match.
47+
func TestResolucaoNaPraticaExercicio2(t *testing.T) {
48+
output := output.New()
49+
result := output.Capture(ResolucaoNaPraticaExercicio2)
50+
51+
expect := `
52+
Resolução:
53+
54+
Slice: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
55+
Tipo: []string
56+
`
57+
58+
trim := trim.New()
59+
60+
if !strings.Contains(trim.String(result), trim.String(expect)) {
61+
t.Errorf(expectTemplate, expect, result)
62+
}
63+
}
64+
65+
// TestResolucaoNaPraticaExercicio3 tests the function ResolucaoNaPraticaExercicio3
66+
// by capturing its output and comparing it to the expected result. It uses the
67+
// output.Capture utility to capture the function's output and the trim.New utility
68+
// to normalize the strings before comparison. If the captured output does not
69+
// contain the expected result, the test fails with an error message.
70+
func TestResolucaoNaPraticaExercicio3(t *testing.T) {
71+
output := output.New()
72+
result := output.Capture(ResolucaoNaPraticaExercicio3)
73+
74+
expect := `
75+
Resolução:
76+
77+
Slice: 1, 2, 3, 4
78+
Tipo: []string
79+
`
80+
81+
trim := trim.New()
82+
83+
if !strings.Contains(trim.String(result), trim.String(expect)) {
84+
t.Errorf(expectTemplate, expect, result)
85+
}
86+
}
87+
88+
// TestResolucaoNaPraticaExercicio4 tests the function ResolucaoNaPraticaExercicio4
89+
// by capturing its output and comparing it to the expected result. The test
90+
// verifies that the function correctly appends elements to slices and produces
91+
// the expected output. If the actual output does not match the expected output,
92+
// the test will fail and report the discrepancy.
93+
func TestResolucaoNaPraticaExercicio4(t *testing.T) {
94+
output := output.New()
95+
result := output.Capture(ResolucaoNaPraticaExercicio4)
96+
97+
expect := `
98+
Resolução:
99+
append52: [42 43 44 45 46 47 48 49 50 51 52]
100+
append53to55: [42 43 44 45 46 47 48 49 50 51 52 53 54 55]
101+
appendSliceY: [42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60]
102+
`
103+
trim := trim.New()
104+
105+
if !strings.Contains(trim.String(result), trim.String(expect)) {
106+
t.Errorf(expectTemplate, expect, result)
107+
}
108+
}
109+
110+
// TestResolucaoNaPraticaExercicio5 tests the function ResolucaoNaPraticaExercicio5
111+
// by capturing its output and comparing it to the expected result.
112+
// It uses the output.Capture utility to capture the function's output
113+
// and the trim.New utility to normalize the strings before comparison.
114+
// If the captured output does not contain the expected result, the test fails
115+
// and an error message is displayed.
116+
func TestResolucaoNaPraticaExercicio5(t *testing.T) {
117+
output := output.New()
118+
result := output.Capture(ResolucaoNaPraticaExercicio5)
119+
120+
expect := `
121+
Resolução:
122+
[42 43 44 48 49 50 51]
123+
`
124+
trim := trim.New()
125+
126+
if !strings.Contains(trim.String(result), trim.String(expect)) {
127+
t.Errorf(expectTemplate, expect, result)
128+
}
129+
}
130+
131+
// TestResolucaoNaPraticaExercicio6 tests the function ResolucaoNaPraticaExercicio6.
132+
// It captures the output of the function and compares it with the expected result.
133+
// If the captured output does not match the expected result, the test fails with an error message.
134+
func TestResolucaoNaPraticaExercicio6(t *testing.T) {
135+
output := output.New()
136+
result := output.Capture(ResolucaoNaPraticaExercicio6)
137+
138+
expect := `
139+
Resolução:
140+
len: 26 cap: 26
141+
Estados: Acre, Alagoas, Amapá, Amazonas, Bahia, Ceará, Espírito Santo, Goiás, Maranhão, Mato Grosso, Mato Grosso do Sul, Minas Gerais, Pará, Paraíba, Paraná, Pernambuco, Piauí, Rio de Janeiro, Rio Grande do Norte, Rio Grande do Sul, Rondônia, Roraima, Santa Catarina, São Paulo, Sergipe, Tocantins
142+
`
143+
144+
trim := trim.New()
145+
146+
if !strings.Contains(trim.String(result), trim.String(expect)) {
147+
t.Errorf(expectTemplate, expect, result)
148+
}
149+
}
150+
151+
// TestResolucaoNaPraticaExercicio7 tests the function ResolucaoNaPraticaExercicio7
152+
// by capturing its output and comparing it to the expected result. The test
153+
// verifies that the output contains the expected formatted strings for names,
154+
// surnames, and favorite hobbies.
155+
func TestResolucaoNaPraticaExercicio7(t *testing.T) {
156+
output := output.New()
157+
result := output.Capture(ResolucaoNaPraticaExercicio7)
158+
159+
expect := `
160+
Resolução:
161+
Nome: Fabiano, Sobrenome: Florentino, Hobby favorito: Programar
162+
Nome: Fulano, Sobrenome: de Tal, Hobby favorito: Jogar bola
163+
Nome: Ciclano, Sobrenome: da Silva, Hobby favorito: Assistir filmes
164+
`
165+
166+
trim := trim.New()
167+
168+
if !strings.Contains(trim.String(result), trim.String(expect)) {
169+
t.Errorf(expectTemplate, expect, result)
170+
}
171+
}
172+
173+
// TestResolucaoNaPraticaExercicio8 tests the function ResolucaoNaPraticaExercicio8
174+
// by capturing its output and comparing it with the expected result. The test
175+
// checks if the output contains the expected formatted string with names and hobbies.
176+
// If the output does not match the expected result, the test will fail and report an error.
177+
func TestResolucaoNaPraticaExercicio8(t *testing.T) {
178+
output := output.New()
179+
result := output.Capture(ResolucaoNaPraticaExercicio8)
180+
181+
expect := `
182+
Resolução:
183+
Sobrenome_Nome: florentino_fabiano
184+
Hobby 1: Programar
185+
Hobby 2: Jogar bola
186+
Hobby 3: Assistir filmes
187+
Sobrenome_Nome: de_tal_fulano
188+
Hobby 1: Programar
189+
Hobby 2: Jogar bola
190+
Hobby 3: Assistir filmes
191+
Sobrenome_Nome: da_silva_ciclano
192+
Hobby 1: Programar 2
193+
Hobby 2: Jogar bola 2
194+
Hobby 3: Assistir filmes 2
195+
`
196+
197+
trim := trim.New()
198+
199+
if !strings.Contains(trim.String(result), trim.String(expect)) {
200+
t.Errorf(expectTemplate, expect, result)
201+
}
202+
}
203+
204+
// TestResolucaoNaPraticaExercicio9 tests the function ResolucaoNaPraticaExercicio9
205+
// by capturing its output and comparing it to the expected result. The test
206+
// verifies that the output contains the expected formatted strings for different
207+
// individuals and their hobbies. If the output does not match the expected result,
208+
// the test will fail and report the discrepancy.
209+
func TestResolucaoNaPraticaExercicio9(t *testing.T) {
210+
output := output.New()
211+
result := output.Capture(ResolucaoNaPraticaExercicio9)
212+
213+
expect := `
214+
Resolução:
215+
Sobrenome_Nome: florentino_fabiano
216+
Hobby 1: Programar
217+
Hobby 2: Jogar bola
218+
Hobby 3: Assistir filmes
219+
Sobrenome_Nome: de_tal_fulano
220+
Hobby 1: Programar
221+
Hobby 2: Jogar bola
222+
Hobby 3: Assistir filmes
223+
Sobrenome_Nome: da_silva_ciclano
224+
Hobby 1: Programar 2
225+
Hobby 2: Jogar bola 2
226+
Hobby 3: Assistir filmes 2
227+
Sobrenome_Nome: de_tal_ciclano
228+
Hobby 1: Programar 3
229+
Hobby 2: Jogar bola 3
230+
Hobby 3: Assistir filmes 3
231+
`
232+
233+
trim := trim.New()
234+
235+
if !strings.Contains(trim.String(result), trim.String(expect)) {
236+
t.Errorf(expectTemplate, expect, result)
237+
}
238+
}
239+
240+
// TestResolucaoNaPraticaExercicio10 tests the function ResolucaoNaPraticaExercicio10.
241+
// It captures the output of the function and compares it with the expected output.
242+
// If the captured output does not match the expected output, the test fails and an error is reported.
243+
func TestResolucaoNaPraticaExercicio10(t *testing.T) {
244+
output := output.New()
245+
result := output.Capture(ResolucaoNaPraticaExercicio10)
246+
247+
expect := `
248+
Resolução:
249+
Sobrenome_Nome: florentino_fabio
250+
Hobby 1: Programar
251+
Hobby 2: Jogar bola
252+
Hobby 3: Assistir filmes
253+
Sobrenome_Nome: de_tal_fulano
254+
Hobby 1: Programar
255+
Hobby 2: Jogar bola
256+
Hobby 3: Assistir filmes
257+
Sobrenome_Nome: de_tal_ciclano
258+
Hobby 1: Programar 3
259+
Hobby 2: Jogar bola 3
260+
Hobby 3: Assistir filmes 3
261+
`
262+
263+
trim := trim.New()
264+
265+
if !strings.Contains(trim.String(result), trim.String(expect)) {
266+
t.Errorf(expectTemplate, expect, result)
267+
}
268+
}

pkg/output/output.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Package output provides utilities for capturing and redirecting standard output.
2+
// It allows capturing the output of functions that write to os.Stdout and returning
3+
// the captured output as a string. This can be useful for testing and logging purposes.
4+
package output
5+
6+
import (
7+
"bytes"
8+
"io"
9+
"os"
10+
)
11+
12+
// Output represents a structure that holds file descriptors for standard output,
13+
// and read/write operations. It contains the following fields:
14+
// - stdout: a file descriptor for standard output.
15+
// - read: a file descriptor for reading operations.
16+
// - write: a file descriptor for writing operations.
17+
type Output struct {
18+
stdout *os.File
19+
read *os.File
20+
write *os.File
21+
}
22+
23+
// New creates a new Output instance with a pipe for reading and writing.
24+
// It returns a pointer to the Output struct with stdout set to the standard output,
25+
// and read and write set to the ends of the pipe.
26+
func New() *Output {
27+
read, write, _ := os.Pipe()
28+
29+
return &Output{
30+
stdout: os.Stdout,
31+
read: read,
32+
write: write,
33+
}
34+
}
35+
36+
// Capture redirects the standard output to a buffer, executes the provided
37+
// captureOutput function, and then restores the standard output. It returns
38+
// the captured output as a string. This is useful for capturing and testing
39+
// output generated by functions that write to standard output.
40+
func (o *Output) Capture(captureOutput func()) string {
41+
var buf bytes.Buffer
42+
43+
os.Stdout = o.write
44+
45+
captureOutput()
46+
47+
o.write.Close()
48+
49+
os.Stdout = o.stdout
50+
io.Copy(&buf, o.read)
51+
52+
return buf.String()
53+
}

0 commit comments

Comments
 (0)