From faec991cd002987d79bb7420ae780f948206eee4 Mon Sep 17 00:00:00 2001 From: Sorrel Bri Date: Wed, 4 Dec 2019 20:28:48 -0800 Subject: [PATCH] refactor state for features to contain references to phones --- src/reducers/stateReducer.features.test.js | 32 ++++++++++----- src/reducers/stateReducer.js | 45 +++++++++++++++++----- src/reducers/stateReducer.phones.test.js | 38 ++++++++++-------- 3 files changed, 79 insertions(+), 36 deletions(-) diff --git a/src/reducers/stateReducer.features.test.js b/src/reducers/stateReducer.features.test.js index 6256095..eba1bd0 100644 --- a/src/reducers/stateReducer.features.test.js +++ b/src/reducers/stateReducer.features.test.js @@ -1,14 +1,20 @@ import {stateReducer} from './stateReducer'; describe('Features', () => { - const state = { - features: [ - 'low', 'high','back', 'rounded', 'sonorant', - 'nasal', 'obstruent', 'occlusive', 'plosive', - 'prenasalized', 'aspirated', 'coronal' - ] - }; - + const state = {} + beforeEach(() => { + state.phones = { + a: {features: {occlusive: true}, grapheme: 'a'}, + n: {features: {occlusive: false}, grapheme: 'n'} + }; + state.features = { + occlusive: { + positive: [state.phones.n], + negative: [state.phones.a] + } + }; + }); + it('features returned unaltered', () => { const action = {type: ''}; expect(stateReducer(state, action)).toBe(state); @@ -16,7 +22,13 @@ describe('Features', () => { it('feature addition returns new feature list', () => { const action = {type: 'ADD_FEATURE', value: {feature: 'anterior'}}; - expect(stateReducer(state, action)).toEqual({...state, features:[...state.features, action.value.feature]}) - }) + expect(stateReducer(state, action)).toEqual( + {...state, + features:{...state.features, + anterior:{ positive:[], negative:[] } + } + } + ); + }); }); \ No newline at end of file diff --git a/src/reducers/stateReducer.js b/src/reducers/stateReducer.js index 80888ee..1987b4d 100644 --- a/src/reducers/stateReducer.js +++ b/src/reducers/stateReducer.js @@ -5,15 +5,24 @@ const initState = () => { } const addPhones = (phones, phone) => { - let node = {} + let node = {}; phone.split('').forEach((graph, index) => { if (index) node[graph] = {} if (!index && !phones[graph]) phones[graph] = {} node = index === 0 ? phones[graph] : node[graph]; + if (index === phone.length - 1) node.grapheme = phone; }) return phones; } +const findPhone = (phones, phone) => { + let node; + phone.split('').forEach((graph, index) => { + node = index === 0 ? phones[graph] : node[graph]; + }); + return node; +} + const addFeatureToPhone = (phones, phone, featureKey, featureValue) => { let node = {} phone.split('').forEach((graph, index) => { @@ -44,20 +53,38 @@ const stateReducer = (state, action) => { } case 'ADD_FEATURE': { - let newFeature = action.value.feature; let positivePhones = action.value.positivePhones || []; let negativePhones = action.value.negativePhones || []; + let newFeatureName = action.value.feature; let newPhoneObject = [ ...positivePhones, ...negativePhones ].reduce((phoneObject, phone) => addPhones(phoneObject, phone), state.phones) - if (positivePhones) positivePhones = positivePhones.reduce( - (phoneObject, positivePhone) => addFeatureToPhone(phoneObject, positivePhone, newFeature, true) - , newPhoneObject); - if (negativePhones) negativePhones = negativePhones.reduce( - (phoneObject, positivePhone) => addFeatureToPhone(phoneObject, positivePhone, newFeature, false) - , newPhoneObject); - return {...state, features:[...state.features, newFeature], phones: newPhoneObject} + + if (positivePhones) { + + positivePhones.reduce( + (phoneObject, positivePhone) => addFeatureToPhone(phoneObject, positivePhone, newFeatureName, true) + , newPhoneObject + ); + + positivePhones = positivePhones.map( positivePhone => findPhone(newPhoneObject, positivePhone) ) + // console.log(positivePhones) + } + + if (negativePhones) { + + negativePhones.reduce( + (phoneObject, positivePhone) => addFeatureToPhone(phoneObject, positivePhone, newFeatureName, false) + , newPhoneObject + ); + + negativePhones = negativePhones.map( negativePhone => findPhone(newPhoneObject, negativePhone) ) + // console.log(negativePhones) + } + + let newFeature = {[action.value.feature]: {positive: positivePhones, negative: negativePhones}}; + return {...state, features:{...state.features, ...newFeature}, phones: newPhoneObject} } default: diff --git a/src/reducers/stateReducer.phones.test.js b/src/reducers/stateReducer.phones.test.js index 42990ec..fc3e638 100644 --- a/src/reducers/stateReducer.phones.test.js +++ b/src/reducers/stateReducer.phones.test.js @@ -1,17 +1,16 @@ import {stateReducer} from './stateReducer'; describe('Phones', () => { - const n_phone = {features: {nasal: true}} - const state = { - features: [ - 'nasal' - ], - phones: { n: n_phone } - }; - + const n_phone = {features: {nasal: true}, grapheme: 'n'}; + const state = {}; beforeEach(()=> { - state.features = [ 'nasal' ]; state.phones= { n: n_phone }; + state.features = { + nasal: { + positive: [state.phones.n], + negative: [] + } + }; }) it('phones returned unaltered', () => { @@ -23,7 +22,7 @@ describe('Phones', () => { const action = {type: 'ADD_FEATURE', value: {feature: 'anterior', positivePhones: ['n']}}; expect(stateReducer(state, action)).toEqual( {...state, - features:[...state.features, action.value.feature], + features:{...state.features, anterior: { positive: [state.phones.n], negative: [] }}, phones:{...state.phones, n:{...state.phones.n, features: {...state.phones.n.features, anterior: true}}} } ) @@ -33,8 +32,8 @@ describe('Phones', () => { const action = {type: 'ADD_FEATURE', value: {feature: 'sonorant', negativePhones: ['t']}}; expect(stateReducer(state, action)).toEqual( {...state, - features:[...state.features, action.value.feature], - phones:{...state.phones, t:{features:{sonorant: false}}} + features:{...state.features, sonorant: { positive: [], negative: [state.phones.t] }}, + phones:{...state.phones, t:{features:{sonorant: false}, grapheme: 't'}} } ); }); @@ -43,9 +42,9 @@ describe('Phones', () => { const action = {type: 'ADD_FEATURE', value: {feature: 'sonorant', positivePhones: ['n'], negativePhones: ['t']}}; expect(stateReducer(state, action)).toEqual( {...state, - features:[...state.features, action.value.feature], + features:{...state.features, sonorant: { positive: [state.phones.n], negative: [state.phones.t] }}, phones:{...state.phones, - t:{features:{sonorant: false}}, + t:{features:{sonorant: false}, grapheme: 't'}, n:{...state.phones.n, features: {...state.phones.n.features, sonorant: true}} } } @@ -56,11 +55,16 @@ describe('Phones', () => { const action = {type: 'ADD_FEATURE', value: {feature: 'aspirated', positivePhones: ['ntʰ'], negativePhones: ['n','t']}}; expect(stateReducer(state, action)).toEqual( {...state, - features:[...state.features, action.value.feature], + features:{...state.features, + aspirated: { + positive: [state.phones.n.t.ʰ], + negative: [state.phones.n, state.phones.t] + } + }, phones:{...state.phones, - t:{features:{aspirated: false}}, + t:{features:{aspirated: false}, grapheme: 't'}, n:{...state.phones.n, features: {...state.phones.n.features, aspirated: false}, - t: {ʰ:{features:{aspirated:true}}} + t: {ʰ:{features:{aspirated:true}, grapheme: 'ntʰ'}} } } }