using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
public class SentimentAnalyzer
public static string ClassifyText(string text, Dictionary<string, Dictionary<string, int>> trainingData)
if (string.IsNullOrWhiteSpace(text) || trainingData == null || trainingData.Count == 0)
var sentiments = trainingData.Keys.ToList();
var probabilities = new Dictionary<string, double>();
var vocabulary = new HashSet<string>();
foreach (var sentimentData in trainingData.Values)
vocabulary.UnionWith(sentimentData.Keys);
int vocabularySize = vocabulary.Count;
foreach (var sentiment in sentiments)
if (!trainingData.ContainsKey(sentiment)) continue;
var wordsInSentiment = trainingData[sentiment];
double totalWordsInSentiment = wordsInSentiment.Values.Sum();
double logLikelihood = 0.0;
double prior = Math.Log((double)trainingData[sentiment].Count / vocabularySize);
var textWords = text.Split(' ');
foreach (var word in textWords)
if (string.IsNullOrWhiteSpace(word)) continue;
double wordCountInSentiment = wordsInSentiment.ContainsKey(word) ? wordsInSentiment[word] : 0;
double wordProbability = (wordCountInSentiment + 1) / (totalWordsInSentiment + vocabularySize);
logLikelihood += Math.Log(wordProbability);
probabilities[sentiment] = prior + logLikelihood;
string predictedSentiment = "positive";
double maxProbability = double.NegativeInfinity;
foreach (var kvp in probabilities)
if (kvp.Value > maxProbability)
maxProbability = kvp.Value;
predictedSentiment = kvp.Key;
return predictedSentiment;
public class SentimentAnalyzerTests
private Dictionary<string, Dictionary<string, int>> GetTrainingData()
return new Dictionary<string, Dictionary<string, int>>
"positive", new Dictionary<string, int>
"negative", new Dictionary<string, int>
public void ClassifyText_PositiveText_ReturnsPositive()
var trainingData = GetTrainingData();
string text = "this is a good and great movie";
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_NegativeText_ReturnsNegative()
var trainingData = GetTrainingData();
string text = "this is a bad and terrible movie";
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("negative", sentiment);
public void ClassifyText_MixedText_ReturnsPositive()
var trainingData = GetTrainingData();
string text = "this is a good and bad movie";
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_UnknownWords_ReturnsPositive()
var trainingData = GetTrainingData();
string text = "unknown words test";
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_EmptyText_ReturnsPositive()
var trainingData = GetTrainingData();
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_NullText_ReturnsPositive()
var trainingData = GetTrainingData();
string sentiment = SentimentAnalyzer.ClassifyText(null, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_EmptyTrainingData_ReturnsPositive()
var trainingData = new Dictionary<string, Dictionary<string, int>>();
string text = "this is a good movie";
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_NullTrainingData_ReturnsPositive()
string text = "this is a good movie";
string sentiment = SentimentAnalyzer.ClassifyText(text, null);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_OneSentimentMissing_ReturnsCorrectSentiment()
var trainingData = new Dictionary<string, Dictionary<string, int>>
"positive", new Dictionary<string, int>
string text = "bad terrible movie";
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
trainingData = new Dictionary<string, Dictionary<string, int>>
"negative", new Dictionary<string, int>
text = "good great movie";
sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("negative", sentiment);
trainingData = new Dictionary<string, Dictionary<string, int>>
"positive", new Dictionary<string, int>
"neutral", new Dictionary<string, int>
sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_WhitespaceText_ReturnsPositive()
var trainingData = GetTrainingData();
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
public static void Main()
Console.WriteLine("š Discovering and Running Tests...\n");
int totalPassed = 0, totalFailed = 0;
var testClasses = Assembly.GetExecutingAssembly()
.Where(t => t.GetCustomAttribute<TestClassAttribute>() != null);
foreach (var testClass in testClasses)
Console.WriteLine($"š Running tests in: {testClass.Name}");
(int passed, int failed) = RunTests(testClass);
Console.WriteLine("\nš FINAL SUMMARY:");
Console.WriteLine($"ā
Total Passed: {totalPassed}");
Console.WriteLine($"ā Total Failed: {totalFailed}");
Console.WriteLine($"š Total Tests: {totalPassed + totalFailed}");
Console.WriteLine("\nā
Test execution completed.");
private static (int passed, int failed) RunTests(Type testClassType)
object testInstance = Activator.CreateInstance(testClassType);
MethodInfo setupMethod = testClassType
.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.FirstOrDefault(m => m.GetCustomAttribute<TestInitializeAttribute>() != null);
MethodInfo[] testMethods = testClassType
.GetMethods(BindingFlags.Instance | BindingFlags.Public)
.Where(m => m.GetCustomAttribute<TestMethodAttribute>() != null)
int passed = 0, failed = 0;
foreach (var method in testMethods)
setupMethod?.Invoke(testInstance, null);
method.Invoke(testInstance, null);
Console.WriteLine($" ā
{method.Name} PASSED");
catch (TargetInvocationException ex)
Console.WriteLine($" ā {method.Name} FAILED: {ex.InnerException?.Message ?? ex.Message}");
Console.WriteLine($" ā ļø {method.Name} ERROR: {ex.Message}");