Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions se5/BrazilianToEuropeanPortuguese.Tests/AnnoyanceSlangTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using SubtitleEdit.Plugins.BrazilianToEuropeanPortuguese;
using SubtitleEdit.Plugins.Shared;

namespace BrazilianToEuropeanPortuguese.Tests;

public sealed class AnnoyanceSlangTests
{
[Theory]
[InlineData("quando um pé no saco da polícia\ncomeçou a fazer perguntas.",
"when some NYPD dick started asking questions.",
"quando um chato da polícia\ncomeçou a fazer perguntas.")]
[InlineData("Ele é um pé no saco.", null, "Ele é um chato.")]
[InlineData("Ela é uma pé no saco.", null, "Ela é uma chata.")]
[InlineData("Eles são uns pés no saco.", null, "Eles são uns chatos.")]
[InlineData("Elas são umas pés no saco.", null, "Elas são umas chatas.")]
[InlineData("Ele era um pé-no-saco.", null, "Ele era um chato.")]
[InlineData("Isso é um pé no saco.", null, "Isso é uma chatice.")]
[InlineData("O trabalho era um pé no saco.", null, "O trabalho era uma chatice.")]
[InlineData("É um pé no saco.", null, "É um incómodo.")]
[InlineData("ELE É UM PÉ NO SACO.", null, "ELE É UM CHATO.")]
[InlineData("<i>Ele é um pé no saco.</i>", null, "<i>Ele é um chato.</i>")]
[InlineData("Ele me enche o saco.", "He annoys me.", "Ele chateia-me.")]
[InlineData("Ele me encheu o saco.", null, "Ele chateou-me.")]
[InlineData("Não me enche o saco.", "He doesn't annoy me.", "Não me chateia.")]
[InlineData("Ele enche o meu saco.", null, "Ele chateia-me.")]
[InlineData("Ele enche meu saco.", null, "Ele chateia-me.")]
[InlineData("Ela torra o nosso saco.", null, "Ela chateia-nos.")]
[InlineData("Eles me torravam o saco.", null, "Eles chateavam-me.")]
[InlineData("Para de me encher o saco.", "Stop bothering me.", "Para de me chatear.")]
[InlineData("Para de encher o saco.", null, "Para de chatear.")]
[InlineData("Para de torrar meu saco.", null, "Para de me chatear.")]
[InlineData("Ele te torrou o saco.", null, "Ele chateou-te.")]
[InlineData("Ele nos enchia o saco.", null, "Ele chateava-nos.")]
[InlineData("Ele enche-me o saco.", null, "Ele chateia-me.")]
[InlineData("Ele torrou-me o saco.", null, "Ele chateou-me.")]
[InlineData("Encher o saco.", "To annoy.", "Chatear.")]
[InlineData("Torrar o saco.", "To pester.", "Chatear.")]
[InlineData("ELE ME ENCHE O SACO.", null, "ELE CHATEIA-ME.")]
[InlineData("<i>Ele me torrou o saco.</i>", null, "<i>Ele chateou-me.</i>")]
public void ReviewedAnnoyanceExpressionsUseEuropeanEquivalents(string source, string? english, string expected)
{
var converter = new PortugueseConverter();
var hint = ReferenceHint.FromText(english);
Assert.Equal(expected, converter.Convert(source, reference: hint));
Assert.Equal(expected, converter.Convert(expected, reference: hint));
}

[Theory]
[InlineData("Pôs um pé no saco.", null)]
[InlineData("Ele pôs um pé no saco de dormir.", null)]
[InlineData("Ele está com um pé no saco.", null)]
[InlineData("Encheu o saco de batatas.", null)]
[InlineData("Encheu o saco com dinheiro.", null)]
[InlineData("Ele encheu o saco.", "He made a lot of money.")]
[InlineData("Ele torrou o saco.", null)]
[InlineData("Ele torrou o saco de café.", null)]
[InlineData("Ele encheu o meu saco com arroz.", null)]
[InlineData("Ele encheu-me o saco de moedas.", null)]
[InlineData("Ele encheu o meu saco até cima.", null)]
[InlineData("Ele encheu o meu saco.", "He filled my bag.")]
[InlineData("Ele encherá o meu saco.", null)]
[InlineData("O saco está cheio.", null)]
public void LiteralAndFinancialSensesArePreserved(string source, string? english) =>
Assert.Equal(source, new PortugueseConverter().Convert(source, reference: ReferenceHint.FromText(english)));

[Fact]
public void OptionsIgnoredPhrasesAndCustomWordsWin()
{
const string source = "Ele é um pé no saco.";
foreach (var options in new[]
{
new ConversionOptions(Vocabulary: false),
new ConversionOptions(Colloquial: false),
new ConversionOptions(DisabledRules: "annoyance-slang"),
})
Assert.Equal(source, new PortugueseConverter(options).Convert(source));
var words = new PortugueseLocalWordList();
words.Ignored.Add("pé no saco");
words.Ignored.Add("encher o saco");
var converter = new PortugueseConverter(localWordList: words);
Assert.Equal(source, converter.Convert(source));
Assert.Equal("Ele enche-me o saco.", converter.Convert("Ele me enche o saco."));
Assert.Equal("Ele me enche o saco.", new PortugueseConverter(new ConversionOptions(Pronouns: false))
.Convert("Ele me enche o saco."));
Assert.Equal("Ele é um chato.", new PortugueseConverter(new ConversionOptions(Pronouns: false)).Convert(source));
var custom = new PortugueseLocalWordList();
custom.Words.Add(("pé no saco", "melga"));
Assert.Equal("Ele é um melga.", new PortugueseConverter(localWordList: custom).Convert(source));
}

[Fact]
public void ExactCuePreservesBothLinesAndTiming()
{
var cue = new SrtBlock { StartMs = 807371, EndMs = 810759,
Text = "quando um pé no saco da polícia\ncomeçou a fazer perguntas." };
var result = Assert.Single(SubtitleConversion.Convert(new[] { cue }, ConversionOptions.Default,
english: new string?[] { "when some NYPD dick started asking questions." }));
Assert.Equal("quando um chato da polícia\ncomeçou a fazer perguntas.", result.Text);
Assert.Equal(807371, cue.StartMs);
Assert.Equal(810759, cue.EndMs);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ public void ScoringNeedsDrugOrEnglishEvidence()
[InlineData("Ele foi faturar no bairro.", "He went to score in the neighborhood.", "Ele foi comprar no bairro.")]
[InlineData("É onde eu costumava faturar.", "That's where I used to score.", "É onde eu costumava comprar.")]
[InlineData("Ele tentou faturar dele.", "He tried to score from him.", "Ele tentou comprar dele.")]
[InlineData("Faturou ontem à noite?", "Did you score last night?", "Comprou ontem à noite?")]
[InlineData("Faturou ontem à noite?", "Did you score last night?", "Compraste ontem à noite?")]
[InlineData("Ele faturou!", "He scored a goal!", "Ele marcou!")]
[InlineData("O time precisa faturar.", "The team needs to score.", "A equipa precisa de marcar.")]
[InlineData("Ele faturou no segundo tempo.", "He scored in the second half.", "Ele marcou na segunda parte.")]
Expand Down Expand Up @@ -572,7 +572,7 @@ public void RemainingAddressAndReflexiveGapsUseEuropeanForms(string input, strin
[InlineData("Pode ir aproveitar seu fim de semana.", "You go have your little weekend.", "Podes ir aproveitar o teu fim de semana.")]
[InlineData("Lembra do meu noivo, David.", "You remember my fiancé, David.", "Lembras-te do meu noivo, David.")]
[InlineData("Que papo é esse? Como pode ter certeza?", "What the hell? Um, how... How are you sure though?", "Que conversa é essa? Como podes ter a certeza?")]
[InlineData("Pode pegar um caderninho\nque está na minha bolsa?", "Can you reach into my purse and hand me my tiny notebook?", "Pode pegar num caderninho\nque está na minha bolsa?")]
[InlineData("Pode pegar um caderninho\nque está na minha bolsa?", "Can you reach into my purse and hand me my tiny notebook?", "Podes pegar num caderninho\nque está na minha bolsa?")]
[InlineData("De que merda está falando?", "What the fuck are you talkin' about?", "De que merda estás a falar?")]
[InlineData("Para que arma se só vai bater na porta?", "Why are you takin' a gun if you just have to knock on the door?", "Para que arma se só vais bater à porta?")]
[InlineData("Isso vai a julgamento mês que vem.", "Would you mind if I take a look? This is going to trial next month.", "Isto vai a julgamento mês que vem.")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ public sealed class ClauseAgreementAnalysisTests
[InlineData("Certeza?", "Certeza", "NominalUse")]
[InlineData("Ajuda financeira.", "Ajuda", "NominalUse")]
[InlineData("Ela precisa de ajuda.", "precisa", "OtherSubject")]
[InlineData("Toda a equipa\nprecisa de uma mascote.", "precisa", "OtherSubject")]
[InlineData("Toda equipa\nprecisa de mascotes.", "precisa", "OtherSubject")]
[InlineData("Cada equipa\nconsegue sair.", "consegue", "OtherSubject")]
[InlineData("Maria trabalha aqui.", "trabalha", "OtherSubject")]
[InlineData("É necessário sair.", "É", "Impersonal")]
[InlineData("A pessoa que tu achas que precisa de ajuda.", "precisa", "RelativeSubject")]
Expand All @@ -25,6 +28,7 @@ public void StructuralReasonsBlockUnsafeAgreement(string text, string verb, stri

[Theory]
[InlineData("Precisa de ajuda.", "Precisa")]
[InlineData("O quê, está a controlar-me?", "está")]
[InlineData("Se não precisar de ajuda.", "precisar")]
[InlineData("Tu sabes que precisa de ajuda.", "precisa")]
[InlineData("Ela saiu. Precisa de ajuda.", "Precisa")]
Expand Down
114 changes: 114 additions & 0 deletions se5/BrazilianToEuropeanPortuguese.Tests/CollectiveAndGreetingTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using SubtitleEdit.Plugins.BrazilianToEuropeanPortuguese;
using SubtitleEdit.Plugins.Shared;

namespace BrazilianToEuropeanPortuguese.Tests;

public sealed class CollectiveAndGreetingTests
{
[Theory]
[InlineData("Toda equipe\nprecisa de uma mascote.", "Every team needs a mascot.", "Toda a equipa\nprecisa de uma mascote.")]
[InlineData("Toda a equipa\nprecisa de várias mascotes.", null, "Toda a equipa\nprecisa de várias mascotes.")]
[InlineData("A equipa\nprecisa de ajuda.", "You need help.", "A equipa\nprecisa de ajuda.")]
[InlineData("Cada equipa\nconsegue fazer isso.", null, "Cada equipa\nconsegue fazer isso.")]
[InlineData("Todo grupo\nmerece ter ajuda.", null, "Todo o grupo\nmerece ter ajuda.")]
[InlineData("A família\nsabe como ajudar.", "You know how to help.", "A família\nsabe como ajudar.")]
[InlineData("A equipa\nquer sair?", "Do you want to leave?", "A equipa\nquer sair?")]
[InlineData("A equipa\nnão fala.", null, "A equipa\nnão fala.")]
[InlineData("As equipas\nprecisam de ajuda.", null, "As equipas\nprecisam de ajuda.")]
[InlineData("<i>Toda equipe\nprecisa de uma mascote.</i>", "Every team needs a mascot.",
"<i>Toda a equipa\nprecisa de uma mascote.</i>")]
[InlineData("TODA EQUIPE\nPRECISA DE UMA MASCOTE.", "Every team needs a mascot.",
"TODA A EQUIPA\nPRECISA DE UMA MASCOTE.")]
public void SubjectSurvivesSubtitleLineBreak(string source, string? english, string expected) =>
Check(source, english, expected);

[Theory]
[InlineData("Precisa de ajuda.", "You need help.", "Precisas de ajuda.")]
[InlineData("A equipa saiu.\nPrecisa de ajuda.", "You need help.", "A equipa saiu.\nPrecisas de ajuda.")]
[InlineData("-A equipa chegou.\n-Precisa de ajuda?", "Do you need help?",
"-A equipa chegou.\n-Precisas de ajuda?")]
[InlineData("Tu\nprecisa de ajuda.", "You need help.", "Tu\nprecisas de ajuda.")]
public void RealClauseAndDialogueBoundariesStillPermitTu(string source, string english, string expected) =>
Check(source, english, expected);

[Theory]
[InlineData("-Danny, ei.\n-Ei, Shelly, como vai?", "Danny, hey. Hey, Shelly, how you doing?",
"-Danny, ei.\n-Ei, Shelly, como vais?")]
[InlineData("Ei, Ana, como está?", "Hey, Ana, how are you?", "Ei, Ana, como estás?")]
[InlineData("Olá, João, como vai?", "Hello, João, how are you?", "Olá, João, como vais?")]
[InlineData("Oi, Ana, como tem estado?", "Hi, Ana, how have you been?", "Olá, Ana, como tens estado?")]
[InlineData("Ei, Ana, como anda?", "Hey, Ana, how are you doing?", "Ei, Ana, como andas?")]
[InlineData("Ei, pessoal.", "Hey, guys. Hello. Hi.", "Ei, pessoal.")]
[InlineData("Ei, rapazes!", "Hey, boys!", "Ei, rapazes!")]
[InlineData("Ei, pare!", "Hey, stop!", "Ei, para!")]
[InlineData("Ei, pessoal.", null, "Ei, pessoal.")]
[InlineData("Olha, pessoal.", "Look, guys.", "Olha, pessoal.")]
[InlineData("<i>Ei, Ana, como vai?</i>", "Hey, Ana, how are you?", "<i>Ei, Ana, como vais?</i>")]
[InlineData("EI, ANA, COMO VAI?", "Hey, Ana, how are you?", "EI, ANA, COMO VAIS?")]
public void GreetingsAreNotVisualCommands(string source, string? english, string expected) =>
Check(source, english, expected);

[Theory]
[InlineData("Ei, Shelly, como vai?", "Hey, Shelly, how is he doing?")]
[InlineData("Ei, Shelly, como vai?", null)]
[InlineData("Ei, Shelly, como vai?", "Hey, Maria, how are you?")]
[InlineData("Ei, Shelly, como vai o trabalho?", "Hey, Shelly, how is work?")]
[InlineData("Ei, Shelly, como vão?", "Hey, Shelly, how are you all?")]
[InlineData("Ei, Shelly, como vai?", "Hey, Shelly, how are you all?")]
[InlineData("Olá, doutor, como vai?", "Hello, Doctor, how are you?")]
public void UncertainAndFormalGreetingsRemainProtected(string source, string? english) =>
Check(source, english, source);

[Fact]
public void GreetingDoesNotOverrideExplicitFormalAddress()
{
const string source = "Ei, Shelly, como vai?";
var hint = ReferenceHint.FromText("Hey, Shelly, how are you?")!;
Assert.Equal(source, new PortugueseConverter().Convert(source, reference: hint with { FormalAddress = true }));
foreach (var options in new[] { new ConversionOptions(YouToTu: false),
new ConversionOptions(DisabledRules: "address") })
Assert.Equal(source, new PortugueseConverter(options).Convert(source, reference: hint));
}

[Fact]
public void ArticleOptionAndIgnoredPhrasesRemainAuthoritative()
{
const string source = "Toda equipa precisa de ajuda.";
Assert.Equal(source, new PortugueseConverter(new ConversionOptions(DisabledRules: "collective-articles"))
.Convert(source));
Assert.Equal(source, new PortugueseConverter(new ConversionOptions(Colloquial: false)).Convert(source));
var words = new PortugueseLocalWordList();
words.Ignored.Add("Ei, Shelly, como vai");
Assert.Equal("Ei, Shelly, como vai?", new PortugueseConverter(localWordList: words)
.Convert("Ei, Shelly, como vai?", reference: ReferenceHint.FromText("Hey, Shelly, how are you?")));
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public void ActualEpisodeCuesPreserveOriginalsAndTimes(bool sentenceContext)
{
var blocks = new[]
{
new SrtBlock { StartMs = 52886, EndMs = 54321, Text = "Toda equipe\nprecisa de uma mascote." },
new SrtBlock { StartMs = 102570, EndMs = 105740, Text = "-Danny, ei.\n-Ei, Shelly, como vai?" },
new SrtBlock { StartMs = 106674, EndMs = 107808, Text = "Ei, pessoal." },
};
var originals = blocks.Select(b => (b.Text, b.StartMs, b.EndMs)).ToArray();
var results = SubtitleConversion.Convert(blocks, new ConversionOptions(SentenceContext: sentenceContext),
english: new string?[] { "Every team needs a mascot.",
"WOMAN: Danny, hey. Hey, Shelly, how you doing?", "Hey, guys. Hello. Hi." });
Assert.Equal("Toda a equipa\nprecisa de uma mascote.", results[0].Text);
Assert.Equal("-Danny, ei.\n-Ei, Shelly, como vais?", results[1].Text);
Assert.Equal("Ei, pessoal.", results[2].Text);
Assert.Equal(originals, blocks.Select(b => (b.Text, b.StartMs, b.EndMs)).ToArray());
}

private static void Check(string source, string? english, string expected)
{
var converter = new PortugueseConverter();
var reference = ReferenceHint.FromText(english);
Assert.Equal(expected, converter.Convert(source, reference: reference));
Assert.Equal(expected, converter.Convert(expected, reference: reference));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public void SpokenInformationPreservesLiteralCompleteAndUnconfirmedRequests(stri
[InlineData("Eras meu vizinho de andar.", "We lived on the same floor.", "Vivíamos no mesmo andar.")]
[InlineData("VOCÊ É MEU VIZINHO DE ANDAR.", "We live on the same floor.", "VIVEMOS NO MESMO ANDAR.")]
[InlineData("<i>Você é meu vizinho de andar.</i>", "Hey, we live on the same floor.", "<i>Vivemos no mesmo andar.</i>")]
[InlineData("Ei, somos vizinhos da mesma rua!", "Hey, we live on the same street!", "Olha, vivemos na mesma rua!")]
[InlineData("Ei, somos vizinhos da mesma rua!", "Hey, we live on the same street!", "Ei, vivemos na mesma rua!")]
public void SharedResidenceRequiresMatchingEnglishMeaning(string source, string english, string expected)
{
var reference = ReferenceHint.FromText(english);
Expand Down
7 changes: 3 additions & 4 deletions se5/BrazilianToEuropeanPortuguese.Tests/ConverterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@
[InlineData("Sempre que chego.")]
[InlineData("Sempre posso ajudar.")]
[InlineData("Sempre estou a trabalhar.")]
[InlineData("Sempre me dizem isso.")]
[InlineData("Sempre fazer o melhor.")]
[InlineData("Quando eu estava a trabalhar.")]
[InlineData("Quando eu também estou a trabalhar.")]
Expand Down Expand Up @@ -377,8 +376,8 @@
[InlineData("Ela estava pagando mico.", "Ela estava a passar vergonha.")]
[InlineData("Ela ficou de bobeira.", "Ela ficou sem fazer nada.")]
[InlineData("Elas ficaram de bobeira.", "Elas ficaram sem fazer nada.")]
[InlineData("Ele fala abobrinha.", "Ele fala disparates.")]
[InlineData("Eles falavam abobrinhas.", "Eles falavam disparates.")]
[InlineData("Ele fala abobrinha.", "Ele diz disparates.")]
[InlineData("Eles falavam abobrinhas.", "Eles diziam disparates.")]
[InlineData("Tomei uma breja.", "Bebi uma cerveja.")]
[InlineData("Tomamos brejas.", "Bebemos cervejas.")]
[InlineData("Ele estava tomando uma breja.", "Ele estava a beber uma cerveja.")]
Expand Down Expand Up @@ -740,7 +739,7 @@
[InlineData("Policial Kevin Olivet atirou.", "Agente Kevin Olivet disparou.")]
[InlineData("Obrigada, policial.", "Obrigada, agente.")]
[InlineData("Não matei policial algum.", "Não matei nenhum polícia.")]
[InlineData("Foi uma ação policial.", "Foi uma ação policial.")]

Check warning on line 742 in se5/BrazilianToEuropeanPortuguese.Tests/ConverterTests.cs

View workflow job for this annotation

GitHub Actions / test

Theory method 'CorpusReviewRules' on test class 'ConverterTests' has InlineData duplicate(s). Remove redundant attribute(s) from the theory method. (https://xunit.net/xunit.analyzers/rules/xUnit1025)
[InlineData("Continuaremos procurando.", "Continuaremos a procurar.")]
[InlineData("Quatro custarão $ 200.", "Quatro custarão 200 dólares.")]
[InlineData("Ele pagou $ 10 mil.", "Ele pagou 10 mil dólares.")]
Expand Down Expand Up @@ -1099,7 +1098,7 @@
[InlineData("Os caquis e as berinjelas.", "Os dióspiros e as beringelas.")]
[InlineData("Calças caqui.", "Calças caqui.")]
[InlineData("Abobrinha grelhada.", "Curgete grelhada.")]
[InlineData("Falar abobrinha.", "Falar disparates.")]
[InlineData("Falar abobrinha.", "Dizer disparates.")]
[InlineData("A farinha de rosca.", "O pão ralado.")]
[InlineData("Leite integral.", "Leite gordo.")]
[InlineData("As balas de menta.", "Os rebuçados de menta.")]
Expand Down
Loading
Loading