예제 #1
0
 public MultiTraitContext()
 {
     _empty = new MultiTrait( this );
     _traits = new ConcurrentDictionary<string, MultiTrait>( StringComparer.Ordinal );
     _traits[ String.Empty ] = _empty;
     _creationLock = new Object();
 }
예제 #2
0
파일: Traits.cs 프로젝트: Paty-B/ck-core
        public void ContainsTraits()
        {
            MultiTrait m = Context.FindOrCreate("Beta+Alpha+Fridge+Combo");

            Assert.That(Context.EmptyTrait.ContainsAll(Context.EmptyTrait), "Empty is contained by definition in itself.");
            Assert.That(m.ContainsAll(Context.EmptyTrait), "Empty is contained by definition.");
            Assert.That(m.ContainsAll(Context.FindOrCreate("Fridge+Alpha")));
            Assert.That(m.ContainsAll(Context.FindOrCreate("Fridge")));
            Assert.That(m.ContainsAll(Context.FindOrCreate("Fridge+Alpha+Combo")));
            Assert.That(m.ContainsAll(Context.FindOrCreate("Fridge+Alpha+Beta+Combo")));
            Assert.That(!m.ContainsAll(Context.FindOrCreate("Fridge+Lol")));
            Assert.That(!m.ContainsAll(Context.FindOrCreate("Murfn")));
            Assert.That(!m.ContainsAll(Context.FindOrCreate("Fridge+Alpha+Combo+Lol")));
            Assert.That(!m.ContainsAll(Context.FindOrCreate("Lol+Fridge+Alpha+Beta+Combo")));

            Assert.That(m.ContainsOne(Context.FindOrCreate("Fridge+Alpha")));
            Assert.That(m.ContainsOne(Context.FindOrCreate("Nimp+Fridge+Mourfn")));
            Assert.That(m.ContainsOne(Context.FindOrCreate("Fridge+Alpha+Combo+Albert")));
            Assert.That(m.ContainsOne(Context.FindOrCreate("ZZF+AAlp+BBeBe+Combo")));
            Assert.That(!m.ContainsOne(Context.FindOrCreate("AFridge+ALol")));
            Assert.That(!m.ContainsOne(Context.FindOrCreate("Murfn")));
            Assert.That(!m.ContainsOne(Context.FindOrCreate("QF+QA+QC+QL")));
            Assert.That(!m.ContainsOne(Context.EmptyTrait), "Empty is NOT contained 'ONE' since EmptyTrait.AtomicTraits.Count == 0...");
            Assert.That(!Context.EmptyTrait.ContainsOne(Context.EmptyTrait), "Empty is NOT contained 'ONE' in itself.");
        }
예제 #3
0
파일: Traits.cs 프로젝트: Paty-B/ck-core
        public void AddTraits()
        {
            MultiTrait m1 = Context.FindOrCreate("Beta+Alpha+Fridge+Combo");
            MultiTrait m2 = Context.FindOrCreate("Xtra+Combo+Another+Fridge+Alt");

            Assert.That(m1.Add(m2).ToString() == "Alpha+Alt+Another+Beta+Combo+Fridge+Xtra", "Works as expected :-)");
            Assert.That(m2.Add(m1) == m1.Add(m2), "Same in both calls.");
        }
예제 #4
0
파일: Traits.cs 프로젝트: Paty-B/ck-core
        public void FindIfAllExist()
        {
            MultiTrait m = Context.FindOrCreate("Alpha+Beta+Combo+Fridge");

            Assert.That(Context.FindIfAllExist(""), Is.EqualTo(Context.EmptyTrait));
            Assert.That(Context.FindIfAllExist("bo"), Is.Null);
            Assert.That(Context.FindIfAllExist("Alpha"), Is.EqualTo(Context.FindOrCreate("Alpha")));
            Assert.That(Context.FindIfAllExist("bo+pha"), Is.Null);
            Assert.That(Context.FindIfAllExist("Fridge+Combo+Alpha+Beta"), Is.SameAs(m));
        }
