Added: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsTypesMap.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsTypesMap.java?rev=991931&view=auto ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsTypesMap.java (added) +++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsTypesMap.java Thu Sep 2 13:43:50 2010 @@ -0,0 +1,275 @@ +/* + * 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. + */ + +package org.apache.uima.analysis_engine.impl; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * This object holds the set of RsTypes for a result spec + * There is one instance of this per ResultSpecification_impl + */ +public class RsTypesMap implements Iterable<RsType> { + + private final Map<String, RsType> types; + + RsTypesMap() { + types = new HashMap<String, RsType>(); + } + + /** + * cloning constructor - clones its arg + * @param src + */ + RsTypesMap(RsTypesMap src) { + types = new HashMap<String, RsType>(src.types); + for (Map.Entry<String, RsType> e : types.entrySet()) { + e.setValue(new RsType(e.getValue())); // copy + } + } + + /** + * add a type (not a type:feat) + * @param typeName + * @param isAllFeat + * @param languages + * @param replace + */ + void add(String typeName, boolean isAllFeat, String[] languages, boolean replace) { + RsType t = types.get(typeName); + if (null == t) { + t = new RsType(typeName); + types.put(typeName, t); + } + if (isAllFeat) { + if (!t.isAllFeatures) { + replace = true; // if setting for the 1st time, replace the x-unspec which is the default + } + t.isAllFeatures = true; + t.languagesAllFeat = addLanguages(t.languagesAllFeat, languages, replace); + } else { + if (!t.isSpecified) { + replace = true; + } + t.isSpecified = true; + t.languagesNotAllFeat = addLanguages(t.languagesNotAllFeat, languages, replace); + } + } + + void add(String typeName, boolean isAllFeat, RsLangs rslangs, boolean replace) { + RsType t = types.get(typeName); + if (null == t) { + t = new RsType(typeName); + types.put(typeName, t); + } + if (isAllFeat) { + if (!t.isAllFeatures) { + replace = true; + } + t.isAllFeatures = true; + t.languagesAllFeat = addLanguages(t.languagesAllFeat, rslangs, replace); + } else { + if (!t.isSpecified) { + replace = true; + } + t.isSpecified = true; + t.languagesNotAllFeat = addLanguages(t.languagesNotAllFeat, rslangs, replace); + } + } + + + /** + * add a feature (not a plain type) + * If feature exists, augments (union) its languages or replaces it + * @param typeName + * @param featName + * @param languages + * @param replace + */ + + void add(String typeName, String shortFeatName, Object rslangs, boolean replace) { + RsType t = types.get(typeName); + if (null == t) { + t = new RsType(typeName); + types.put(typeName, t); + } + RsFeats feats = t.features; + RsFeat feat = null; + if (null == feats) { + feats = new RsFeats(); + t.features = feats; + } else { + feat = feats.get(shortFeatName); + } + if (null == feat) { + feats.add(shortFeatName, rslangs); + } else { + feat.languages = addLanguages(feat.languages, rslangs, replace); + } + } + + RsLangs addLanguages(RsLangs existing, Object langs, boolean replace) { + String[] saLangs = null; + RsLangs rsLangs = null; + if (langs instanceof String[]) { + saLangs = (String[])langs; + } else { + rsLangs = (RsLangs)langs; + } + + boolean noLangs = (null == langs) ? true + : (null != saLangs) ? (0 == ((String[])langs).length) + : RsLangs.isEmpty(rsLangs); + + if (noLangs) { + if (replace) { + return null; + } + return existing; + } + if (null == existing && !replace) { // existing is x-unspecified + return null; // subsumes everything + } + if (replace) { + if (saLangs != null) { + return RsLangs.createOrNull(saLangs); + } else { + rsLangs.setShared(); + return rsLangs; + } + } + // not replace, and existing + existing = (null != saLangs) ? RsLangs.addAll(existing, saLangs) + : RsLangs.addAll(existing, rsLangs); + return existing; + } + + RsLangs addLanguages(RsLangs existing, RsLangs rslangs, boolean replace) { + if (RsLangs.isEmpty(rslangs)) { + if (replace) { + return null; + } + return existing; + } + if (null == existing && !replace) { // existing is x-unspecified + return null; + } + if (replace) { + rslangs.setShared(); + return rslangs; + } + existing = RsLangs.addAll(existing, rslangs); + return existing; + } + + + /** + * Remove a type, regardless of languages + * NOTE: doesn't remove type:feature entries associated with that type + * @param type + */ + void remove(String type) { + RsType t = types.get(type); + if (null != t) { + if (null == t.features || t.features.size() == 0) { + types.remove(type); + return; + } + t.isAllFeatures = false; + t.isSpecified = false; + t.languagesAllFeat = null; + t.languagesNotAllFeat = null; + } + } + + /** + * remove a feature, regardless of languages + * If all features are removed, null out the rsFeats slot. + * If all features are removed, and no type instance, remove the type also. + * @param typeName + * @param feature Short Name + */ + void remove(String type, String feature) { + RsType t = types.get(type); + if (null != t) { + if (null != t.features) { + t.features.remove(type, feature); + if (0 == t.features.size()) { + t.features = null; + if (!t.isAllFeatures && !t.isSpecified) { + types.remove(type); + } + } + } + } + } + + RsType getRsType(String typeName) { + return types.get(typeName); + } + + RsFeat get(String typeName, String shortFeatName) { + RsType t = types.get(typeName); + if (t == null || t.features == null) { + return null; + } + return t.features.get(shortFeatName); + } + + int nbrOfTypes() { + return types.size(); + } + + public Iterator<RsType> iterator() { + return types.values().iterator(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((types == null) ? 0 : types.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + RsTypesMap other = (RsTypesMap) obj; + if (types == null) { + if (other.types != null) { + return false; + } + } else if (!types.equals(other.types)) { + return false; + } + return true; + } + +}
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/TypeOrFeature_impl.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/TypeOrFeature_impl.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/TypeOrFeature_impl.java (original) +++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/TypeOrFeature_impl.java Thu Sep 2 13:43:50 2010 @@ -161,4 +161,42 @@ public class TypeOrFeature_impl extends return new XmlizationInfo(null, null); // this object has custom XMLization routines } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + (mAllAnnotatorFeatures ? 1231 : 1237); + result = prime * result + ((mName == null) ? 0 : mName.hashCode()); + result = prime * result + (mType ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TypeOrFeature_impl other = (TypeOrFeature_impl) obj; + if (mAllAnnotatorFeatures != other.mAllAnnotatorFeatures) { + return false; + } + if (mName == null) { + if (other.mName != null) { + return false; + } + } else if (!mName.equals(other.mName)) { + return false; + } + if (mType != other.mType) { + return false; + } + return true; + } } Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/compatibility/AnnotatorAdapter.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/compatibility/AnnotatorAdapter.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/compatibility/AnnotatorAdapter.java (original) +++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/compatibility/AnnotatorAdapter.java Thu Sep 2 13:43:50 2010 @@ -168,10 +168,14 @@ public class AnnotatorAdapter implements rs = UIMAFramework.getResourceSpecifierFactory().createResultSpecification(); rs.setResultTypesAndFeatures(tofs); } else { - // special case: if annotator lists no outputs for this language, all it - // with all possible outputs. This is mainly for backwards compatibility, + // special case: if annotator lists no outputs for this language, call it + // with the actual result spec, set up by language. + + // An earlier version of this comment erroneously asserted + // "call for all possible outputs. + // This is mainly for backwards compatibility, // but here's a rationalization: the FlowController wants us to invoke the - // annotator, so calling it with no outputs doesn't really make sense. + // annotator, so calling it with no outputs doesn't really make sense." rs = mDefaultResultSpecification; } mLanguageToResultSpecMap.put(language, rs); Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java (original) +++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java Thu Sep 2 13:43:50 2010 @@ -125,7 +125,7 @@ public class TypeSystemImpl implements T // A map from the full space of feature names to feature codes. A feature // may - // be know by many different names (one for each subtype of the type the + // be known by many different names (one for each subtype of the type the // feature is declared on). private StringToIntMap featureMap; @@ -808,7 +808,7 @@ public class TypeSystemImpl implements T // We have to copy the array since we don't have const. return (this.approp.get(type)).toArrayCopy(); } - + /** * @return An offset <code>>0</code> if <code>feat</code> exists; <code>0</code>, else. */ Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java (original) +++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java Thu Sep 2 13:43:50 2010 @@ -325,11 +325,17 @@ public class AnalysisEngine_implTest ext public void testProcess() throws Exception { try { // test simple primitive TextAnalysisEngine (using TestAnnotator class) + // This test should work with or without a type system description AnalysisEngineDescription primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setPrimitive(true); primitiveDesc .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); primitiveDesc.getMetaData().setName("Test Primitive TAE"); + +// TypeSystemDescription tsd = new TypeSystemDescription_impl(); +// tsd.addType("NamedEntity", "", "uima.tcas.Annotation"); +// tsd.addType("DocumentStructure", "", "uima.cas.TOP"); +// primitiveDesc.getAnalysisEngineMetaData().setTypeSystem(tsd); Capability cap = new Capability_impl(); cap.addOutputType("NamedEntity", true); cap.addOutputType("DocumentStructure", true); @@ -337,6 +343,23 @@ public class AnalysisEngine_implTest ext primitiveDesc.getAnalysisEngineMetaData().setCapabilities(caps); _testProcess(primitiveDesc); + primitiveDesc = new AnalysisEngineDescription_impl(); + primitiveDesc.setPrimitive(true); + primitiveDesc + .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); + primitiveDesc.getMetaData().setName("Test Primitive TAE"); + + TypeSystemDescription tsd = new TypeSystemDescription_impl(); + tsd.addType("NamedEntity", "", "uima.tcas.Annotation"); + tsd.addType("DocumentStructure", "", "uima.cas.TOP"); + primitiveDesc.getAnalysisEngineMetaData().setTypeSystem(tsd); + cap = new Capability_impl(); + cap.addOutputType("NamedEntity", true); + cap.addOutputType("DocumentStructure", true); + caps = new Capability[] {cap}; + primitiveDesc.getAnalysisEngineMetaData().setCapabilities(caps); + _testProcess(primitiveDesc); + // test simple aggregate TextAnalysisEngine (again using TestAnnotator class) AnalysisEngineDescription aggDesc = new AnalysisEngineDescription_impl(); aggDesc.setPrimitive(false); @@ -409,10 +432,18 @@ public class AnalysisEngine_implTest ext // process(CAS,ResultSpecification) ResultSpecification resultSpec = new ResultSpecification_impl(tcas.getTypeSystem()); - resultSpec.addResultType("NamedEntity", true); + resultSpec.addResultType("NamedEntity", true); // includes subtypes Person, Sentence, Place, Paragraph + // sets for lang = x-unspecified ResultSpecification expectedLastResultSpec = new ResultSpecification_impl(tcas.getTypeSystem()); - expectedLastResultSpec.addResultType("NamedEntity", true, languages); + // interesting case: + // Because the annotator extends a UIMA Version 1.x impl class, we go thru an "adapter" interface + // which normally replaces the result spec with one that is based on language x-unspecified + // (guessing because version 1.x didn't properly support languages) + // However there's an exception to this: if the result spec would have no types or features + // for the language in the CAS, the original result spec is used, rather than a + // new one based on x-unspecified. + expectedLastResultSpec.addResultType("NamedEntity", true, languages); _testProcessInner(ae, tcas, resultSpec, expectedLastResultSpec); } @@ -429,9 +460,10 @@ public class AnalysisEngine_implTest ext // Test each form of the process method. When TestAnnotator executes, it // stores in static fields the document text and the ResultSpecification. - // We use thse to make sure the information propogates correctly to the annotator. + // We use these to make sure the information propagates correctly to the annotator. // process(CAS) + // Calls with the Result spec set to default to that of the outer annotator output capabilities tcas.setDocumentText("new test"); ae.process(tcas); assertEquals("new test", TestAnnotator.lastDocument); Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java (original) +++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java Thu Sep 2 13:43:50 2010 @@ -30,6 +30,10 @@ import org.apache.uima.analysis_engine.A import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.cas.CAS; +import org.apache.uima.cas.Feature; +import org.apache.uima.cas.Type; +import org.apache.uima.cas.admin.TypeSystemMgr; +import org.apache.uima.cas.impl.TypeSystemImpl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; @@ -43,6 +47,14 @@ public class ResultSpecTest extends Test private static final String PTBR = "pt-br"; private static final String I = "I"; // split designator + // types + + private static final TypeSystemMgr ts = new TypeSystemImpl(); + private static final Type t1 = ts.addType("T1", ts.getTopType()); + private static final Feature f1 = ts.addFeature("F1", t1, t1); + private static final Feature f1a = ts.addFeature("F1a", t1, t1); + static {ts.commit();}; + /** * Tests for https://issues.apache.org/jira/browse/UIMA-1840 */ @@ -86,16 +98,16 @@ public class ResultSpecTest extends Test String[] rs2langs = rs2List.toArray(new String[rs2List.size()]); String[] explangs = expList.toArray(new String[expList.size()]); - ResultSpecification_impl rs1 = new ResultSpecification_impl(); - ResultSpecification_impl rs2 = new ResultSpecification_impl(); - ResultSpecification_impl rsE = new ResultSpecification_impl(); //expected + ResultSpecification_impl rs1 = new ResultSpecification_impl(ts); + ResultSpecification_impl rs2 = new ResultSpecification_impl(ts); + ResultSpecification_impl rsE = new ResultSpecification_impl(ts); //expected addResultTypeOneAtATime(rs1, rs1langs); addResultTypeOneAtATime(rs2, rs2langs); addResultTypeOneAtATime(rsE, explangs); - ResultSpecification_impl rsQ = ResultSpecification_impl.intersect(rs1, rs2); - assertTrue(rsQ.equals(rsE)); + ResultSpecification_impl rsQ = rs1.intersect(rs2); + assertEquals(rsQ, rsE); } // we do this to avoid language normalization from collapsing x-unspecified @@ -120,13 +132,13 @@ public class ResultSpecTest extends Test PrimitiveAnalysisEngine_impl ae = (PrimitiveAnalysisEngine_impl) UIMAFramework .produceAnalysisEngine(aeDesc); CAS cas = ae.newCAS(); - ResultSpecification resultSpec = new ResultSpecification_impl(); + ResultSpecification_impl resultSpec = new ResultSpecification_impl(); resultSpec.addResultType("uima.tt.TokenLikeAnnotation", true); resultSpec.setTypeSystem(cas.getTypeSystem()); ResultSpecification_impl rs2 = new ResultSpecification_impl(cas.getTypeSystem()); rs2.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); - ResultSpecification acResultSpec = ResultSpecification_impl.intersect(resultSpec, rs2); + ResultSpecification acResultSpec = resultSpec.intersect(rs2); assertTrue(acResultSpec.containsType("uima.tt.TokenAnnotation")); assertFalse(acResultSpec.containsType("uima.tt.SentenceAnnotation")); assertFalse(acResultSpec.containsType("uima.tt.Lemma")); @@ -143,12 +155,12 @@ public class ResultSpecTest extends Test PrimitiveAnalysisEngine_impl ae = (PrimitiveAnalysisEngine_impl) UIMAFramework .produceAnalysisEngine(aeDesc); CAS cas = ae.newCAS(); - ResultSpecification resultSpec = new ResultSpecification_impl(cas.getTypeSystem()); + ResultSpecification_impl resultSpec = new ResultSpecification_impl(cas.getTypeSystem()); resultSpec.addResultType("uima.tcas.Annotation", true); ResultSpecification_impl rs2 = new ResultSpecification_impl(cas.getTypeSystem()); rs2.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); - ResultSpecification acResultSpec = ResultSpecification_impl.intersect(resultSpec, rs2); + ResultSpecification acResultSpec = resultSpec.intersect(rs2); assertTrue(acResultSpec.containsType("uima.tt.TokenAnnotation")); assertTrue(acResultSpec.containsType("uima.tt.SentenceAnnotation")); assertFalse(acResultSpec.containsType("uima.tt.Lemma")); Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecWithTypeSystemTest.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecWithTypeSystemTest.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecWithTypeSystemTest.java (original) +++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecWithTypeSystemTest.java Thu Sep 2 13:43:50 2010 @@ -110,11 +110,11 @@ public class ResultSpecWithTypeSystemTes check(tofT2, K.NotContain, f1); check(tofT2allFeat, K.Contains, f2); check(tofT2, K.NotContain, f2); -// check(tofT1allFeat, K.NotContain, f2); // because allFeat on T1 doesn't include F2 which is only introduced on T2 + check(tofT1allFeat, K.NotContain, f2); // because allFeat on T1 doesn't include F2 which is only introduced on T2 check(tofT2F1, K.NotContain, f1); // feature spec'd for subtype check(tofT2F1, K.Contains, "T2:F1"); -// check(tofT2F1, K.Contains, "T3:F1"); // oops, features not inheriting -// check(tofT1allFeat, K.NotContain, f4); // because allFeat on T1 doesn't include F4 which is only introduced on T4 + check(tofT2F1, K.Contains, "T3:F1"); // oops, features not inheriting + check(tofT1allFeat, K.NotContain, f4); // because allFeat on T1 doesn't include F4 which is only introduced on T4 check(tofT2allFeat, K.NotContain, f4); check(tofT1, K.NotContain, f4); } @@ -131,7 +131,7 @@ public class ResultSpecWithTypeSystemTes check(tofT1, EN, K.Contains, t2, EN_US); TofLs[] tofls = aT(tofT1allFeat, X, tofT2, X); -// check(tofls, K.NotContain, f2); // bad + check(tofls, K.NotContain, f2); // bad } @@ -142,12 +142,12 @@ public class ResultSpecWithTypeSystemTes check(tofT1allFeat, EN, K.Contains, f1, EN_US); TofLs[] tofls =aT(tofT1allFeat, X, tofT2, EN); -// check(tofls, K.NotContain, f2, X); // because f2 not in T1 -// check(tofls, K.NotContain, f2, EN); -// check(tofls, K.NotContain, f2, EN_US); + check(tofls, K.NotContain, f2, X); + check(tofls, K.NotContain, f2, EN); + check(tofls, K.NotContain, f2, EN_US); tofls =aT(tofT1allFeat, X, tofF2, EN); -// check(tofls, K.NotContain, f2, X); + check(tofls, K.NotContain, f2, X); check(tofls, K.Contains, f2, EN); check(tofls, K.Contains, f2, EN_US); @@ -163,8 +163,8 @@ public class ResultSpecWithTypeSystemTes tofls = aT(tofT1allFeat, EN_US, tofT2, EN); check(tofls, K.NotContain, f2, X); -// check(tofls, K.NotContain, f2, EN); -// check(tofls, K.NotContain, f2, EN_US); + check(tofls, K.NotContain, f2, EN); //broken + check(tofls, K.NotContain, f2, EN_US); tofls = aT(tofT1, X, tofT2, EN_US); check(tofls, K.NotContain, f2, X); @@ -178,9 +178,9 @@ public class ResultSpecWithTypeSystemTes tofls = aT(tofF1, EN, tofF2, EN_US); check(tofls, K.NotContain, "T2:F1", X); -// check(tofls, K.Contains, "T2:F1", EN); // because feats not inheriting from supers -// check(tofls, K.Contains, "T2:F1", EN_US); - check(tofls, K.NotContain, f2, EN); + check(tofls, K.Contains, "T2:F1", EN); + check(tofls, K.Contains, "T2:F1", EN_US); + check(tofls, K.NotContain, f2, EN); //broken check(tofls, K.Contains, f2, EN_US);
