Look for similar strings in a text file C# - c#

I have a text file that contains:
Memory Test
Test Results : Pass
Video Test
Test Results : Pass
Audio Test
Test Results : Fail
I need to return 'true' if all Test Results are Pass and 'false' if one or more test results is Fail.
List<string> filecontents = File.ReadAllLines("abc.txt").ToList<string();
//If all "Test results : Pass"
{
return true;
}
for (int i = 0; i < filecontents.Count; i++)
{
if (filecontents[i].Contains("Test Results : Fail"))
{
return false;
}
}
Thank you.

You already got it,
....
for (int i = 0; i < filecontents.Count; i++)
{
if (filecontents[i].Contains("Test Results : Fail"))
{
return false;
}
}
return true;

No need to read the entire file into memory at once:
var oneOrMoreTestsFailed =
File.ReadLines(filename)
.Any(x => x.Contains("Test Results : Fail"));
return !oneOrMoreTestsFailed;
This reads the file line-by-line. It also will exit when it encounters the first failure. So it doesn't necessarily have to read the entire file.

It sounds like you are really just looking for the presence of "Fail" right?
string text = File.ReadAllText("myText.txt");
if (text.Contains("Fail"))
return false;

Related

How I can automatization tests if data input in console?

I have a file with data in the form of strings that are sequentially entered into the console. I also have a file of correct answers in the same format. (You may have seen such a testing format on codeforces). I decided to automate the process (in my project in visual studio) and I want to do it through Unit tests so as not to rebuild the code too much every time (so that it passes on codeforces).
Input data in the same format (output the same):
5
256 42
1000 1000
-1000 1000
-1000 1000
20 22
At the moment I have created methods to get the data and compare my results with the correct output file results. But I don't really like this option, since files need to be entered by hand or sorted with a check for existence. I would like these issues to be solved out of the box.
public static string[] GetFileData(string File)
{
string[] result = { };
foreach (string line in System.IO.File.ReadLines(File))
{
string? str = line;
if (str == null) break;
//Console.WriteLine(str);
result.Append(str);
}
return result;
}
public static bool Compare(string[] result, string[] _out)
{
if (result.Length != _out.Length)
{
Console.WriteLine("Error. Array not equal");
return false;
}
for (int i = 0; i < result.Length; i++)
{
if (result[i] != _out[i])
{
Console.WriteLine($"Error! - {result[i]} != {_out[i]}");
return false;
}
}
Console.WriteLine($"Success");
return true;
}

How to iterate through multiple variables?

I'd like to create a short program to download several pictures from a website.
On a form, I would like to enter a root-link to a website with placeholders.
The placeholders can be defined with Start/End value and asc/desc.
For example: the original link is
google.de/1236-01.jpg
and I'd like to generate all links from
google.de/1236-1.jpg
up to
google.de/9955-12.jpg
So my input would be "google.de/[0]-[1].jpg" and placeholders are set to:
[0] = start 1236|end 9955|asc
[1] = start 1|end 12|asc
Via GetValidCharacters() I get a String-List of valid combinations for each entered placeholder (can be selected via ascending/descending + start&end).
The goal I'm struggling with is to build all combinations of this link, because I need to determine while runtime, how much placeholders I have.
My idea was to loop over an queue and enquueue each new build line, until there is none left with placeholders, but I don't know how to do this.
I need to make sure that all combinations are entered and they are entered only once.
private static void CreateDownloadList()
{
Queue<string> tmpQueue = new Queue<string>(); //temp queue
tmpQueue.Enqueue(DL_path); //DL_Path = google.de/[0]-[1].jpg
string line = "";
while ((line = tmpQueue.Dequeue()) != null) //not empty
{
if (line.Contains("[")) //placeholder
{
string tmpLine = line;
//how to determine, which placeholder is next?? need to know this and replace this with every combination, I get from GetValidCharacters(start, end, DESC)
}
else //done
{
_urlList.Add(line);
}
}
}
how about a simple for loop?
for (int i = 1236; i <= 9955; i++)
{
for (int j = 1; j <= 12; j++)
{
tmpQueue.Enqueue(string.Format("google.de/{0}-{1}.jpg", i, j));
}
}
I'm not going give you the full code but here is some pseudo code that would solve the problem.
given :
todostack -- stack object that holds a list of unresolved items
replace_map -- map object that holds marker string and map of all values
marker_list -- list of all markers
final_list -- list object that holds the results
(note you can probably use marker_list and replace_map in one object -- I have them separate to make my code clearer)
init :
push todostack with your starting string
set marker_list and replace_map to correct values (from parameters I assume)
clear final_list
algorithm :
while (there are any items in todostack)
{
curitem = todostack.pop
if (curitem contains a marker in marker_list)
{
loop for each replacement in replace_map
{
new_item = curitem replaced with replacement
todostack.push(new_item)
}
}
else
add curitem to final_list
}
#Hogan this was the hint to the correct way.
solution is this
private void CreateDownloadList()
{
Queue<string> tmpQueue = new Queue<string>();
tmpQueue.Enqueue(downloadPathWithPlaceHolders);
while(tmpQueue.Count > 0)
{
string currentItem = tmpQueue.Dequeue();
bool test = false;
if(currentItem.Contains("["))
{
foreach(Placeholder p in _placeholders)
{
if(currentItem.Contains(p.PlaceHolder))
{
foreach(string s in p.Replacements)
{
tmpQueue.Enqueue(currentItem.Replace(p.PlaceHolder, s));
}
test = true;
}
if(test)
break;
}
}
else
{
_downloadLinkList.Add(currentItem);
}
}
}

