public void WeCanParseFbkTextToObject() { var funContent = @"FUNCTION_BLOCK SampleFBK VAR_INPUT InputVariable : BOOL; END_VAR VAR_OUTPUT OutputVariable : { REDUND_UNREPLICABLE} BOOL; END_VAR VAR InternalVariable : TransferConveyorStateEnum; END_VAR END_FUNCTION_BLOCK"; var fbk = new Fbk(funContent); fbk.Name.Should().Be("SampleFBK"); fbk.Variables.Count.Should().Be(3); fbk.Variables[0].Category.Should().Be(FbkVarCategory.Input); fbk.Variables[0].Name.Should().Be("InputVariable"); fbk.Variables[0].Type.Should().Be("BOOL"); fbk.Variables[1].Category.Should().Be(FbkVarCategory.Output); fbk.Variables[1].Name.Should().Be("OutputVariable"); fbk.Variables[1].Type.Should().Be("BOOL"); fbk.Variables[2].Category.Should().Be(FbkVarCategory.Local); fbk.Variables[2].Name.Should().Be("InternalVariable"); fbk.Variables[2].Type.Should().Be("TransferConveyorStateEnum"); }
public void FbkContentElementCanOutputItselfAndItsVariablesAsAnArrayOfStrings() { var funContent = @"FUNCTION_BLOCK SampleFBK VAR_INPUT InputVariable0 : BOOL; END_VAR VAR_OUTPUT OutputVariable: BOOL; END_VAR VAR InternalVariable: TransferConveyorStateEnum; END_VAR END_FUNCTION_BLOCK"; var fbk = new Fbk(Fbk.FlattenDefinitionText(funContent)); var fbkContentElement = new FbkContentElement(fbk); fbkContentElement.ToContent().Should().BeEquivalentTo(new string[] { "<--*****************SampleFBK Function Block Diagram*****************-->", $@"<Widget xsi:type=""widgets.brease.Label"" id=""Label_SampleFBK"" top=""0"" left=""200"" width=""240"" height=""60"" zIndex=""0"" text=""SampleFBK"" style=""FbkLabel"" />", $@"<Widget xsi:type=""widgets.brease.Label"" id=""Label_InputVariable0"" top=""0"" left=""0"" width=""200"" height=""60"" zIndex=""0"" text=""InputVariable0"" style=""VarLabelBoolFalse"" />", $@"<Widget xsi:type=""widgets.brease.Label"" id=""Label_OutputVariable"" top=""0"" left=""440"" width=""200"" height=""60"" zIndex=""0"" text=""OutputVariable"" style=""VarLabelBoolFalse"" />", $@"<Widget xsi:type=""widgets.brease.Label"" id=""Label_InternalVariable"" top=""60"" left=""220"" width=""200"" height=""60"" zIndex=""0"" text=""InternalVariable"" style=""VarLabelBoolFalse"" />", "<--******************************************************************-->" }); }
public void WeCanTurnAFbkIntoAContentElement() { var funContent = @"FUNCTION_BLOCK SampleFBK VAR_INPUT InputVariable0 : BOOL; InputVariable1 : BOOL; InputVariable2 : BOOL; END_VAR VAR_OUTPUT OutputVariable: BOOL; END_VAR VAR InternalVariable: TransferConveyorStateEnum; END_VAR END_FUNCTION_BLOCK"; var fbk = new Fbk(Fbk.FlattenDefinitionText(funContent)); var fbkContentElement = new FbkContentElement(fbk); fbkContentElement.ElementString.Should() .Be( $@"<Widget xsi:type=""widgets.brease.Label"" id=""Label_SampleFBK"" top=""0"" left=""200"" width=""240"" height=""180"" zIndex=""0"" text=""SampleFBK"" style=""FbkLabel"" />"); }
public FbkContentElement(Fbk fbk) { Name = fbk.Name; VarContentElements = GenerateContentElements(fbk.Variables); Left = FbkVarContentElement.VarLabelWidth; Height = CalculateHeight(fbk.Variables); Width = FbkWidth; Style = "FbkLabel"; }
public void WeCanIgnoreFunctions() { var funContent = "FUNCTION_BLOCK SampleFBK END_FUNCTION_BLOCK,FUNCTION SampleFunc : BOOL END_FUNCTION,FUNCTION_BLOCK SampleFBK2 END_FUNCTION_BLOCK"; var fbkTexts = Fbk.GetFunctionBlockTexts(funContent); fbkTexts[0].Should().Be("FUNCTION_BLOCK SampleFBK"); fbkTexts[1].Should().Be("FUNCTION_BLOCK SampleFBK2"); }
public void FbkContentElementHasVariableElementsWithCorrectPlacement() { var funContent = @"FUNCTION_BLOCK SampleFBK VAR_INPUT InputVariable0 : BOOL; InputVariable1 : BOOL; InputVariable2 : BOOL; END_VAR VAR_OUTPUT OutputVariable: BOOL; END_VAR VAR InternalVariable: TransferConveyorStateEnum; END_VAR END_FUNCTION_BLOCK"; var fbk = new Fbk(Fbk.FlattenDefinitionText(funContent)); var fbkContentElement = new FbkContentElement(fbk); //inputs fbkContentElement.VarContentElements[0].Name.Should().Be("InputVariable0"); fbkContentElement.VarContentElements[0].Top.Should().Be(0); fbkContentElement.VarContentElements[0].Left.Should().Be(0); fbkContentElement.VarContentElements[1].Name.Should().Be("InputVariable1"); fbkContentElement.VarContentElements[1].Top.Should().Be(FbkVarContentElement.VarLabelHeight); fbkContentElement.VarContentElements[1].Left.Should().Be(0); fbkContentElement.VarContentElements[2].Name.Should().Be("InputVariable2"); fbkContentElement.VarContentElements[2].Top.Should().Be(FbkVarContentElement.VarLabelHeight * 2); fbkContentElement.VarContentElements[2].Left.Should().Be(0); //local fbkContentElement.VarContentElements[3].Name.Should().Be("OutputVariable"); fbkContentElement.VarContentElements[3].Top.Should().Be(0); fbkContentElement.VarContentElements[3].Left.Should().Be(FbkVarContentElement.VarLabelWidth + FbkContentElement.FbkWidth); //outputs fbkContentElement.VarContentElements[4].Name.Should().Be("InternalVariable"); fbkContentElement.VarContentElements[4].Top.Should().Be(fbkContentElement.Top + FbkVarContentElement.VarLabelHeight); fbkContentElement.VarContentElements[4].Left.Should().Be(FbkVarContentElement.VarLabelWidth + FbkContentElement.Padding); }
public void WeCanRemoveLineBreaksAndWhiteSpaceFromFunctionDefinition() { var funContent = @"FUNCTION_BLOCK SampleFBK VAR_INPUT InputVariable : BOOL; END_VAR VAR_OUTPUT OutputVariable: { REDUND_UNREPLICABLE} BOOL; END_VAR VAR InternalVariable: TransferConveyorStateEnum; END_VAR END_FUNCTION_BLOCK"; var flatContent = Fbk.FlattenDefinitionText(funContent); flatContent.Should() .Be("FUNCTION_BLOCK SampleFBK,VAR_INPUT,InputVariable : BOOL;,END_VAR,VAR_OUTPUT,OutputVariable: { REDUND_UNREPLICABLE} BOOL;,END_VAR,VAR,InternalVariable: TransferConveyorStateEnum;,END_VAR,END_FUNCTION_BLOCK"); }
public void WeCanGetTheNameOfAFunctionBlock() { var funContent = @"{REDUND_ERROR} FUNCTION_BLOCK SampleFBK (*Transfer Conveyor State Manager*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) VAR_INPUT InputVariable : BOOL; END_VAR VAR_OUTPUT OutputVariable: { REDUND_UNREPLICABLE} BOOL; END_VAR VAR InternalVariable: TransferConveyorStateEnum; END_VAR END_FUNCTION_BLOCK"; var fbkName = Fbk.GetFbkName(funContent); fbkName.Should().Be("SampleFBK"); }
static void Main(string[] args) { var output = "C://Temp/Content.txt"; var path = string.Empty; while (string.IsNullOrWhiteSpace(path)) { Console.WriteLine("Enter the path to a .fun file to turn into mappview content:"); path = Console.ReadLine()?.Trim('"') ?? string.Empty; } var funContent = File.ReadAllText(path); var fbks = Fbk.ParseFunctionFile(funContent); var fbkContents = fbks.Select(f => new FbkContentElement(f)); var lines = fbkContents.SelectMany(f => f.ToContent()).ToArray(); File.WriteAllLines(output, lines); }
public void WeCanIsolateVariableGroupings() { var funContent = @"FUNCTION_BLOCK SampleFBK VAR_INPUT InputVariable : BOOL; END_VAR VAR_OUTPUT OutputVariable : { REDUND_UNREPLICABLE} BOOL; END_VAR VAR InternalVariable : TransferConveyorStateEnum; END_VAR END_FUNCTION_BLOCK"; var variableGroupTexts = Fbk.GetVariableGroupTexts(funContent); variableGroupTexts.Length.Should().Be(3); variableGroupTexts[0].Should().Be("VAR_INPUT,InputVariable : BOOL;"); variableGroupTexts[1].Should().Be("VAR_OUTPUT,OutputVariable : { REDUND_UNREPLICABLE} BOOL;"); variableGroupTexts[2].Should().Be("VAR,InternalVariable : TransferConveyorStateEnum;"); }
public Event(DateTime ClockStart, DateTime ClockEnd, int ClockRunTime, System.Xml.Linq.XDocument XMLEvents, ref CrashHandler Crash) { ch = Crash; events = new Dictionary<string, List<EventItem>>(); clock = new PartyClock(ClockStart, ClockEnd, ClockRunTime); Util.ShowClock = true; sound = new Sound(true); text = new Text2D(); chess = new Chess(); sf = new Starfield(150); intro = new Intro(ref sound, ref text); outro = new Outro(ref sound); advent = new Advent(ref sound); birthday = new Birthday(ref sound, ref text, ref chess); xmas = new Christmas(ref sound); smurf = new Datasmurf(ref sound, ref text); // random dif = new Dif(ref chess, ref sound); // random fbk = new Fbk(ref sound); // random hw = new Halloween(ref chess, ref sound, 25); lucia = new Lucia(ref chess, ref sound); newyear = new NewYear(); richard = new RMS(ref sound, ref text); // random scroller = new Scroller(ref chess, ref sf, ref text); // random semla = new Semla(); sune = new SuneAnimation(ref sound, ref text); tl = new TurboLogo(ref sound, ref chess, (OpenGL.Util.SpringOrFall.Equals("Spring")? true:false)/*((ClockStart.Month >= 1 && ClockStart.Month <= 8)? false:true)*/ ); // vilken termin är det? jan till början av augusti VT, resten HT... random valentine = new Valentine(ref sound); wl = new WinLinux(ref chess); //random creators = new Self(ref sound); // random bb = new BB(ref sound); // random GM = new GummiBears(ref sound); NDay = new National(ref chess, ref sound); easter = new Easter(ref sound); hajk = new Hajk(ref sound); mid = new Midsummer(ref sound); vaf = new Vaffla(); wp = new Walpurgis(); crayfish = new CrayFish(); ts = new TeknatStyle(ref chess, ref sound, ref text); m = new Matrix(ref text); q = new Quiz(ref text, false, ref sound); talepsin = new Talespin(ref sound); cd = new ChipAndDale(ref sound, ref chess); nerd = new Nerdy(ref chess, ref sound); trex = new Trex(ref sound); sailormoon = new Sailormoon(ref sound,ref chess); gb = new GhostBusters(ref sound); zelda = new Zelda(ref sound, ref chess); tardis = new Tardis(ref sound); f**k = new F**k(ref sound, ref chess); silverFang = new SilverFang(ref sound); mt = new MoraT(ref sound); swine = new Swine(ref chess, ref text); tjall = new Tjall(ref chess, ref text); ronja = new Ronja(ref sound); emil = new Emil(ref sound); djungelboken = new Djungelboken(ref sound); fabbe = new Fabbe(ref sound); drink = new Drink(ref sound); frozen = new Frozen(ref sound); eventCurrent = null; // event item for events to be triggerd in clock_NewDate //randomEvent = new List<string>(new string[] { "starfield", "SuneAnimation", "TurboLogo", "Datasmurf", "WinLinux", "Scroller", "BB", "GummiBears", "TeknatStyle", "Matrix"}); randomEvent = new List<string>(new string[] { "starfield", "Nerdy", "Talespin", "Sailormoon", "GhostBusters", "Zelda", "Tardis", "F**k", "SilverFang", "MoraT" }); //new stuff List<UtilXML.EventData> ed = UtilXML.Loadeffectdata(); // TODO: Make a clean list with all events allowed to be used implement so that it is actaully usable instead of a switch at the bottom of this file. Dictionary<string, Effect> effects = new Dictionary<string, Effect>() { {"SuneAnimation", new Effect(sune, ed.Find(e => e.Name == "SuneAnimation"))}, {"Dif",new Effect(dif, ed.Find(e => e.Name == "Dif"))}, {"Fbk",new Effect(fbk, ed.Find(e => e.Name == "Fbk"))}, {"TurboLogo",new Effect(tl, ed.Find(e => e.Name == "TurboLogo"))}, {"Datasmurf", new Effect(smurf, ed.Find(e => e.Name == "Datasmurf"))}, {"RMS",new Effect(richard, ed.Find(e => e.Name == "RMS"))}, {"WinLinux",new Effect(wl, ed.Find(e => e.Name == "WinLinux"))}, {"Scroller",new Effect(scroller, ed.Find(e => e.Name == "Scroller"))}, {"Self",new Effect(creators, ed.Find(e => e.Name == "Self"))}, {"BB",new Effect(bb, ed.Find(e => e.Name == "BB"))}, {"GummiBears",new Effect(GM, ed.Find(e => e.Name == "GummiBears"))}, {"Hajk",new Effect(hajk, ed.Find(e => e.Name == "Hajk"))}, {"TeknatStyle",new Effect(ts, ed.Find(e => e.Name == "TeknatStyle"))}, {"Matrix",new Effect(m, ed.Find(e => e.Name == "Matrix"))}, {"Quiz",new Effect(q, ed.Find(e => e.Name == "Quiz"))}, {"Talespin",new Effect(talepsin, ed.Find(e => e.Name == "Talespin"))}, {"ChipDale",new Effect(cd, ed.Find(e => e.Name == "ChipDale"))}, {"Nerdy",new Effect(nerd, ed.Find(e => e.Name == "Nerdy"))}, /* {"Trex",new Effect(trex, ed.Find(e => e.Name == "Trex"))},*/ {"Sailormoon",new Effect(sailormoon, ed.Find(e => e.Name == "Sailormoon"))}, {"GhostBusters",new Effect(gb, ed.Find(e => e.Name == "GhostBusters"))}, {"Zelda",new Effect(zelda, ed.Find(e => e.Name == "Zelda"))}, {"Tardis",new Effect(tardis, ed.Find(e => e.Name == "Tardis"))}, {"F**k",new Effect(f**k, ed.Find(e => e.Name == "F**k"))}, {"SilverFang",new Effect(silverFang, ed.Find(e => e.Name == "SilverFang"))}, {"MoraT",new Effect(mt, ed.Find(e => e.Name == "MoraT"))}, {"Ronja",new Effect(ronja, ed.Find(e => e.Name == "Ronja"))}, {"Emil",new Effect(emil, ed.Find(e => e.Name == "Emil"))}, {"Djungelboken",new Effect(djungelboken, ed.Find(e => e.Name == "Djungelboken"))}, {"Fabbe",new Effect(fabbe, ed.Find(e => e.Name == "Fabbe"))}, {"Drink",new Effect(drink, ed.Find(e => e.Name == "Drink"))}, {"Frozen",new Effect(drink, ed.Find(e => e.Name == "Frozen"))} }; runEffectInMonth = new Dictionary<string, List<objdata>>(); string[] months = Util.monthlist(); int counter; foreach (KeyValuePair<string, Effect> pair in effects) { counter = 0; foreach (bool b in pair.Value.RunAllowedlist) { if (b == true) { if (!runEffectInMonth.ContainsKey(months[counter])) { runEffectInMonth.Add(months[counter], new List<objdata>()); } runEffectInMonth[months[counter]].Add(new objdata(pair.Key, pair.Value.Vetolist[counter], pair.Value.Priolist[counter], pair.Value.Runslist[counter])); } counter++; } } clock.NewDate += clock_NewDate; // Event listener if (ch.CrashDialogResult == System.Windows.Forms.DialogResult.Yes) { clock.clock = ch.CrashClock; } string name, date, type; // Event dates setup foreach (var item in XMLEvents.Descendants("event")) { name = item.Element("name").Value; date = item.Element("date").Value; type = item.Element("type").Value.ToLower(); EventItem ei = new EventItem(name, type, date); if (!events.ContainsKey(date)) { List<EventItem> list = new List<EventItem>(); // seems most bad in my eyes... events.Add(date, list); } for (int i = 0; i < events[date].Count; i++) { EventItem e = events[date][i]; if ("birthday".Equals(e.Type) && "birthday".Equals(ei.Type)) { e.Name += "\n\n" + ei.Name; events[date][i] = e; } } events[date].Add(ei); name = date = type = string.Empty; } // this needs to be fixed nicer... if (events.ContainsKey(ClockEnd.ToShortDateString())) { events[ClockEnd.ToShortDateString()].Clear(); // force this to be top.. events[ClockEnd.ToShortDateString()].Add( new EventItem("outro", "outro", ClockEnd.ToShortDateString()) ); } else { events.Add(ClockEnd.ToShortDateString(), new List<EventItem>() { new EventItem("outro", "outro", ClockEnd.ToShortDateString()) }); } // Random effects on dates with no effects and check against new list of allowed things for them... DateTime dt = ClockStart; bool star = (Util.Rnd.Next(0, 1000) < 500 ? true:false); // make this random at the start too? int num = 0; while (dt <= ClockEnd) { date = dt.ToShortDateString(); if (!events.ContainsKey(date)) { EventItem ei; if (num == 0 || num == 1) { ei = new EventItem("starfield", "random", date); } else { //ei = new EventItem(randomEvent[Util.Rnd.Next(1, randomEvent.Count)], "random", date); string month = ""; if (dt != null) month = dt.Month.ToString(); switch (month) { case "1": month = "jan"; break; case "2": month = "feb"; break; case "3": month = "mar"; break; case "4": month = "apr"; break; case "5": month = "maj"; break; case "6": month = "jun"; break; case "7": month = "jul"; break; case "8": month = "aug"; break; case "9": month = "sep"; break; case "10": month = "okt"; break; case "11": month = "nov"; break; case "12": month = "dec"; break; }//switch if (runEffectInMonth.ContainsKey(month)) { List<objdata> mobj = runEffectInMonth[month]; List<objdata> vetolist = new List<objdata>(); List<objdata> novetolist = new List<objdata>(); foreach (objdata n in mobj) { if ("Quiz".Equals(n.Name) && eventnum == 4) { n.vetoAgain(); eventnum = 0; } if (n.Veto == true) { if (n.Runs > 0) vetolist.Add(n); } else { if (n.Runs > 0) novetolist.Add(n); } } vetolist.Sort(); novetolist.Sort(); if (vetolist.Count > 0) { ei = new EventItem(vetolist[0].Name, "random", date); vetolist[0].noMoreVeto(); } else if (novetolist.Count > 0) { ei = new EventItem(novetolist[0].Name, "random", date); novetolist[0].decRuns(); if (eventnum < 4) eventnum++; } else { ei = new EventItem(randomEvent[Util.Rnd.Next(1, randomEvent.Count)], "random", date); } } else { ei = new EventItem(randomEvent[Util.Rnd.Next(1, randomEvent.Count)], "random", date); } } num++; if (num == 3) { num = 0; } ei = new EventItem("Self", "random", date); // this is for debuging new events events.Add(date, new List<EventItem>()); events[date].Add(ei); } dt = dt.AddDays(1); date = string.Empty; } }
public void WeCanParseAFullDotFunFileWithMultipleFbks() { var sampleFilePath = "SampleFile\\TTCtrlLIB.fun"; var fileContent = File.ReadAllText(sampleFilePath); var fbks = Fbk.ParseFunctionFile(fileContent); fbks.Count.Should().Be(10); fbks[0].Name.Should().Be("TransferConveyorStateMgrFBK"); fbks[0].Variables.Count.Should().Be(11); fbks[0].Variables.Count(v => v.Category.Equals(FbkVarCategory.Input)).Should().Be(5); fbks[0].Variables.Count(v => v.Category.Equals(FbkVarCategory.Output)).Should().Be(2); fbks[0].Variables.Count(v => v.Category.Equals(FbkVarCategory.Local)).Should().Be(4); fbks[1].Name.Should().Be("TT_Mark_DKFV_CtrlFBK"); fbks[1].Variables.Count.Should().Be(25); fbks[1].Variables.Count(v => v.Category.Equals(FbkVarCategory.Input)).Should().Be(18); fbks[1].Variables.Count(v => v.Category.Equals(FbkVarCategory.Output)).Should().Be(4); fbks[1].Variables.Count(v => v.Category.Equals(FbkVarCategory.Local)).Should().Be(3); fbks[2].Name.Should().Be("TT_Mark_DKFV_InputConfigFBK"); fbks[2].Variables.Count.Should().Be(19); fbks[2].Variables.Count(v => v.Category.Equals(FbkVarCategory.Input)).Should().Be(9); fbks[2].Variables.Count(v => v.Category.Equals(FbkVarCategory.Output)).Should().Be(4); fbks[2].Variables.Count(v => v.Category.Equals(FbkVarCategory.Local)).Should().Be(6); fbks[3].Name.Should().Be("TT_Mark_DKFV_MgrFBK"); fbks[3].Variables.Count.Should().Be(39); fbks[3].Variables.Count(v => v.Category.Equals(FbkVarCategory.Input)).Should().Be(26); fbks[3].Variables.Count(v => v.Category.Equals(FbkVarCategory.Output)).Should().Be(8); fbks[3].Variables.Count(v => v.Category.Equals(FbkVarCategory.Local)).Should().Be(5); fbks[4].Name.Should().Be("TT_Mark_DKFV_OutputConfigFBK"); fbks[4].Variables.Count.Should().Be(7); fbks[4].Variables.Count(v => v.Category.Equals(FbkVarCategory.Input)).Should().Be(4); fbks[4].Variables.Count(v => v.Category.Equals(FbkVarCategory.Output)).Should().Be(3); fbks[4].Variables.Count(v => v.Category.Equals(FbkVarCategory.Local)).Should().Be(0); fbks[5].Name.Should().Be("TT_Mark_DKFV_PartPassCtrlFBK"); fbks[5].Variables.Count.Should().Be(9); fbks[5].Variables.Count(v => v.Category.Equals(FbkVarCategory.Input)).Should().Be(6); fbks[5].Variables.Count(v => v.Category.Equals(FbkVarCategory.Output)).Should().Be(3); fbks[5].Variables.Count(v => v.Category.Equals(FbkVarCategory.Local)).Should().Be(0); fbks[6].Name.Should().Be("TT_TDC_DKFV_CtrlFBK"); fbks[6].Variables.Count.Should().Be(24); fbks[6].Variables.Count(v => v.Category.Equals(FbkVarCategory.Input)).Should().Be(17); fbks[6].Variables.Count(v => v.Category.Equals(FbkVarCategory.Output)).Should().Be(4); fbks[6].Variables.Count(v => v.Category.Equals(FbkVarCategory.Local)).Should().Be(3); fbks[7].Name.Should().Be("TT_TDC_DKFV_InputConfigFBK"); fbks[7].Variables.Count.Should().Be(21); fbks[7].Variables.Count(v => v.Category.Equals(FbkVarCategory.Input)).Should().Be(9); fbks[7].Variables.Count(v => v.Category.Equals(FbkVarCategory.Output)).Should().Be(5); fbks[7].Variables.Count(v => v.Category.Equals(FbkVarCategory.Local)).Should().Be(7); fbks[8].Name.Should().Be("TT_TDC_DKFV_OutputConfigFBK"); fbks[8].Variables.Count.Should().Be(7); fbks[8].Variables.Count(v => v.Category.Equals(FbkVarCategory.Input)).Should().Be(4); fbks[8].Variables.Count(v => v.Category.Equals(FbkVarCategory.Output)).Should().Be(3); fbks[8].Variables.Count(v => v.Category.Equals(FbkVarCategory.Local)).Should().Be(0); fbks[9].Name.Should().Be("TT_TDC_DKFV_PartPassCtrlFBK"); fbks[9].Variables.Count.Should().Be(9); fbks[9].Variables.Count(v => v.Category.Equals(FbkVarCategory.Input)).Should().Be(6); fbks[9].Variables.Count(v => v.Category.Equals(FbkVarCategory.Output)).Should().Be(3); fbks[9].Variables.Count(v => v.Category.Equals(FbkVarCategory.Local)).Should().Be(0); }