예제 #5
0
파일: Traits.cs 프로젝트: Paty-B/ck-core
        public void RemoveTraits()
        {
            MultiTrait m1 = Context.FindOrCreate("Beta+Alpha+Fridge+Combo");
            MultiTrait m2 = Context.FindOrCreate("Xtra+Combo+Another+Fridge+Alt");

            Assert.That(m1.Remove(m2).ToString() == "Alpha+Beta", "Works as expected :-)");
            Assert.That(m2.Remove(m1).ToString() == "Alt+Another+Xtra", "Works as expected...");

            Assert.That(m2.Remove(Context.EmptyTrait) == m2 && m1.Remove(Context.EmptyTrait) == m1, "Removing empty does nothing.");
        }
예제 #6
0
파일: Traits.cs 프로젝트: Paty-B/ck-core
        public void IntersectTraits()
        {
            MultiTrait m1 = Context.FindOrCreate("Beta+Alpha+Fridge+Combo");
            MultiTrait m2 = Context.FindOrCreate("Xtra+Combo+Another+Fridge+Alt");

            Assert.That(m1.Intersect(m2).ToString() == "Combo+Fridge", "Works as expected :-)");
            Assert.That(m2.Intersect(m1) == m1.Intersect(m2), "Same object in both calls.");

            Assert.That(m2.Intersect(Context.EmptyTrait) == Context.EmptyTrait, "Intersecting empty gives empty.");
        }
예제 #7
0
파일: Traits.cs 프로젝트: Paty-B/ck-core
 public void Fallbacks()
 {
     {
         MultiTrait m = Context.FindOrCreate("");
         IReadOnlyList <MultiTrait> f = m.Fallbacks;
         Assert.That(f.Count == 1);
         Assert.That(f[0].ToString() == "");
     }
     {
         MultiTrait m = Context.FindOrCreate("Alpha");
         IReadOnlyList <MultiTrait> f = m.Fallbacks;
         Assert.That(f.Count == 1);
         Assert.That(f[0].ToString() == "");
     }
     {
         MultiTrait m = Context.FindOrCreate("Alpha+Beta");
         IReadOnlyList <MultiTrait> f = m.Fallbacks;
         Assert.That(f.Count == 3);
         Assert.That(f[0].ToString() == "Alpha");
         Assert.That(f[1].ToString() == "Beta");
         Assert.That(f[2].ToString() == "");
     }
     {
         MultiTrait m = Context.FindOrCreate("Alpha+Beta+Combo");
         IReadOnlyList <MultiTrait> f = m.Fallbacks;
         Assert.That(f.Count == 7);
         Assert.That(f[0].ToString() == "Alpha+Beta");
         Assert.That(f[1].ToString() == "Alpha+Combo");
         Assert.That(f[2].ToString() == "Beta+Combo");
         Assert.That(f[3].ToString() == "Alpha");
         Assert.That(f[4].ToString() == "Beta");
         Assert.That(f[5].ToString() == "Combo");
         Assert.That(f[6].ToString() == "");
     }
     {
         MultiTrait m = Context.FindOrCreate("Alpha+Beta+Combo+Fridge");
         IReadOnlyList <MultiTrait> f = m.Fallbacks;
         Assert.That(f.Count == 15);
         Assert.That(f[0].ToString() == "Alpha+Beta+Combo");
         Assert.That(f[1].ToString() == "Alpha+Beta+Fridge");
         Assert.That(f[2].ToString() == "Alpha+Combo+Fridge");
         Assert.That(f[3].ToString() == "Beta+Combo+Fridge");
         Assert.That(f[4].ToString() == "Alpha+Beta");
         Assert.That(f[5].ToString() == "Alpha+Combo");
         Assert.That(f[6].ToString() == "Alpha+Fridge");
         Assert.That(f[7].ToString() == "Beta+Combo");
         Assert.That(f[8].ToString() == "Beta+Fridge");
         Assert.That(f[9].ToString() == "Combo+Fridge");
         Assert.That(f[10].ToString() == "Alpha");
         Assert.That(f[11].ToString() == "Beta");
         Assert.That(f[12].ToString() == "Combo");
         Assert.That(f[13].ToString() == "Fridge");
         Assert.That(f[14].ToString() == "");
     }
 }
