blob: 072d41d52977035138dddad11dcf1a3dd9df5551 [file] [log] [blame]
using Lucene.Net.Analysis.Util;
using Lucene.Net.Diagnostics;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace Lucene.Net.Analysis.Core
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// <summary>
/// Sanity check some things about all factories,
/// we do our best to see if we can sanely initialize it with
/// no parameters and smoke test it, etc.
/// </summary>
// LUCENETODO: move this, TestRandomChains, and TestAllAnalyzersHaveFactories
// to an integration test module that sucks in all analysis modules.
// currently the only way to do this is via eclipse etc (LUCENE-3974)
[TestFixture]
public class TestFactories : BaseTokenStreamTestCase
{
[Test]
[Slow]
public virtual void Test()
{
foreach (string tokenizer in TokenizerFactory.AvailableTokenizers)
{
DoTestTokenizer(tokenizer);
}
foreach (string tokenFilter in TokenFilterFactory.AvailableTokenFilters)
{
DoTestTokenFilter(tokenFilter);
}
foreach (string charFilter in CharFilterFactory.AvailableCharFilters)
{
DoTestCharFilter(charFilter);
}
}
private void DoTestTokenizer(string tokenizer)
{
var factoryClazz = TokenizerFactory.LookupClass(tokenizer);
TokenizerFactory factory = (TokenizerFactory)Initialize(factoryClazz);
if (factory != null)
{
// we managed to fully create an instance. check a few more things:
// if it implements MultiTermAware, sanity check its impl
if (factory is IMultiTermAwareComponent multiTermAwareComponent)
{
AbstractAnalysisFactory mtc = multiTermAwareComponent.GetMultiTermComponent();
assertNotNull(mtc);
// its not ok to return e.g. a charfilter here: but a tokenizer could wrap a filter around it
assertFalse(mtc is CharFilterFactory);
}
// beast it just a little, it shouldnt throw exceptions:
// (it should have thrown them in initialize)
CheckRandomData(Random, new FactoryAnalyzer(factory, null, null), 100, 20, false, false);
}
}
private void DoTestTokenFilter(string tokenfilter)
{
var factoryClazz = TokenFilterFactory.LookupClass(tokenfilter);
TokenFilterFactory factory = (TokenFilterFactory)Initialize(factoryClazz);
if (factory != null)
{
// we managed to fully create an instance. check a few more things:
// if it implements MultiTermAware, sanity check its impl
if (factory is IMultiTermAwareComponent multiTermAwareComponent)
{
AbstractAnalysisFactory mtc = multiTermAwareComponent.GetMultiTermComponent();
assertNotNull(mtc);
// its not ok to return a charfilter or tokenizer here, this makes no sense
assertTrue(mtc is TokenFilterFactory);
}
// beast it just a little, it shouldnt throw exceptions:
// (it should have thrown them in initialize)
CheckRandomData(Random, new FactoryAnalyzer(assertingTokenizer, factory, null), 100, 20, false, false);
}
}
private void DoTestCharFilter(string charfilter)
{
var factoryClazz = CharFilterFactory.LookupClass(charfilter);
CharFilterFactory factory = (CharFilterFactory)Initialize(factoryClazz);
if (factory != null)
{
// we managed to fully create an instance. check a few more things:
// if it implements MultiTermAware, sanity check its impl
if (factory is IMultiTermAwareComponent multiTermAwareComponent)
{
AbstractAnalysisFactory mtc = multiTermAwareComponent.GetMultiTermComponent();
assertNotNull(mtc);
// its not ok to return a tokenizer or tokenfilter here, this makes no sense
assertTrue(mtc is CharFilterFactory);
}
// beast it just a little, it shouldnt throw exceptions:
// (it should have thrown them in initialize)
CheckRandomData(Random, new FactoryAnalyzer(assertingTokenizer, null, factory), 100, 20, false, false);
}
}
// LUCENENET specific - remove overhead of converting to a string on each loop
private static readonly string TEST_VERSION_CURRENT_STRING = TEST_VERSION_CURRENT.ToString();
/// <summary>
/// tries to initialize a factory with no arguments </summary>
private static AbstractAnalysisFactory Initialize(Type factoryClazz) // LUCENENET: CA1822: Mark members as static
{
IDictionary<string, string> args =
new Dictionary<string, string> { ["luceneMatchVersion"] = TEST_VERSION_CURRENT_STRING };
ConstructorInfo ctor;
try
{
ctor = factoryClazz.GetConstructor(new Type[] { typeof(IDictionary<string, string>) });
}
catch (Exception e)
{
throw new Exception("factory '" + factoryClazz + "' does not have a proper ctor!", e);
}
AbstractAnalysisFactory factory = null;
try
{
factory = (AbstractAnalysisFactory)ctor.Invoke(new object[] { args });
}
catch (TypeInitializationException e)
{
throw new Exception(e.Message, e);
}
catch (MethodAccessException e)
{
throw new Exception(e.Message, e);
}
catch (TargetInvocationException e)
{
if (e.InnerException is ArgumentException)
{
// its ok if we dont provide the right parameters to throw this
return null;
}
}
if (factory is IResourceLoaderAware aware)
{
try
{
aware.Inform(new StringMockResourceLoader(""));
}
#pragma warning disable CA1031 // Do not catch general exception types
catch (IOException)
{
// its ok if the right files arent available or whatever to throw this
}
catch (ArgumentException)
{
// is this ok? I guess so
}
#pragma warning restore CA1031 // Do not catch general exception types
}
return factory;
}
// some silly classes just so we can use checkRandomData
private readonly TokenizerFactory assertingTokenizer = new AnonymousInnerClassHelperTokenizerFactory(new Dictionary<string, string>());
private sealed class AnonymousInnerClassHelperTokenizerFactory : TokenizerFactory
{
public AnonymousInnerClassHelperTokenizerFactory(IDictionary<string, string> java) : base(java)
{
}
public override Tokenizer Create(AttributeSource.AttributeFactory factory, TextReader input)
{
return new MockTokenizer(factory, input);
}
}
private sealed class FactoryAnalyzer : Analyzer
{
internal readonly TokenizerFactory tokenizer;
internal readonly CharFilterFactory charFilter;
internal readonly TokenFilterFactory tokenfilter;
internal FactoryAnalyzer(TokenizerFactory tokenizer, TokenFilterFactory tokenfilter, CharFilterFactory charFilter)
{
if (Debugging.AssertsEnabled) Debugging.Assert(tokenizer != null);
this.tokenizer = tokenizer;
this.charFilter = charFilter;
this.tokenfilter = tokenfilter;
}
protected internal override TokenStreamComponents CreateComponents(string fieldName, TextReader reader)
{
Tokenizer tf = tokenizer.Create(reader);
if (tokenfilter != null)
{
return new TokenStreamComponents(tf, tokenfilter.Create(tf));
}
else
{
return new TokenStreamComponents(tf);
}
}
protected internal override TextReader InitReader(string fieldName, TextReader reader)
{
if (charFilter != null)
{
return charFilter.Create(reader);
}
else
{
return reader;
}
}
}
}
}