Unable to parse code snippet in roslyn

I'm trying to dynamically build a c# class from small pieces of code. We have a window where a user can enter c# code (valid or not), and we parse these strings into roslyn. I recently found an issue when i was using this :
public override IEnumerable<StatementSyntax> GenerateStatements()
{
var result = new List<StatementSyntax>();
if (!string.IsNullOrWhiteSpace(this.Tag.Code))
{
result.Add(SyntaxFactory.ParseStatement(this.Tag.Code));
}
return result;
}
Turns out when compiling in VB, if the statement is multiline, it would inline all the text, even in c#.
I then made an helper class to parse it into a dummy class and method to get a list of parsed statements.
public override IEnumerable<StatementSyntax> GenerateStatements()
{
var result = new List<StatementSyntax>();
if (!string.IsNullOrWhiteSpace(this.Tag.Code))
{
foreach (var statement in SyntaxFactoryHelper.ParseStatements(this.Tag.Code))
{
result.Add(statement);
}
}
return result;
}
public static StatementSyntax[] ParseStatements(string code)
{
var blockCode = string.Format(CultureInfo.InvariantCulture, "public class C {{ public void M() {{ {0} }} }}", code);
var compilationUnit = SyntaxFactory.ParseCompilationUnit(blockCode);
return compilationUnit
.ChildNodes().OfType<ClassDeclarationSyntax>().First(c => c.Identifier.Text == "C")
.ChildNodes().OfType<MethodDeclarationSyntax>().First(m => m.Identifier.Text == "M")
.ChildNodes().OfType<BlockSyntax>().First()
.Statements.ToArray();
}
Here's my issue.
If i have 3 statements in my applications.
for (var i = 0; i < 10; i++)
{
then
i.ToString()
and finally
}
It auto-closes the curly braces of the first statement, so I lose my scope.
Is there a way to parse invalid code and avoid this kind of behavior?
I know inlined code is valid in c#, but we are facing the same issue with VB.
Thanks for your help :)

How to take screenshot if Assert.AreEqual fails? How to put if condition with Assert.AreEqual?

I am trying to take screenshot of failed test case in C# selenium.
But i dont know how to use if condition with Assert.AreEqual.
I tried using if(Assert.Equals == false) also but that's not working.
Can anybody help??
Well actually, "Asset.AreEqual" accepts three parameter
1. expected result in bool
2. Original result in bool
3. error message
if expected and original does not match it will throw an error and for the screenshot u need to use try-catch, I have used this long ago.
public void AreEqual(bool expected, bool result, string comment = "",string pictureName = "")
{
try
{
Assert.AreEqual(expected, result, comment);
}
catch
{
/// will capture a screenshot of errors
if (string.IsNullOrEmpty(pictureName) && !string.IsNullOrEmpty(comment))
{
int length = comment.Replace(" ", string.Empty).Length;
if (length > 30)
length = 30;
pictureName = comment.Replace(" ", string.Empty).Substring(0, length);
}
pictureName = (pictureName == "" ? Guid.NewGuid().ToString() : pictureName);
GetScreenShot(pictureName);
// Getscreenshot function capture image for me u need to put your code here(before throw)
throw;
}
}
It'd help to see more of your actual test, but since Assert.Equals doesn't return a value, you could break it down into multiple steps.
For example, if you have this:
Assert.AreEqual(value1, value2);
Then you could replace it with this:
var areValuesEqual = (value1 == value2);
Assert.IsTrue(areValuesEqual);
if (!areValuesEqual)
{
// rest of testing logic
}