예제 #8
0
파일: Traits.cs 프로젝트: Paty-B/ck-core
        public void OneAtomicTrait()
        {
            MultiTrait m = Context.FindOrCreate("Alpha");

            Assert.That(m.IsAtomic && m.AtomicTraits.Count == 1, "Not a combined one.");
            Assert.That(m.AtomicTraits[0] == m, "Atomic traits are self-contained.");

            Assert.That(Context.FindOrCreate(" \t Alpha\r\n  ") == m, "Strings are trimmed.");
            Assert.That(Context.FindOrCreate("+ \t Alpha+") == m, "Leading and trailing '+' are ignored.");
            Assert.That(Context.FindOrCreate("+Alpha+++") == m, "Multiple + are ignored");
            Assert.That(Context.FindOrCreate("++ Alpha +++ \r\n  + \t +") == m, "Multiple empty strings are ignored.");
        }
예제 #9
0
파일: Traits.cs 프로젝트: Paty-B/ck-core
        public void ToggleTraits()
        {
            MultiTrait m = Context.FindOrCreate("Beta+Alpha+Fridge+Combo");

            Assert.That(m.Toggle(Context.FindOrCreate("Beta")).ToString() == "Alpha+Combo+Fridge");
            Assert.That(m.Toggle(Context.FindOrCreate("Fridge+Combo")).ToString() == "Alpha+Beta");
            Assert.That(m.Toggle(Context.FindOrCreate("Beta+Fridge+Combo")).ToString() == "Alpha");
            Assert.That(m.Toggle(Context.FindOrCreate("Beta+Fridge+Combo+Alpha")).ToString() == "");

            Assert.That(m.Toggle(Context.FindOrCreate("")).ToString() == "Alpha+Beta+Combo+Fridge");
            Assert.That(m.Toggle(Context.FindOrCreate("Xtra")).ToString() == "Alpha+Beta+Combo+Fridge+Xtra");
            Assert.That(m.Toggle(Context.FindOrCreate("Alpha+Xtra")).ToString() == "Beta+Combo+Fridge+Xtra");
            Assert.That(m.Toggle(Context.FindOrCreate("Zenon+Alpha+Xtra+Fridge")).ToString() == "Beta+Combo+Xtra+Zenon");
        }
예제 #10
0
파일: Traits.cs 프로젝트: Paty-B/ck-core
        public void EmptyOne()
        {
            MultiTrait m = Context.EmptyTrait;

            Assert.That(m.ToString() == String.Empty, "Empty trait is the empty string.");
            Assert.That(m.IsAtomic, "Empty trait is considered as atomic.");
            Assert.That(m.AtomicTraits.Count == 0, "Empty trait has no atomic traits inside.");

            Assert.That(Context.FindOrCreate("") == m, "Obtaining empty string gives the empty trait.");
            Assert.That(Context.FindOrCreate("+") == m, "Obtaining '+' gives the empty trait.");
            Assert.That(Context.FindOrCreate(" \t \r\n  ") == m, "Strings are trimmed.");
            Assert.That(Context.FindOrCreate("+ \t +") == m, "Leading and trailing '+' are ignored.");
            Assert.That(Context.FindOrCreate("++++") == m, "Multiple + are ignored");
            Assert.That(Context.FindOrCreate("++  +++ \r\n  + \t +") == m, "Multiple empty strings leads to empty trait.");
        }
