A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using System.Collections.Concurrent;
5using System.Globalization;
6using System.Linq;
7using System.Threading;
8using NUnit.Framework;
9using osu.Framework.Allocation;
10using osu.Framework.Configuration;
11using osu.Framework.Platform;
12using osu.Framework.Testing;
13using osu.Framework.Tests.Visual;
14
15namespace osu.Framework.Tests.Localisation
16{
17 [HeadlessTest]
18 public class ThreadCultureTest : FrameworkTestScene
19 {
20 [Resolved]
21 private GameHost host { get; set; }
22
23 [Resolved]
24 private FrameworkConfigManager config { get; set; }
25
26 [Test]
27 public void TestDefaultCultureIsInvariant()
28 {
29 setCulture("");
30 assertCulture("");
31 }
32
33 [Test]
34 public void TestValidCultureIsSelected()
35 {
36 setCulture("ko-KR");
37 assertCulture("ko-KR");
38 }
39
40 [Test]
41 public void TestInvalidCultureFallsBackToInvariant()
42 {
43 setCulture("ko_KR");
44 assertCulture("");
45 }
46
47 [Test]
48 public void TestCreateThreadOnNewCulture()
49 {
50 setCulture("ko-KR");
51 assertThreadCulture("ko-KR");
52 }
53
54 private void setCulture(string name) => AddStep($"set culture = {name}", () =>
55 {
56 var locale = config.GetBindable<string>(FrameworkSetting.Locale);
57 // force ValueChanged to trigger by calling SetValue explicitly instead of setting .Value
58 // this is done since the existing value might have been the same and TestScene.SetUpTestForUnit() might have overridden the culture silently
59 locale.SetValue(locale.Value, name);
60 });
61
62 private void assertCulture(string name)
63 {
64 var cultures = new ConcurrentBag<CultureInfo>();
65
66 AddStep("query cultures", () =>
67 {
68 host.DrawThread.Scheduler.Add(() => cultures.Add(Thread.CurrentThread.CurrentCulture));
69 host.UpdateThread.Scheduler.Add(() => cultures.Add(Thread.CurrentThread.CurrentCulture));
70 host.AudioThread.Scheduler.Add(() => cultures.Add(Thread.CurrentThread.CurrentCulture));
71 });
72
73 AddUntilStep("wait for query", () => cultures.Count == 3);
74 AddAssert($"culture is {name}", () => cultures.All(c => c.Name == name));
75 }
76
77 private void assertThreadCulture(string name)
78 {
79 CultureInfo culture = null;
80
81 AddStep("start new thread", () => new Thread(() => culture = Thread.CurrentThread.CurrentCulture) { IsBackground = true }.Start());
82 AddUntilStep("wait for culture", () => culture != null);
83 AddAssert($"thread culture is {name}", () => culture.Name == name);
84 }
85 }
86}