public void ColorChange_Should_SpanColorRange(ActionParams actionData) { var sut = new LedWrapper (); var result = sut.GetActionOutput (actionData); // detemining that ColorChange spans color range uniformly is tricky because of dynamic precision in C++ code // Instead, verify that increments happen uniformly and that start, middle and end colors are correct result [0].Should ().Be (actionData.colorFrom); result [actionData.effectiveResultsCount / 2].MaxDifference (actionData.colorFrom.MoveCloserTo (actionData.colorTo, 0.5)).Should ().BeLessOrEqualTo (2, "Middle color can be different only by a small margin"); result [actionData.effectiveResultsCount - 1].Should ().Be (actionData.colorTo); List<int> diffs = new List<int> (); for (int i = 1; i < actionData.effectiveResultsCount; i++) { var delta = result [i].MaxDifference (result [i - 1]); diffs.Add (delta); } var notNullDiffs = diffs.Where (i => i != 0).ToList(); (notNullDiffs.Average() - notNullDiffs.Max()).Should ().BeLessThan (2, "Color increments should be uniform and can vary only due to rounding errors"); (notNullDiffs.Average() - notNullDiffs.Min()).Should ().BeLessThan (2); var minDifferentValuesCount = actionData.duration / (Math.Max (actionData.tickLength, 32)); // precision is never less than 32ms notNullDiffs.Count.Should ().BeGreaterOrEqualTo (Math.Min(actionData.colorTo.MaxDifference(actionData.colorFrom) / 2, minDifferentValuesCount - 2)); }
public void Strobe_Should_BeInOrder(ActionParams actionData) { var sut = new LedWrapper (); var result = sut.GetActionOutput (actionData); // ascending int i = 0; if (actionData.upPct != 0) result [0].Should ().Be (actionData.colorFrom); while (i < actionData.effectiveResultsCount * actionData.upPct) { result [i + 1].IsCloserOrSameTo (actionData.colorTo, result [i]).Should ().BeTrue (); i++; } // max brightness while (i < actionData.effectiveResultsCount * (actionData.upPct + actionData.maxColorPct)) { result [i].Should ().Be (actionData.colorTo); i++; } // descending while (i < actionData.effectiveResultsCount - 1) { result [i + 1].IsCloserOrSameTo (actionData.colorFrom, result[i]).Should ().BeTrue (); i++; } if (actionData.upPct + actionData.maxColorPct < 1) result [actionData.effectiveResultsCount].Should ().Be (actionData.colorFrom); }
public List<RGB> GetActionOutput(ActionParams actiondata) { int size = 0; IntPtr data = IntPtr.Zero; int errorCode = 0; errorCode = GetActionOutput ((uint)actiondata.action, out size, out data, actiondata.colorFrom, actiondata.colorTo, actiondata.startTime, actiondata.duration, actiondata.delayAfter, actiondata.tickLength, actiondata.count, actiondata.upPct, actiondata.maxColorPct, actiondata.firstColorPct, actiondata.secondColorPct); // We can't catch exceptions thrown in native code so we return errorCode instead if (errorCode != 0) { throw new Exception (string.Format ("Got error {0} in native code", errorCode)); } var result = new List<RGB> (); /*byte[] buffer = new byte[size * 3]; Marshal.Copy (data, buffer, 0, buffer.Length);*/ var structSize = Marshal.SizeOf (typeof(RGB)); for (int i = 0; i < size; i++) { var valuePtr = new IntPtr(data.ToInt64() + structSize * i); RGB tmpVal = (RGB)Marshal.PtrToStructure(valuePtr, typeof(RGB)); result.Add(tmpVal); } return result; }
public void ColorChange_Should_ShowBlack_AfterEnd(ActionParams actionData) { var sut = new LedWrapper (); var result = sut.GetActionOutput (actionData); var afterEndElemets = result.Skip (actionData.effectiveResultsCount + 1).ToList (); afterEndElemets.Count.Should ().Be (actionData.afterEndResultsCount); if (actionData.delayAfter > 0) afterEndElemets.Should ().OnlyContain (c => c.Equals(RGBColors.COLOR_BLACK)); }
public void ColorChange_Should_BeInOrder(ActionParams actionData) { var sut = new LedWrapper (); var result = sut.GetActionOutput (actionData); for (int i = 1; i < actionData.effectiveResultsCount; i++) { result [i].IsCloserOrSameTo (actionData.colorTo, result [i - 1]).Should ().BeTrue (); } }
public ActionParams(ActionParams data) { this.action = data.action; this.colorFrom = data.colorFrom; this.colorTo = data.colorTo; this.startTime = data.startTime; this.duration = data.duration; this.delayAfter = data.delayAfter; this.tickLength = data.tickLength; this.count = data.count; this.upPct = data.upPct; this.maxColorPct = data.maxColorPct; this.firstColorPct = data.firstColorPct; this.secondColorPct = data.secondColorPct; }