예제 #11
0
파일: Traits.cs 프로젝트: Paty-B/ck-core
        public void FindClosest()
        {
            MultiTrait m = Context.FindOrCreate("Alpha+Beta+Combo+Fridge");

            Assert.That(ClosestString(m, ""), Is.EqualTo(String.Empty));
            Assert.That(ClosestString(m, "POP+AZAZ", "LKL+ZEU"), Is.EqualTo(null));
            Assert.That(ClosestString(m, "POP+AZAZ", "LKL+ZEU", ""), Is.EqualTo(String.Empty));

            Assert.That(Context.FindIfAllExist("POP"), Is.Null, "No side effects if trait does not exist.");

            Assert.That(ClosestString(m, "Alpha+Beta", "Combo+Fridge", "Beta+Combo+Fridge", "Alpha+Beta+Combo+Fridge"), Is.EqualTo("Alpha+Beta+Combo+Fridge"));
            Assert.That(ClosestString(m, "Alpha+Beta", "Combo+Fridge", "Beta+Combo+Fridge"), Is.EqualTo("Beta+Combo+Fridge"));
            Assert.That(ClosestString(m, "Beta+Alpha+Fridge", "Combo+Fridge", "Beta+Combo+Fridge"), Is.EqualTo("Beta+Alpha+Fridge"), "Since Alpha is better than Beta");
            Assert.That(ClosestString(m, "Beta+Fridge", "Combo+Fridge", "Alpha"), Is.EqualTo("Beta+Fridge"));
        }
예제 #12
0
파일: Traits.cs 프로젝트: Paty-B/ck-core
        public void CombinedTraits()
        {
            MultiTrait m = Context.FindOrCreate("Beta+Alpha");

            Assert.That(!m.IsAtomic && m.AtomicTraits.Count == 2, "Combined trait.");
            Assert.That(m.AtomicTraits[0] == Context.FindOrCreate("Alpha"), "Atomic Alpha is the first one.");
            Assert.That(m.AtomicTraits[1] == Context.FindOrCreate("Beta"), "Atomic Beta is the second one.");

            Assert.That(Context.FindOrCreate("Alpha+Beta") == m, "Canonical order is ensured.");
            Assert.That(Context.FindOrCreate("+ +\t++ Alpha+++Beta++") == m, "Extra characters and empty traits are ignored.");

            Assert.That(Context.FindOrCreate("Alpha+Beta+Alpha") == m, "Multiple identical traits are removed.");
            Assert.That(Context.FindOrCreate("Alpha+ +Beta\r++Beta+ + Alpha +    Beta   ++ ") == m, "Multiple identical traits are removed.");

            m = Context.FindOrCreate("Beta+Alpha+Zeta+Tau+Pi+Omega+Epsilon");
            Assert.That(Context.FindOrCreate("++Beta+Zeta+Omega+Epsilon+Alpha+Zeta+Epsilon+Zeta+Tau+Epsilon+Pi+Tau+Beta+Zeta+Omega+Beta+Pi+Alpha") == m,
                        "Unicity of Atomic trait is ensured.");
        }
예제 #13
0
파일: Traits.cs 프로젝트: Paty-B/ck-core
        public void FallbacksAndOrdering()
        {
            {
                MultiTrait m = Context.FindOrCreate("Alpha+Beta+Combo+Fridge");
                IReadOnlyList <MultiTrait> f = m.Fallbacks;

                MultiTrait[] sorted = f.ToArray();
                Array.Sort(sorted);
                Array.Reverse(sorted);
                Assert.That(sorted.SequenceEqual(f), "KeyboardTrait.CompareTo respects the fallbacks (fallbacks is in reverse order).");
            }
            {
                MultiTrait m = Context.FindOrCreate("Alpha+Beta+Combo+Fridge+F+K+Ju+J+A+B");
                IReadOnlyList <MultiTrait> f = m.Fallbacks;
                Assert.That(f.OrderBy(trait => trait).Reverse().SequenceEqual(f), "KeyboardTrait.CompareTo is ok, thanks to Linq ;-).");
            }
            {
                MultiTrait m = Context.FindOrCreate("xz+lz+ded+az+zer+t+zer+ce+ret+ert+ml+a+nzn");
                IReadOnlyList <MultiTrait> f = m.Fallbacks;
                Assert.That(f.OrderBy(trait => trait).Reverse().SequenceEqual(f), "KeyboardTrait.CompareTo is ok, thanks to Linq ;-).");
            }
        }
예제 #14
0
 string ClosestString( MultiTrait m, params string[] strings )
 {
     return m.Closest( strings, Util.FuncIdentity );
 }
예제 #15
0
        /// <summary>
        /// Obtains a trait from a list of atomic (already sorted) traits.
        /// Used by fall back generation.
        /// </summary>
        internal MultiTrait FindOrCreate( MultiTrait[] atomicTraits, int count )
        {
            Debug.Assert( count > 1, "Atomic traits are handled directly." );

            Debug.Assert( !Array.Exists( atomicTraits, delegate( MultiTrait mA ) { return mA.Context != this || mA.AtomicTraits.Count != 1; } ),
                "Traits are from this Context and they are atomic and not empty." );

            StringBuilder b = new StringBuilder( atomicTraits[0].ToString() );
            for( int i = 1; i < count; ++i )
            {
                Debug.Assert( StringComparer.Ordinal.Compare( atomicTraits[i - 1].ToString(), atomicTraits[i].ToString() ) < 0, "Traits are already sorted and NO DUPLICATE exists." );
                b.Append( '+' ).Append( atomicTraits[i].ToString() );
            }
            string traits = b.ToString();
            MultiTrait m;
            if( !_traits.TryGetValue( traits, out m ) )
            {
                // We must clone the array since fallback generation reuses it.
                if( atomicTraits.Length != count )
                {
                    MultiTrait[] subArray = new MultiTrait[count];
                    Array.Copy( atomicTraits, subArray, count );
                    atomicTraits = subArray;
                }
                else atomicTraits = (MultiTrait[])atomicTraits.Clone();
                lock( _creationLock )
                {
                    if( !_traits.TryGetValue( traits, out m ) )
                    {
                        m = new MultiTrait( this, traits, new ReadOnlyListOnIList<MultiTrait>( atomicTraits ) );
                        _traits[traits] = m;
                    }
                }
            }
            return m;
        }
예제 #16
0
파일: Traits.cs 프로젝트: Paty-B/ck-core
 string ClosestString(MultiTrait m, params string[] strings)
 {
     return(m.Closest(strings, Util.FuncIdentity));
 }
예제 #17
0
 MultiTrait FindOrCreate( string traits, bool create )
 {
     if( traits == null || traits.Length == 0 ) return _empty;
     traits = traits.Normalize();
     MultiTrait m;
     if( !_traits.TryGetValue( traits, out m ) )
     {
         int traitCount;
         string[] splitTraits = SplitMultiTrait( traits, out traitCount );
         if( traitCount <= 0 ) return _empty;
         if( traitCount == 1 )
         {
             m = FindOrCreateAtomicTrait( splitTraits[0], create );
         }
         else
         {
             traits = String.Join( "+", splitTraits, 0, traitCount );
             if( !_traits.TryGetValue( traits, out m ) )
             {
                 MultiTrait[] atomics = new MultiTrait[traitCount];
                 for( int i = 0; i < traitCount; ++i )
                 {
                     MultiTrait trait = FindOrCreateAtomicTrait( splitTraits[i], create );
                     if( (atomics[i] = trait) == null ) return null;
                 }
                 lock( _creationLock )
                 {
                     if( !_traits.TryGetValue( traits, out m ) )
                     {
                         m = new MultiTrait( this, traits, new ReadOnlyListOnIList<MultiTrait>( atomics ) );
                         _traits[traits] = m;
                     }
                 }
             }
             Debug.Assert( !m.IsAtomic && m.AtomicTraits.Count == traitCount, "Combined trait." );
         }
     }
     return m;
 }
예제 #18
0
 private MultiTrait FindOrCreateAtomicTrait( string trait, bool create )
 {
     MultiTrait m;
     if( !_traits.TryGetValue( trait, out m ) && create )
     {
         lock( _creationLock )
         {
             if( !_traits.TryGetValue( trait, out m ) )
             {
                 m = new MultiTrait( this, trait );
                 _traits[trait] = m;
             }
         }
         Debug.Assert( m.IsAtomic, "Special construction for atomic traits." );
     }
     return m;
 }
예제 #19
0
 /// <summary>
 /// Obtains a trait from a list of atomic (already sorted) traits.
 /// Used by the Add, Toggle, Remove, Intersect methods.
 /// </summary>
 internal MultiTrait FindOrCreate( List<MultiTrait> atomicTraits )
 {
     if( atomicTraits.Count == 0 ) return _empty;
     Debug.Assert( atomicTraits[0].Context == this, "This is one of our traits." );
     Debug.Assert( atomicTraits[0].AtomicTraits.Count == 1, "This is an atomic trait and not the empty one." );
     if( atomicTraits.Count == 1 ) return atomicTraits[0];
     StringBuilder b = new StringBuilder( atomicTraits[0].ToString() );
     for( int i = 1; i < atomicTraits.Count; ++i )
     {
         Debug.Assert( atomicTraits[i].Context == this, "This is one of our traits." );
         Debug.Assert( atomicTraits[i].AtomicTraits.Count == 1, "This is an atomic trait and not the empty one." );
         Debug.Assert( StringComparer.Ordinal.Compare( atomicTraits[i - 1].ToString(), atomicTraits[i].ToString() ) < 0,
             "Traits are already sorted and NO DUPLICATES exist." );
         b.Append( '+' ).Append( atomicTraits[i].ToString() );
     }
     string traits = b.ToString();
     MultiTrait m;
     if( !_traits.TryGetValue( traits, out m ) )
     {
         lock( _creationLock )
         {
             if( !_traits.TryGetValue( traits, out m ) )
             {
                 m = new MultiTrait( this, traits, new ReadOnlyListOnIList<MultiTrait>( atomicTraits.ToArray() ) );
                 _traits[traits] = m;
             }
         }
     }
     return m;
 }
예제 #20
0
 /// <summary>
 /// Finds a <see cref="MultiTrait"/> with only already existing atomic traits.
 /// </summary>
 /// <param name="traits">Atomic trait or traits separated by +.</param>
 /// <param name="collector">Optional collector for unknown trait. As soon as the collector returns false, the process stops.</param>
 /// <returns>A trait that contains only already existing traits or null if none already exists.</returns>
 public MultiTrait FindOnlyExisting( string traits, Func<string,bool> collector = null )
 {
     if( traits == null || traits.Length == 0 ) return null;
     traits = traits.Normalize();
     MultiTrait m;
     if( !_traits.TryGetValue( traits, out m ) )
     {
         int traitCount;
         string[] splitTraits = SplitMultiTrait( traits, out traitCount );
         if( traitCount <= 0 ) return null;
         if( traitCount == 1 )
         {
             m = FindOrCreateAtomicTrait( splitTraits[0], false );
         }
         else
         {
             traits = String.Join( "+", splitTraits, 0, traitCount );
             if( !_traits.TryGetValue( traits, out m ) )
             {
                 List<MultiTrait> atomics = new List<MultiTrait>();
                 for( int i = 0; i < traitCount; ++i )
                 {
                     MultiTrait trait = FindOrCreateAtomicTrait( splitTraits[i], false );
                     if( trait == null )
                     {
                         if( collector != null && !collector( splitTraits[i] ) ) break;
                     }
                     else atomics.Add( trait );
                 }
                 if( atomics.Count != 0 )
                 {
                     traits = String.Join( "+", atomics );
                     if( !_traits.TryGetValue( traits, out m ) )
                     {
                         lock( _creationLock )
                         {
                             if( !_traits.TryGetValue( traits, out m ) )
                             {
                                 m = new MultiTrait( this, traits, atomics.ToReadOnlyList() );
                                 _traits[traits] = m;
                             }
                         }
                     }
                 }
             }
         }
     }
     return m;
 }