@@ -1576,6 +1576,105 @@ describe('writeMorphemeGloss', () => {
15761576 store . getState ( ) . analysis . analysis . tokenAnalyses [ 0 ] . morphemes ?. [ 0 ] . gloss ,
15771577 ) . toBeUndefined ( ) ;
15781578 } ) ;
1579+
1580+ it ( 're-converges onto an identical sibling after a morpheme gloss edit' , ( ) => {
1581+ // Two payloads for "cats" differ only in morpheme-0's gloss; glossing tok-1's morpheme to match
1582+ // tok-2's makes them content-identical, so the two payloads should collapse back onto one.
1583+ const ta1 : TokenAnalysis = {
1584+ id : 'ta-1' ,
1585+ surfaceText : 'cats' ,
1586+ morphemes : [
1587+ { id : 'm-1' , form : 'cat' , writingSystem : 'und' } ,
1588+ { id : 'm-2' , form : '-s' , writingSystem : 'und' , gloss : { und : 'PL' } } ,
1589+ ] ,
1590+ } ;
1591+ const ta2 : TokenAnalysis = {
1592+ id : 'ta-2' ,
1593+ surfaceText : 'cats' ,
1594+ morphemes : [
1595+ { id : 'm-3' , form : 'cat' , writingSystem : 'und' , gloss : { und : 'feline' } } ,
1596+ { id : 'm-4' , form : '-s' , writingSystem : 'und' , gloss : { und : 'PL' } } ,
1597+ ] ,
1598+ } ;
1599+ const store = createAnalysisStore ( {
1600+ analysis : {
1601+ analysis : {
1602+ ...emptyAnalysis ( ) ,
1603+ tokenAnalyses : [ ta1 , ta2 ] ,
1604+ tokenAnalysisLinks : [
1605+ {
1606+ analysisId : 'ta-1' ,
1607+ status : 'approved' ,
1608+ token : { tokenRef : 'tok-1' , surfaceText : 'cats' } ,
1609+ } ,
1610+ {
1611+ analysisId : 'ta-2' ,
1612+ status : 'approved' ,
1613+ token : { tokenRef : 'tok-2' , surfaceText : 'cats' } ,
1614+ } ,
1615+ ] ,
1616+ } ,
1617+ analysisLanguage : 'und' ,
1618+ } ,
1619+ } ) ;
1620+
1621+ store . dispatch ( writeMorphemeGloss ( { tokenRef : 'tok-1' , morphemeId : 'm-1' , value : 'feline' } ) ) ;
1622+
1623+ const { tokenAnalyses, tokenAnalysisLinks } = store . getState ( ) . analysis . analysis ;
1624+ expect ( tokenAnalyses ) . toHaveLength ( 1 ) ;
1625+ expect ( tokenAnalysisLinks ) . toHaveLength ( 2 ) ;
1626+ expect ( tokenAnalysisLinks . every ( ( l ) => l . analysisId === tokenAnalyses [ 0 ] . id ) ) . toBe ( true ) ;
1627+ } ) ;
1628+
1629+ it ( 're-converges onto an identical sibling after clearing a morpheme gloss' , ( ) => {
1630+ // Two payloads for "cats" differ only in that tok-1's morpheme-0 carries a stray gloss; clearing
1631+ // it makes the two payloads content-identical, so they should collapse back onto one — the clear
1632+ // path must re-converge symmetrically with the write path, not leave a duplicate behind.
1633+ const ta1 : TokenAnalysis = {
1634+ id : 'ta-1' ,
1635+ surfaceText : 'cats' ,
1636+ morphemes : [
1637+ { id : 'm-1' , form : 'cat' , writingSystem : 'und' , gloss : { und : 'feline' } } ,
1638+ { id : 'm-2' , form : '-s' , writingSystem : 'und' , gloss : { und : 'PL' } } ,
1639+ ] ,
1640+ } ;
1641+ const ta2 : TokenAnalysis = {
1642+ id : 'ta-2' ,
1643+ surfaceText : 'cats' ,
1644+ morphemes : [
1645+ { id : 'm-3' , form : 'cat' , writingSystem : 'und' } ,
1646+ { id : 'm-4' , form : '-s' , writingSystem : 'und' , gloss : { und : 'PL' } } ,
1647+ ] ,
1648+ } ;
1649+ const store = createAnalysisStore ( {
1650+ analysis : {
1651+ analysis : {
1652+ ...emptyAnalysis ( ) ,
1653+ tokenAnalyses : [ ta1 , ta2 ] ,
1654+ tokenAnalysisLinks : [
1655+ {
1656+ analysisId : 'ta-1' ,
1657+ status : 'approved' ,
1658+ token : { tokenRef : 'tok-1' , surfaceText : 'cats' } ,
1659+ } ,
1660+ {
1661+ analysisId : 'ta-2' ,
1662+ status : 'approved' ,
1663+ token : { tokenRef : 'tok-2' , surfaceText : 'cats' } ,
1664+ } ,
1665+ ] ,
1666+ } ,
1667+ analysisLanguage : 'und' ,
1668+ } ,
1669+ } ) ;
1670+
1671+ store . dispatch ( writeMorphemeGloss ( { tokenRef : 'tok-1' , morphemeId : 'm-1' , value : '' } ) ) ;
1672+
1673+ const { tokenAnalyses, tokenAnalysisLinks } = store . getState ( ) . analysis . analysis ;
1674+ expect ( tokenAnalyses ) . toHaveLength ( 1 ) ;
1675+ expect ( tokenAnalysisLinks ) . toHaveLength ( 2 ) ;
1676+ expect ( tokenAnalysisLinks . every ( ( l ) => l . analysisId === tokenAnalyses [ 0 ] . id ) ) . toBe ( true ) ;
1677+ } ) ;
15791678} ) ;
15801679
15811680describe ( 'selectApprovedMorphemes' , ( ) => {
0 commit comments