Return value from For loop

I have a listView in my app. I loop through the items to check which one is currently selected and then return a value. As all paths have to return a value I have to return a value outside the loop which overwrites the for loop return, how do I keep this without overwriting it after the loop?
public string GetItemValue()
{
for (int i = 0; i < listView1.Items.Count; i++)
{
if (listView1.Items[i].Checked == true)
{
return listView1.Items[i].Text; // I want to keep this value
}
}
// Without overwriting it with this but the compiler
// requires me to return a value here
return "Error";
}
Any help is most appreciated. Thanks.
P.S I have tried using break after the if but no luck.
On edit: bringing down my comment from above.
You don't need to worry about this. As soon as it hits the first return inside the loop, it will return immediately with that value. No code outside the loop is ever hit in that case.
Incidentally, this code would be cleaner:
public string GetItemValue()
{
foreach (var item in listView1.Items)
{
if (item.Checked) return item.Text;
}
throw new InvalidOperationException("No checked items found");
}
Exceptions are a more idiomatic way of handling errors, and the foreach loop is preferred to a for loop when you're just iterating over collections.
Also using LINQ, you can get even more concise:
public string GetItemValue()
{
return listView1.Items.Cast<ListViewItem>().Single(i => i.Checked).Text;
}
Well, your return outside of the loop, return "Error"; shouldn't get called based on your logic. Since return causes your method to immediately exit, the "Error" return will never happen, that is unless the code never steps into the if inside the loop.
All things considered, this may be an exceptional case in your code. Thus, throwing an exception may be the appropriate thing to do:
public string GetItemValue()
{
for (int i = 0; i < listView1.Items.Count; i++)
{
if (listView1.Items[i].Checked == true)
{
return listView1.Items[i].Text; // I want to keep this value
}
}
throw new InvalidOperationException("Did not find value expected.");
}
Exceptions are usually thrown to indicate that a bug exists in code. A "Hey, that should really not be happening." The application stops, and hopefully the user gets an opportunity to contact support to help you reproduce it.
Based on your comment:
When I run it, it just returns the error text...
That means your check in your if statement is not succeeding.
if (listView1.Items[i].Checked == true)
Which means that none of your items in your ListView are checked.
That's the kind of situations where you are probably better of throwing an exception in order to signal the exceptional situation:
public string GetItemValue()
{
for (int i = 0; i < listView1.Items.Count; i++)
{
if (listView1.Items[i].Checked == true)
{
// Here you are leaving the GetItemValue method
// and the loop stops
return listView1.Items[i].Text;
}
}
// if we get that far it means that none of the items of
// the select list was actually checked => we are better of
// reporting this to the caller of the method
throw new Exception("Please select a value");
}
The return in your for loop isn't overwritten -- the method will return the value in the loop if your conditions are met. Execution of the method ends immediately upon reaching a return statement.
If your method is returning "Error", then I'd recommend looking at your code in a debugger, because it's reaching the end of the loop and returning the value "Error".
If you're returning a value in the loop, it should not reach the return that's outside of the loop. I would check to make sure that the loop is finding the selected item.
The other option is to create a local variable to hold the return value:
string returnValue = "Error";
for (int i = 0; i < listView1.Items.Count; i++)
{
if (listView1.Items[i].Checked == true)
{
returnValue = listView1.Items[i].Text;
break;
}
}
return returnValue;
Lastly, you might also consider returning an exception when no selections are found, and handling the exception from the calling method.
The return "Error" bit will not overwrite your loop return value. When a return is hit, the function exits, so when a value that is selected is found, the function will spit out your data and stop.
The compiler requires that all paths of the function return a value. The compiler cannot know before hand whether your inner loop if condition will be met. You can cache the value at a variable and return this in the end of the function e.g. :
public string GetItemValue()
{
string temp = null;
for (int i = 0; i < listView1.Items.Count; i++)
{
if (listView1.Items[i].Checked == true)
{
temp = listView1.Items[i].Text; // I want to keep this value
break;
}
}
return temp; // Without overwriting it with this but the compiler requires me to return a value here
}
Actually, there is no need for a loop here:
return (listView1.SelectedItems.Count > 0)
? listView1.SelectedItems[0].Text
: "Error";
But, as it was said, the original question is misleading since return does not override values. You might be thinking about assignment, instead of return. In this case a working code can look like this:
string ret = "Error";
foreach(var item in listView1.Items)
{
if(item.Checked) { ret = item.Text; break; }
}
return ret;

Categories

Resources