How to use TestMap method of td_test Package

Best Go-testdeep code snippet using td_test.TestMap

td_map_test.go

Source:td_map_test.go Github

copy

Full Screen

...8 "testing"9 "github.com/maxatome/go-testdeep/internal/test"10 "github.com/maxatome/go-testdeep/td"11)12func TestMap(t *testing.T) {13 type MyMap map[string]int14 //15 // Map16 checkOK(t, (map[string]int)(nil), td.Map(map[string]int{}, nil))17 checkError(t, nil, td.Map(map[string]int{}, nil),18 expectedError{19 Message: mustBe("values differ"),20 Path: mustBe(`DATA`),21 Got: mustBe("nil"),22 Expected: mustBe("map[string]int{}"),23 })24 gotMap := map[string]int{"foo": 1, "bar": 2}25 checkOK(t, gotMap, td.Map(map[string]int{"foo": 1, "bar": 2}, nil))26 checkOK(t, gotMap,27 td.Map(map[string]int{"foo": 1}, td.MapEntries{"bar": 2}))28 checkOK(t, gotMap,29 td.Map(map[string]int{}, td.MapEntries{"foo": 1, "bar": 2}))30 checkOK(t, gotMap,31 td.Map((map[string]int)(nil), td.MapEntries{"foo": 1, "bar": 2}))32 one := 133 checkOK(t, map[string]*int{"foo": nil, "bar": &one},34 td.Map(map[string]*int{}, td.MapEntries{"foo": nil, "bar": &one}))35 checkError(t, gotMap, td.Map(map[string]int{"foo": 1, "bar": 3}, nil),36 expectedError{37 Message: mustBe("values differ"),38 Path: mustBe(`DATA["bar"]`),39 Got: mustBe("2"),40 Expected: mustBe("3"),41 })42 checkError(t, gotMap, td.Map(map[string]int{}, nil),43 expectedError{44 Message: mustBe("comparing hash keys of %%"),45 Path: mustBe("DATA"),46 Summary: mustMatch(`^Extra 2 keys: \("bar",\s+"foo"\)\z`),47 })48 checkError(t, gotMap, td.Map(map[string]int{"test": 2}, nil),49 expectedError{50 Message: mustBe("comparing hash keys of %%"),51 Path: mustBe("DATA"),52 Summary: mustMatch(53 `^ Missing key: \("test"\)\nExtra 2 keys: \("bar",\s+"foo"\)\z`),54 })55 checkError(t, gotMap,56 td.Map(map[string]int{}, td.MapEntries{"test": 2}),57 expectedError{58 Message: mustBe("comparing hash keys of %%"),59 Path: mustBe("DATA"),60 Summary: mustMatch(61 `^ Missing key: \("test"\)\nExtra 2 keys: \("bar",\s+"foo"\)\z`),62 })63 checkError(t, gotMap,64 td.Map(map[string]int{}, td.MapEntries{"foo": 1, "bar": 2, "test": 2}),65 expectedError{66 Message: mustBe("comparing hash keys of %%"),67 Path: mustBe("DATA"),68 Summary: mustBe(`Missing key: ("test")`),69 })70 checkError(t, gotMap,71 td.Map(MyMap{}, td.MapEntries{"foo": 1, "bar": 2}),72 expectedError{73 Message: mustBe("type mismatch"),74 Path: mustBe("DATA"),75 Got: mustBe("map[string]int"),76 Expected: mustBe("td_test.MyMap"),77 })78 //79 // Map type80 gotTypedMap := MyMap{"foo": 1, "bar": 2}81 checkOK(t, gotTypedMap, td.Map(MyMap{"foo": 1, "bar": 2}, nil))82 checkOK(t, gotTypedMap,83 td.Map(MyMap{"foo": 1}, td.MapEntries{"bar": 2}))84 checkOK(t, gotTypedMap,85 td.Map(MyMap{}, td.MapEntries{"foo": 1, "bar": 2}))86 checkOK(t, gotTypedMap,87 td.Map((MyMap)(nil), td.MapEntries{"foo": 1, "bar": 2}))88 checkOK(t, &gotTypedMap, td.Map(&MyMap{"foo": 1, "bar": 2}, nil))89 checkOK(t, &gotTypedMap,90 td.Map(&MyMap{"foo": 1}, td.MapEntries{"bar": 2}))91 checkOK(t, &gotTypedMap,92 td.Map(&MyMap{}, td.MapEntries{"foo": 1, "bar": 2}))93 checkOK(t, &gotTypedMap,94 td.Map((*MyMap)(nil), td.MapEntries{"foo": 1, "bar": 2}))95 checkError(t, gotTypedMap, td.Map(MyMap{"foo": 1, "bar": 3}, nil),96 expectedError{97 Message: mustBe("values differ"),98 Path: mustBe(`DATA["bar"]`),99 Got: mustBe("2"),100 Expected: mustBe("3"),101 })102 checkError(t, gotTypedMap, td.Map(MyMap{}, nil),103 expectedError{104 Message: mustBe("comparing hash keys of %%"),105 Path: mustBe("DATA"),106 Summary: mustMatch(`^Extra 2 keys: \("bar",\s+"foo"\)\z`),107 })108 checkError(t, gotTypedMap, td.Map(MyMap{"test": 2}, nil),109 expectedError{110 Message: mustBe("comparing hash keys of %%"),111 Path: mustBe("DATA"),112 Summary: mustMatch(113 `^ Missing key: \("test"\)\nExtra 2 keys: \("bar",\s+"foo"\)\z`),114 })115 checkError(t, gotTypedMap, td.Map(MyMap{}, td.MapEntries{"test": 2}),116 expectedError{117 Message: mustBe("comparing hash keys of %%"),118 Path: mustBe("DATA"),119 Summary: mustMatch(120 `^ Missing key: \("test"\)\nExtra 2 keys: \("bar",\s+"foo"\)\z`),121 })122 checkError(t, gotTypedMap,123 td.Map(MyMap{}, td.MapEntries{"foo": 1, "bar": 2, "test": 2}),124 expectedError{125 Message: mustBe("comparing hash keys of %%"),126 Path: mustBe("DATA"),127 Summary: mustBe(`Missing key: ("test")`),128 })129 checkError(t, &gotTypedMap, td.Map(&MyMap{"foo": 1, "bar": 3}, nil),130 expectedError{131 Message: mustBe("values differ"),132 Path: mustBe(`DATA["bar"]`),133 Got: mustBe("2"),134 Expected: mustBe("3"),135 })136 checkError(t, &gotTypedMap, td.Map(&MyMap{}, nil),137 expectedError{138 Message: mustBe("comparing hash keys of %%"),139 Path: mustBe("DATA"),140 Summary: mustMatch(`^Extra 2 keys: \("bar",\s+"foo"\)\z`),141 })142 checkError(t, &gotTypedMap, td.Map(&MyMap{"test": 2}, nil),143 expectedError{144 Message: mustBe("comparing hash keys of %%"),145 Path: mustBe("DATA"),146 Summary: mustMatch(147 `^ Missing key: \("test"\)\nExtra 2 keys: \("bar",\s+"foo"\)\z`),148 })149 checkError(t, &gotTypedMap, td.Map(&MyMap{}, td.MapEntries{"test": 2}),150 expectedError{151 Message: mustBe("comparing hash keys of %%"),152 Path: mustBe("DATA"),153 Summary: mustMatch(154 `^ Missing key: \("test"\)\nExtra 2 keys: \("bar",\s+"foo"\)\z`),155 })156 checkError(t, &gotTypedMap,157 td.Map(&MyMap{}, td.MapEntries{"foo": 1, "bar": 2, "test": 2}),158 expectedError{159 Message: mustBe("comparing hash keys of %%"),160 Path: mustBe("DATA"),161 Summary: mustBe(`Missing key: ("test")`),162 })163 checkError(t, &gotMap, td.Map(&MyMap{}, nil),164 expectedError{165 Message: mustBe("type mismatch"),166 Path: mustBe("DATA"),167 Got: mustBe("*map[string]int"),168 Expected: mustBe("*td_test.MyMap"),169 })170 checkError(t, gotMap, td.Map(&MyMap{}, nil),171 expectedError{172 Message: mustBe("type mismatch"),173 Path: mustBe("DATA"),174 Got: mustBe("map[string]int"),175 Expected: mustBe("*td_test.MyMap"),176 })177 checkError(t, nil, td.Map(&MyMap{}, nil),178 expectedError{179 Message: mustBe("values differ"),180 Path: mustBe("DATA"),181 Got: mustBe("nil"),182 Expected: mustBe("*td_test.MyMap{}"),183 })184 checkError(t, nil, td.Map(MyMap{}, nil),185 expectedError{186 Message: mustBe("values differ"),187 Path: mustBe("DATA"),188 Got: mustBe("nil"),189 Expected: mustBe("td_test.MyMap{}"),190 })191 //192 // nil cases193 var (194 gotNilMap map[string]int195 gotNilTypedMap MyMap196 )197 checkOK(t, gotNilMap, td.Map(map[string]int{}, nil))198 checkOK(t, gotNilTypedMap, td.Map(MyMap{}, nil))199 checkOK(t, &gotNilTypedMap, td.Map(&MyMap{}, nil))200 // Be lax...201 // Without Lax → error202 checkError(t, MyMap{}, td.Map(map[string]int{}, nil),203 expectedError{204 Message: mustBe("type mismatch"),205 })206 checkError(t, map[string]int{}, td.Map(MyMap{}, nil),207 expectedError{208 Message: mustBe("type mismatch"),209 })210 // With Lax → OK211 checkOK(t, MyMap{}, td.Lax(td.Map(map[string]int{}, nil)))212 checkOK(t, map[string]int{}, td.Lax(td.Map(MyMap{}, nil)))213 //214 // SuperMapOf215 checkOK(t, gotMap, td.SuperMapOf(map[string]int{"foo": 1}, nil))216 checkOK(t, gotMap,217 td.SuperMapOf(map[string]int{"foo": 1}, td.MapEntries{"bar": 2}))218 checkOK(t, gotMap,219 td.SuperMapOf(map[string]int{}, td.MapEntries{"foo": 1, "bar": 2}))220 checkError(t, gotMap,221 td.SuperMapOf(map[string]int{"foo": 1, "bar": 3}, nil),222 expectedError{223 Message: mustBe("values differ"),224 Path: mustBe(`DATA["bar"]`),225 Got: mustBe("2"),226 Expected: mustBe("3"),227 })228 checkError(t, gotMap, td.SuperMapOf(map[string]int{"test": 2}, nil),229 expectedError{230 Message: mustBe("comparing hash keys of %%"),231 Path: mustBe("DATA"),232 Summary: mustBe(`Missing key: ("test")`),233 })234 checkError(t, gotMap,235 td.SuperMapOf(map[string]int{}, td.MapEntries{"test": 2}),236 expectedError{237 Message: mustBe("comparing hash keys of %%"),238 Path: mustBe("DATA"),239 Summary: mustBe(`Missing key: ("test")`),240 })241 checkOK(t, gotNilMap, td.SuperMapOf(map[string]int{}, nil))242 checkOK(t, gotNilTypedMap, td.SuperMapOf(MyMap{}, nil))243 checkOK(t, &gotNilTypedMap, td.SuperMapOf(&MyMap{}, nil))244 //245 // SubMapOf246 checkOK(t, gotMap,247 td.SubMapOf(map[string]int{"foo": 1, "bar": 2, "tst": 3}, nil))248 checkOK(t, gotMap,249 td.SubMapOf(map[string]int{"foo": 1, "tst": 3}, td.MapEntries{"bar": 2}))250 checkOK(t, gotMap,251 td.SubMapOf(map[string]int{}, td.MapEntries{"foo": 1, "bar": 2, "tst": 3}))252 checkError(t, gotMap,253 td.SubMapOf(map[string]int{"foo": 1, "bar": 3}, nil),254 expectedError{255 Message: mustBe("values differ"),256 Path: mustBe(`DATA["bar"]`),257 Got: mustBe("2"),258 Expected: mustBe("3"),259 })260 checkError(t, gotMap, td.SubMapOf(map[string]int{"foo": 1}, nil),261 expectedError{262 Message: mustBe("comparing hash keys of %%"),263 Path: mustBe("DATA"),264 Summary: mustBe(`Extra key: ("bar")`),265 })266 checkError(t, gotMap,267 td.SubMapOf(map[string]int{}, td.MapEntries{"foo": 1, "test": 2}),268 expectedError{269 Message: mustBe("comparing hash keys of %%"),270 Path: mustBe("DATA"),271 Summary: mustBe(`Missing key: ("test")272 Extra key: ("bar")`),273 })274 checkOK(t, gotNilMap, td.SubMapOf(map[string]int{"foo": 1}, nil))275 checkOK(t, gotNilTypedMap, td.SubMapOf(MyMap{"foo": 1}, nil))276 checkOK(t, &gotNilTypedMap, td.SubMapOf(&MyMap{"foo": 1}, nil))277 //278 // Bad usage279 checkError(t, "never tested",280 td.Map("test", nil),281 expectedError{282 Message: mustBe("bad usage of Map operator"),283 Path: mustBe("DATA"),284 Summary: mustContain("usage: Map("),285 })286 checkError(t, "never tested",287 td.SuperMapOf("test", nil),288 expectedError{289 Message: mustBe("bad usage of SuperMapOf operator"),290 Path: mustBe("DATA"),291 Summary: mustContain("usage: SuperMapOf("),292 })293 checkError(t, "never tested",294 td.SubMapOf("test", nil),295 expectedError{296 Message: mustBe("bad usage of SubMapOf operator"),297 Path: mustBe("DATA"),298 Summary: mustContain("usage: SubMapOf("),299 })300 num := 12301 checkError(t, "never tested",302 td.Map(&num, nil),303 expectedError{304 Message: mustBe("bad usage of Map operator"),305 Path: mustBe("DATA"),306 Summary: mustContain("usage: Map("),307 })308 checkError(t, "never tested",309 td.SuperMapOf(&num, nil),310 expectedError{311 Message: mustBe("bad usage of SuperMapOf operator"),312 Path: mustBe("DATA"),313 Summary: mustContain("usage: SuperMapOf("),314 })315 checkError(t, "never tested",316 td.SubMapOf(&num, nil),317 expectedError{318 Message: mustBe("bad usage of SubMapOf operator"),319 Path: mustBe("DATA"),320 Summary: mustContain("usage: SubMapOf("),321 })322 checkError(t, "never tested",323 td.Map(&MyMap{}, td.MapEntries{1: 2}),324 expectedError{325 Message: mustBe("bad usage of Map operator"),326 Path: mustBe("DATA"),327 Summary: mustBe("expected key 1 type mismatch: int != model key type (string)"),328 })329 checkError(t, "never tested",330 td.SuperMapOf(&MyMap{}, td.MapEntries{1: 2}),331 expectedError{332 Message: mustBe("bad usage of SuperMapOf operator"),333 Path: mustBe("DATA"),334 Summary: mustBe("expected key 1 type mismatch: int != model key type (string)"),335 })336 checkError(t, "never tested",337 td.SubMapOf(&MyMap{}, td.MapEntries{1: 2}),338 expectedError{339 Message: mustBe("bad usage of SubMapOf operator"),340 Path: mustBe("DATA"),341 Summary: mustBe("expected key 1 type mismatch: int != model key type (string)"),342 })343 checkError(t, "never tested",344 td.Map(&MyMap{}, td.MapEntries{"foo": nil}),345 expectedError{346 Message: mustBe("bad usage of Map operator"),347 Path: mustBe("DATA"),348 Summary: mustBe(`expected key "foo" value cannot be nil as entries value type is int`),349 })350 checkError(t, "never tested",351 td.Map(&MyMap{}, td.MapEntries{"foo": uint16(2)}),352 expectedError{353 Message: mustBe("bad usage of Map operator"),354 Path: mustBe("DATA"),355 Summary: mustBe(`expected key "foo" value type mismatch: uint16 != model key type (int)`),356 })357 checkError(t, "never tested",358 td.Map(&MyMap{"foo": 1}, td.MapEntries{"foo": 1}),359 expectedError{360 Message: mustBe("bad usage of Map operator"),361 Path: mustBe("DATA"),362 Summary: mustBe(`"foo" entry exists in both model & expectedEntries`),363 })364 //365 // String366 test.EqualStr(t, td.Map(MyMap{}, nil).String(),367 "td_test.MyMap{}")368 test.EqualStr(t, td.Map(&MyMap{}, nil).String(),369 "*td_test.MyMap{}")370 test.EqualStr(t, td.Map(&MyMap{"foo": 2}, nil).String(),371 `*td_test.MyMap{372 "foo": 2,373}`)374 test.EqualStr(t, td.SubMapOf(MyMap{}, nil).String(),375 "SubMapOf(td_test.MyMap{})")376 test.EqualStr(t, td.SubMapOf(&MyMap{}, nil).String(),377 "SubMapOf(*td_test.MyMap{})")378 test.EqualStr(t, td.SubMapOf(&MyMap{"foo": 2}, nil).String(),379 `SubMapOf(*td_test.MyMap{380 "foo": 2,381})`)382 test.EqualStr(t, td.SuperMapOf(MyMap{}, nil).String(),383 "SuperMapOf(td_test.MyMap{})")384 test.EqualStr(t, td.SuperMapOf(&MyMap{}, nil).String(),385 "SuperMapOf(*td_test.MyMap{})")386 test.EqualStr(t, td.SuperMapOf(&MyMap{"foo": 2}, nil).String(),387 `SuperMapOf(*td_test.MyMap{388 "foo": 2,389})`)390 // Erroneous op391 test.EqualStr(t, td.Map(12, nil).String(), "Map(<ERROR>)")392 test.EqualStr(t, td.SubMapOf(12, nil).String(), "SubMapOf(<ERROR>)")393 test.EqualStr(t, td.SuperMapOf(12, nil).String(), "SuperMapOf(<ERROR>)")394}395func TestMapTypeBehind(t *testing.T) {396 type MyMap map[string]int397 // Map398 equalTypes(t, td.Map(map[string]int{}, nil), map[string]int{})399 equalTypes(t, td.Map(MyMap{}, nil), MyMap{})400 equalTypes(t, td.Map(&MyMap{}, nil), &MyMap{})401 // SubMap402 equalTypes(t, td.SubMapOf(map[string]int{}, nil), map[string]int{})403 equalTypes(t, td.SubMapOf(MyMap{}, nil), MyMap{})404 equalTypes(t, td.SubMapOf(&MyMap{}, nil), &MyMap{})405 // SuperMap406 equalTypes(t, td.SuperMapOf(map[string]int{}, nil), map[string]int{})407 equalTypes(t, td.SuperMapOf(MyMap{}, nil), MyMap{})408 equalTypes(t, td.SuperMapOf(&MyMap{}, nil), &MyMap{})409 // Erroneous op...

Full Screen

Full Screen

TestMap

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 t.TestMap()4}5import (6func main() {7 t.TestMap()8}9import (10func main() {11 t.TestMap()12}13import (14func main() {15 t.TestMap()16}17import (18func main() {19 t.TestMap()20}21import (22func main() {23 t.TestMap()24}25import (26func main() {27 t.TestMap()28}29import (30func main() {31 t.TestMap()32}33import (34func main() {35 t.TestMap()36}37import (38func main() {39 t.TestMap()40}41import (42func main() {43 t.TestMap()44}

Full Screen

Full Screen

TestMap

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 t.TestMap()4}5import (6func main() {7 t.TestMap()8}9import (10func main() {11 t.TestMap()12}13import (14type TD_Test struct {15}16func (t *TD_Test) TestMap() {17 fmt.Println("TestMap")18}19import (20type TD_Test struct {21}22func (t *TD_Test) TestMap() {23 fmt.Println("TestMap")24}25import (26type TD_Test struct {27}28func (t *TD_Test) TestMap() {29 fmt.Println("TestMap")30}31import (32type TD_Test struct {33}34func (t *TD_Test) TestMap() {35 fmt.Println("TestMap")36}37import (38type TD_Test struct {39}40func (t *TD_Test) TestMap() {41 fmt.Println("TestMap")42}43import (44type TD_Test struct {45}46func (t *TD_Test) TestMap() {47 fmt.Println("TestMap")48}49import (50type TD_Test struct {51}52func (t *TD_Test) TestMap() {53 fmt.Println("TestMap")54}55import (56type TD_Test struct {57}58func (t *TD_Test) TestMap() {59 fmt.Println("TestMap")60}

Full Screen

Full Screen

TestMap

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println("Hello World!")4 td_test.TestMap()5}6import (7func main() {8 fmt.Println("Hello World!")9 td_test.TestSlice()10}11import (12func main() {13 fmt.Println("Hello World!")14 td_test.TestStruct()15}16{one two three}17import (18func main() {19 fmt.Println("Hello World!")20 td_test.TestPointer()21}22import (23func main() {24 fmt.Println("Hello World!")25 td_test.TestArray()26}27import (28func main() {29 fmt.Println("Hello World!")30 td_test.TestInterface()31}32{one two three}33import (34func main() {35 fmt.Println("Hello World!")36 td_test.TestChannel()37}

Full Screen

Full Screen

TestMap

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println("Hello, playground")4 td_test.TestMap()5}6import (7func main() {8 fmt.Println("Hello, playground")9 td_test.TestMap()10}11import (12func main() {13 fmt.Println("Hello, playground")14 td_test.TestMap()15}16import (17func main() {18 fmt.Println("Hello, playground")19 td_test.TestMap()20}21import (22func main() {23 fmt.Println("Hello, playground")24 td_test.TestMap()25}26import (27func main() {28 fmt.Println("Hello, playground")29 td_test.TestMap()30}31import (32func main() {33 fmt.Println("Hello, playground")34 td_test.TestMap()35}36import (37func main() {38 fmt.Println("Hello, playground")39 td_test.TestMap()40}41import (42func main() {43 fmt.Println("Hello, playground")44 td_test.TestMap()45}

Full Screen

Full Screen

TestMap

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 m := td_test.TestMap{}4 m1 := m.TestMap()5 fmt.Println(m1)6}

Full Screen

Full Screen

TestMap

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 t.TestMap()4}5import "fmt"6func main() {7 m := map[string]string{8 }9 fmt.Println(m)10 fmt.Println(n)11}12import (13func main() {14 m := make(map[string]string)15 wg.Add(2)16 go func() {17 defer wg.Done()18 for i := 0; i < 100; i++ {19 m[fmt.Sprintf("%d", i)] = fmt.Sprintf("value %d", i)20 }21 }()22 go func() {23 defer wg.Done()24 for i := 0; i < 100; i++ {25 m[fmt.Sprintf("%d", i)] = fmt.Sprintf("value %d", i)26 }27 }()28 wg.Wait()29 fmt.Println(m)30}31runtime.throw(0x4d0c0d, 0x15)32runtime.mapassign_faststr(0x4a7d20, 0xc0000120

Full Screen

Full Screen

TestMap

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 td := td_test.NewTestMap()4 fmt.Println(td.TestMap())5}6import (7func main() {8 td := td_test.NewTestMap()9 fmt.Println(td.TestMap())10}11import (12func main() {13 td := td_test.NewTestMap()14 fmt.Println(td.TestMap())15}16import (17func main() {18 td := td_test.NewTestMap()19 fmt.Println(td.TestMap())20}21import (22func main() {23 td := td_test.NewTestMap()24 fmt.Println(td.TestMap())25}26import (27func main() {28 td := td_test.NewTestMap()29 fmt.Println(td.TestMap())30}31import (32func main() {33 td := td_test.NewTestMap()34 fmt.Println(td.TestMap())35}36import (37func main() {38 td := td_test.NewTestMap()39 fmt.Println(td.TestMap())40}

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Go-testdeep automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Most used method in

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful