Commit b7d28703 authored by 16이상민's avatar 16이상민

Write tests for class "NoteManager"

parent 5ec5e505
This diff is collapsed.
fileFormatVersion: 2
guid: ed97868d86289994081e09ef995f7591
timeCreated: 1518729339
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
This diff is collapsed.
fileFormatVersion: 2
guid: 27c0dfb4f46da394bbdf8d34b0a9ed87
timeCreated: 1518729563
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
This diff is collapsed.
fileFormatVersion: 2
guid: 8fcf519fe09af4c4b8185353f0def4ef
timeCreated: 1518815265
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
......@@ -7,13 +8,13 @@ namespace JudgeModule
public class NoteJudger
{
private Transform deactives;
private Action<int> EndGame;
private Action EndGame;
private GameObject judgeText;
public NoteJudger(Action<int> endgame)
public NoteJudger(Dictionary<string, GameObject> obj, Action endgame)
{
deactives = GameObject.Find("Deactives"). transform;
judgeText = GameObject.Find("Judge");
deactives = obj["deactives"].transform;
judgeText = obj["judgetext"];
EndGame = endgame;
}
......@@ -23,7 +24,7 @@ namespace JudgeModule
DeactivateNote(note);
if (!(note is MotionNote))
EndGame(0);
EndGame();
}
public void EnteredNoteProc(Note note, float timing)
......
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace JudgeModule
{
public class NoteManager
{
private float baseTime;
private bool IsInitTime;
private GameObject offset;
private GameObject noteobj;
private GameObject deactives;
private GameObject appear;
private GameObject disappear;
private Vector3 initialPos;
private float BPM;
private Func<Note> GetLastNote;
private float MsPerBeat
{
get
{
return 60 * 1000f / BPM;
}
}
private float ScrollSpeed
{
get
{
return MsPerBeat / 1000f;
}
}
public NoteManager(Dictionary<string, GameObject> gameObjects, float bpm, Func<Note> getlastnote)
{
offset = gameObjects["offset"];
noteobj = gameObjects["noteobj"];
deactives = gameObjects["deactives"];
appear = gameObjects["appear"];
disappear = gameObjects["disappear"];
initialPos = offset.transform.position;
BPM = bpm;
GetLastNote = getlastnote;
}
public void Controll(float current)
{
if (!IsInitTime)
{
baseTime = current;
IsInitTime = true;
}
float timing = current - baseTime;
offset.transform.position = Vector3.left * timing * ScrollSpeed;
RelocateControllers(timing);
}
private void RelocateControllers(float timing)
{
DeactiveUndecided();
SwitchStandBy();
AssignNotes(timing);
}
private void DeactiveUndecided()
{
noteobj.transform
.Cast<Transform>()
.Select(x => x.GetComponent<Controller>())
.Where(c => initialPos.x - c.transform.position.x
- (c.Instance.EndTiming - c.Instance.StartTiming)
> Judge.BAD.ButtonTimingRange)
.ToList()
.ForEach(x => x.transform.SetParent(deactives.transform));
}
private void SwitchStandBy()
{
deactives.transform
.Cast<Transform>()
.Select(x => x.GetComponent<Controller>())
.Where(c => c.transform.position.x <= disappear.transform.position.x)
.ToList()
.ForEach(x =>
{
x.transform.position = appear.transform.position;
x.transform.SetParent(appear.transform);
x.Instance = null;
x.gameObject.SetActive(false);
});
}
private void AssignNotes(float timing)
{
appear.transform
.Cast<Transform>()
.Select(x => x.GetComponent<Controller>())
.ToList()
.ForEach(c =>
{
var note = GetLastNote();
if (note != null)
{
c.Instance = note;
c.Instance.Component = c;
c.transform.position = initialPos + Vector3.right * ((c.Instance.StartTiming - timing) * ScrollSpeed);
c.transform.SetParent(noteobj.transform);
c.gameObject.SetActive(true);
}
});
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: e83b419b496632c47a9d6c3d4c7e757b
timeCreated: 1518722605
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
......@@ -50,7 +50,7 @@ public class InGameManager : MonoBehaviour {
judgeText = GameObject.Find("Judge");
input = GameObject.Find("InGameManagers").GetComponent<InputManager>();
condition = new NoteCondition(input);
judger = new NoteJudger(x => ShowResult());
judger = new NoteJudger(new Dictionary<string, GameObject> { }, () => ShowResult());
motionGageManager = new MotionGageManager
{ motionGuage = GameObject.Find("Motion Guage") };
}
......
......@@ -15,6 +15,9 @@ public class JudgeManager : MonoBehaviour
private GameObject offset;
private GameObject noteobj;
private GameObject deactives;
private GameObject appear;
private GameObject disappear;
private MotionGageManager motionGageManager;
private GameObject judgeText;
......@@ -47,10 +50,13 @@ public class JudgeManager : MonoBehaviour
{
offset = GameObject.Find("Offset");
noteobj = GameObject.Find("Noteobj");
deactives = GameObject.Find("Deactives");
appear = GameObject.Find("NoteAppear");
disappear = GameObject.Find("NoteDisappear");
judgeText = GameObject.Find("Judge");
input = GameObject.Find("InGameManagers").GetComponent<InputManager>();
condition = new NoteCondition(input);
judger = new NoteJudger(x => ShowResult());
judger = new NoteJudger(new Dictionary<string, GameObject> { }, ShowResult);
motionGageManager = new MotionGageManager
{ motionGuage = GameObject.Find("Motion Guage") };
}
......@@ -100,7 +106,7 @@ public class JudgeManager : MonoBehaviour
float timing = current - baseTime;
offset.transform.position = Vector3.left * current * ScrollSpeed;
offset.transform.position = Vector3.left * timing * ScrollSpeed;
motionGageManager.UpdateGuage();
......@@ -108,9 +114,62 @@ public class JudgeManager : MonoBehaviour
IsGameEnd)
Invoke("ShowResult", 2f);
RelocateControllers(timing);
JudgeNote(timing);
}
void RelocateControllers(float timing)
{
DeactiveUndecided();
SwitchStandBy();
AssignNotes(timing);
}
void DeactiveUndecided()
{
noteobj.transform
.Cast<Transform>()
.Where(c => initialPos.x - c.position.x > Judge.BAD.ButtonTimingRange)
.ToList()
.ForEach(x => x.SetParent(deactives.transform));
}
void SwitchStandBy()
{
deactives.transform
.Cast<Transform>()
.Select(x => x.GetComponent<Controller>())
.Where(c => c.transform.position.x < disappear.transform.position.x)
.ToList()
.ForEach(x =>
{
x.transform.position = appear.transform.position;
x.transform.SetParent(appear.transform);
x.Instance = null;
x.gameObject.SetActive(false);
});
}
void AssignNotes(float timing)
{
appear.transform
.Cast<Transform>()
.Select(x => x.GetComponent<Controller>())
.ToList()
.ForEach(c =>
{
c.Instance = GetLastNote(timing);
if (c.Instance != null)
{
c.Instance.Component = c;
c.transform.position = initialPos + Vector3.right * ((c.Instance.StartTiming - timing) * ScrollSpeed);
c.transform.SetParent(noteobj.transform);
c.gameObject.SetActive(true);
}
});
}
void JudgeNote(float timing)
{
Note note = GetLastNote(timing);
......
using UnityEngine.TestTools;
using System.Collections;
using TrackAnalysis;
using UnityEngine;
using JudgeModule;
using NUnit.Framework;
using UnityEngine.UI;
using System.Collections.Generic;
using TestSupport;
public class NoteJudgerTests
{
[UnityTest]
public IEnumerator DeactivedNote_Should_Change_Parent_Deactives()
{
var note = CreateNoteAndController("SBT", 0);
var settings = new TestSettings("SBT", 0);
var judger = new NoteJudger(x => { });
var note = settings.note;
var judger = new NoteJudger(new Dictionary<string, GameObject>
{
{ "deactives", settings.deactives },
{ "judgetext", settings.judge }
},
() => { });
yield return null;
......@@ -28,11 +36,16 @@ public class NoteJudgerTests
[UnityTest]
public IEnumerator SetJudge_Should_Change_Judge_Text()
{
var text = CreateJudgeText();
var settings = new TestSettings("SBT", 0);
CreateNoteAndController("SBT", 0);
var text = settings.judgeText;
var judger = new NoteJudger(x => { });
var judger = new NoteJudger(new Dictionary<string, GameObject>
{
{ "deactives", settings.deactives },
{ "judgetext", settings.judge }
},
() => { });
int cnt = 0;
foreach (var x in Judge.JudgeList)
......@@ -55,12 +68,18 @@ public class NoteJudgerTests
[UnityTest]
public IEnumerator WrongNoteProc_Should_Execute_EndGame_When_Button_Note()
{
var note = CreateNoteAndController("SBT", 0);
var settings = new TestSettings("SBT", 0);
CreateJudgeText();
var note = settings.note;
bool isEnd = false;
var judger = new NoteJudger(x => isEnd = true);
var judger = new NoteJudger(new Dictionary<string, GameObject>
{
{ "deactives", settings.deactives },
{ "judgetext", settings.judge }
},
() => { isEnd = true; });
yield return null;
......@@ -75,12 +94,18 @@ public class NoteJudgerTests
[UnityTest]
public IEnumerator WrongNoteProc_Should_Not_Execute_EndGame_When_Motion_Note()
{
var note = CreateNoteAndController("SMO", 0);
var settings = new TestSettings("SMO", 0);
CreateJudgeText();
var note = settings.note;
bool isEnd = false;
var judger = new NoteJudger(x => isEnd = true);
var judger = new NoteJudger(new Dictionary<string, GameObject>
{
{ "deactives", settings.deactives },
{ "judgetext", settings.judge }
},
() => { isEnd = true; });
yield return null;
......@@ -95,11 +120,16 @@ public class NoteJudgerTests
[UnityTest]
public IEnumerator EnteredNoteProc_Should_Change_Activated_True_When_Long_Note()
{
var note = CreateNoteAndController("LBT", 0, Judge.MISS.ButtonTimingRange + 10);
var settings = new TestSettings("LBT", 0, Judge.MISS.ButtonTimingRange + 10);
CreateJudgeText();
var judger = new NoteJudger(x => { });
var note = settings.note;
var judger = new NoteJudger(new Dictionary<string, GameObject>
{
{ "deactives", settings.deactives },
{ "judgetext", settings.judge }
},
() => { });
yield return null;
......@@ -114,11 +144,16 @@ public class NoteJudgerTests
[UnityTest]
public IEnumerator EnteredNoteProc_Should_Not_Change_Activated_True_When_Short_Note()
{
var note = CreateNoteAndController("SBT", 0);
var settings = new TestSettings("SBT", 0);
CreateJudgeText();
var note = settings.note;
var judger = new NoteJudger(x => { });
var judger = new NoteJudger(new Dictionary<string, GameObject>
{
{ "deactives", settings.deactives },
{ "judgetext", settings.judge }
},
() => { });
yield return null;
......@@ -133,11 +168,16 @@ public class NoteJudgerTests
[UnityTest]
public IEnumerator ContinuingNoteProc_Should_Deactive_When_Not_End_And_Break()
{
var note = CreateNoteAndController("LBT", 0, Judge.BAD.ButtonTimingRange + 1);
var settings = new TestSettings("LBT", 0, Judge.BAD.ButtonTimingRange + 1);
CreateJudgeText();
var note = settings.note;
var judger = new NoteJudger(x => { });
var judger = new NoteJudger(new Dictionary<string, GameObject>
{
{ "deactives", settings.deactives },
{ "judgetext", settings.judge }
},
() => { });
yield return null;
......@@ -152,11 +192,16 @@ public class NoteJudgerTests
[UnityTest]
public IEnumerator ContinuingNoteProc_Should_Not_Deactive_When_End()
{
var note = CreateNoteAndController("LBT", 0, 1);
var settings = new TestSettings("LBT", 0, 1);
CreateJudgeText();
var note = settings.note;
var judger = new NoteJudger(x => { });
var judger = new NoteJudger(new Dictionary<string, GameObject>
{
{ "deactives", settings.deactives },
{ "judgetext", settings.judge }
},
() => { });
yield return null;
......@@ -171,11 +216,16 @@ public class NoteJudgerTests
[UnityTest]
public IEnumerator ContinuingNoteProc_Should_Not_Deactive_When_Not_Break()
{
var note = CreateNoteAndController("LBT", 0, Judge.BAD.ButtonTimingRange + 1);
var settings = new TestSettings("LBT", 0, Judge.BAD.ButtonTimingRange + 1);
CreateJudgeText();
var note = settings.note;
var judger = new NoteJudger(x => { });
var judger = new NoteJudger(new Dictionary<string, GameObject>
{
{ "deactives", settings.deactives },
{ "judgetext", settings.judge }
},
() => { });
yield return null;
......@@ -187,47 +237,42 @@ public class NoteJudgerTests
Assert.AreEqual(expected, actual, "ContinuingNoteProc should not deactive when not break");
}
private Note CreateNoteAndController(string type, float start, float end = 0)
class TestSettings
{
var noteobj = new GameObject("NoteObj");
var deactives = new GameObject("Deactives");
public Note note;
public GameObject noteobj,
deactives,
judge;
public Text judgeText;
var notemaker = new NoteMaker();
private TestNoteMaker maker = new TestNoteMaker();
Note note;
switch (type)
public TestSettings(string type, float start, float end = 0)
{
case "LBT":
notemaker.Make("AA", "LBT", start);
note = notemaker.Make("AA", "LBT", end);
break;
case "SMO":
note = notemaker.Make("CP", "SMO", start);
break;
case "LMO":
notemaker.Make("JS", "LMO", start);
note = notemaker.Make("JS", "LMO", end);
break;
default:
note = notemaker.Make("AA", "SBT", start);
break;
CreateNoteAndController(type, start, end);
CreateJudgeText();
}
var obj = new GameObject();
obj.transform.SetParent(noteobj.transform);
var controller = obj.AddComponent<Controller>();
private void CreateNoteAndController(string type, float start, float end)
{
noteobj = new GameObject("NoteObj");
deactives = new GameObject("Deactives");
controller.Instance = note;
note.Component = controller;
note = maker.MakeNote(type, start, end);
return note;
}
var obj = new GameObject();
obj.transform.SetParent(noteobj.transform);
private Text CreateJudgeText()
{
var judgeText = new GameObject("Judge", typeof(RectTransform));
var controller = obj.AddComponent<Controller>();
controller.Instance = note;
note.Component = controller;
}
return judgeText.AddComponent<Text>();
private void CreateJudgeText()
{
judge = new GameObject("Judge", typeof(RectTransform));
judgeText = judge.AddComponent<Text>();
}
}
}
\ No newline at end of file
using UnityEngine.TestTools;
using System.Collections;
using UnityEngine;
using JudgeModule;
using NUnit.Framework;
using System.Collections.Generic;
using System.Linq;
using TestSupport;
public class NoteManagerTests
{
[UnityTest]
public IEnumerator Offset_Should_Move_In_Some_Frames()
{
var objects = MakeObjects();
var manager = new NoteManager(objects, 60, () => null);
bool result = true;
foreach (var time in Enumerable.Range(0, 10 + 1))
{
yield return null;
manager.Controll(time);
if (IsSeriousError(objects["offset"].transform.position.x, Vector3.left.x * time, 0.001f))
result = false;
}
var expected = true;
var actual = result;
Assert.AreEqual(expected, actual, "Offset should move in some frames");
}
[UnityTest]
public IEnumerator Controllers_Should_Not_Change_Parent_When_Note_Not_Exist()
{
var objects = MakeObjects();
var manager = new NoteManager(objects, 60, () => null);
int count = objects["appear"].transform.childCount;
yield return null;
manager.Controll(0);
var expected = true;
var actual = (count == objects["appear"].transform.childCount);
Assert.AreEqual(expected, actual, "Controllers should not change parent when notes does not exist");
}
[UnityTest]
public IEnumerator Short_Note_Should_Move_Correctly()
{
var work = new TestWork(MakeObjects());
yield return work.Work(
new string[]
{
"SBT"
},
new float[,]
{
{ 1000, 0 }
},
new List<TestTask>
{
new TestTask{ timing = 0, name = "appear", isSame = true, isMemorize = true },
new TestTask{ timing = 500, name = "noteobj", isSame = false, isMemorize = true },
new TestTask{ timing = 1000, name = "noteobj", isSame = false },
new TestTask{ timing = 1500, name = "noteobj", isSame = true },
new TestTask{ timing = 2000, name = "deactives", isSame = true, isMemorize = true },
});
var expected = true;
var actual = work.isCorrect;
Assert.AreEqual(expected, actual, "Short note should move correctly");
}
[UnityTest]
public IEnumerator Long_Note_Should_Move_Correctly()
{
var work = new TestWork(MakeObjects());
yield return work.Work(
new string[]
{
"LBT"
},
new float[,]
{
{ 1000, 1500 }
},
new List<TestTask>
{
new TestTask{ timing = 0, name = "appear", isSame = true, isMemorize = true },
new TestTask{ timing = 500, name = "noteobj", isSame = false, isMemorize = true },
new TestTask{ timing = 1000, name = "noteobj", isSame = false },
new TestTask{ timing = 1500, name = "noteobj", isSame = false },
new TestTask{ timing = 1800, name = "noteobj", isSame = true },
new TestTask{ timing = 2000, name = "deactives", isSame = true, isMemorize = true },
});
var expected = true;
var actual = work.isCorrect;
Assert.AreEqual(expected, actual, "Long note should move correctly");
}
private bool IsSeriousError(float a, float b, float errorLimit)
{
return Mathf.Abs(a - b) >= errorLimit;
}
public Dictionary<string, GameObject> MakeObjects()
{
var offset = new GameObject();
var noteobj = new GameObject();
var deactives = new GameObject();
var appear = new GameObject();
var disappear = new GameObject();
offset .transform.position = Vector3.zero;
noteobj .transform.position = Vector3.zero;
deactives.transform.position = Vector3.zero;
appear .transform.position = Vector3.right * 1000;
disappear.transform.position = Vector3.left * 1000;
noteobj .transform.SetParent(offset.transform);
deactives.transform.SetParent(offset.transform);
Enumerable.Range(0, 20).ToList().ForEach(x =>
{
var obj = new GameObject();
obj.transform.SetParent(appear.transform);
var controller = obj.AddComponent<Controller>();
controller.Instance = new Note(0, 0);
});
return new Dictionary<string, GameObject>
{
{ "offset", offset },
{ "noteobj", noteobj },
{ "deactives", deactives },
{ "appear", appear },
{ "disappear", disappear }
};
}
private class NoteGenerator
{
private TestNoteMaker maker = new TestNoteMaker();
private string[] orderType;
private float[,] orderTime;
private int location = 0;
public NoteGenerator(string[] type, float[,] time)
{
orderType = type;
orderTime = time;
}
public Note GetNext()
{
if (location >= orderType.Length)
return null;
Note note = maker.MakeNote(orderType[location],
orderTime[location, 0],
orderTime[location, 1]);
++location;
return note;
}
}
private class CountMemory
{
private Dictionary<string, GameObject> objects;
private Dictionary<string, int> counts = new Dictionary<string, int>();
public CountMemory(Dictionary<string, GameObject> target)
{
objects = target;
foreach (var x in objects.Keys)
counts.Add(x, 0);
}
public void Memorize(string name)
{
counts[name] = objects[name].transform.childCount;
}
public bool IsSameAsMemorized(string name)
{
return counts[name] == objects[name].transform.childCount;
}
}
private class TestTask
{
public float timing;
public string name;
public bool isMemorize;
public bool isSame;
}
private class TestWork
{
public bool isCorrect = true;
private Dictionary<string, GameObject> objects;
public TestWork(Dictionary<string, GameObject> obj)
{
objects = obj;
}
public IEnumerator Work(string[] type, float[,] time, List<TestTask> tasklist)
{
var generator = new NoteGenerator(type, time);
var manager = new NoteManager(objects, 60, generator.GetNext);
var memory = new CountMemory(objects);
foreach (var task in tasklist)
{
if (task.isMemorize)
memory.Memorize(task.name);
yield return null;
manager.Controll(task.timing);
if (!(task.isSame ^ memory.IsSameAsMemorized(task.name)))
isCorrect = false;
}
}
}
}
fileFormatVersion: 2
guid: 8d81e7e180331504bb73eedb929ab3b5
timeCreated: 1518722605
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: af7e6bf17f0be644f814c6aa02e5494f
folderAsset: yes
timeCreated: 1518808085
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using TrackAnalysis;
namespace TestSupport
{
public class TestNoteMaker
{
private NoteMaker maker = new NoteMaker();
public Note MakeNote(string type, float start, float end = 0)
{
switch (type)
{
case "LBT":
maker.Make("AA", "LBT", start);
return maker.Make("AA", "LBT", end);
case "SMO":
return maker.Make("CP", "SMO", start);
case "LMO":
maker.Make("JS", "LMO", start);
return maker.Make("JS", "LMO", end);
default:
return maker.Make("AA", "SBT", start);
}
}
}
}
fileFormatVersion: 2
guid: 2b72dbbe52fba9948aa169c8db03a549
timeCreated: 1518808085
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment