// Path: src/main/java/org/oscii/lex/Meaning.java
// public class Meaning {
//     public final Expression expression;
//     public final List<String> pos = new ArrayList<>();
//     public final List<Definition> definitions = new ArrayList<>();
//     public final List<Translation> translations = new ArrayList<>();
//     public final List<Expression> synonyms = new ArrayList<>();
// 
//     @Override
//     public String toString() {
//         return "Meaning{" +
//                 "expression=" + expression +
//                 ", definitions=" + definitions +
//                 ", translations=" + translations +
//                 '}';
//     }
// 
//     public Meaning(Expression expression) {
//         this.expression = expression;
//     }
// }


import com.google.gson.Gson;
import org.junit.Test;
import org.oscii.lex.Meaning;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
package org.oscii.panlex;




public class PanLexJSONParserTest {

    /*
     * Create an object like obj from JSON object s.
     */
    private <T> T create(T obj, String s) {
        return (T) new Gson().fromJson(s, obj.getClass());
    }

    /*
     * Find and return the first element of s matching condition.
     */
    private <T> T getAndCheck(Collection<T> s, Predicate<? super T> condition) {
        Optional<T> maybe = s.stream().filter(condition).findFirst();
        assertTrue(maybe.isPresent());
        return maybe.get();
    }

    @Test
    public void testForEachMeaning() throws Exception {
        Set<String> languages = new HashSet<>(Arrays.asList(new String[]{"spa", "eng"}));
        PanLexJSONParser parser = new PanLexJSONParser(PanLexDir.empty());
        Predicate<Models.Lv> storeLanguage = parser.storeLanguage(languages);
        Predicate<Models.Ex> storeExpression = parser.storeEx(null);

        // Initialize parser
        assertTrue(parser.storeSource(create(new Models.Source(), "{\"ap\": 10, \"li\": \"gp\"}")));
        assertTrue(storeLanguage.test(create(new Models.Lv(), "{\"lv\": 20, \"lc\": \"spa\"}")));
        assertTrue(storeLanguage.test(create(new Models.Lv(), "{\"lv\": 30, \"lc\": \"eng\"}")));
        parser.addLanguages(languages);

        // Load a translation: dog (noun) <-> perro is defined as "a creature"
        assertTrue(storeExpression.test(create(new Models.Ex(), "{\"ex\": 40, \"lv\": 20, \"tt\": \"perro\"}")));
        assertTrue(storeExpression.test(create(new Models.Ex(), "{\"ex\": 50, \"lv\": 30, \"tt\": \"dog\"}")));
        assertTrue(parser.storeMn(create(new Models.Mn(), "{\"mn\": 60, \"ap\": 10}")));
        assertTrue(parser.storeDn(create(new Models.Dn(), "{\"dn\": 70, \"mn\": 60, \"ex\": 40}")));
        assertTrue(parser.storeDn(create(new Models.Dn(), "{\"dn\": 80, \"mn\": 60, \"ex\": 50}")));
        assertTrue(parser.storeDf(create(new Models.Df(), "{\"df\": 90, \"mn\": 60, \"lv\": 30, \"tt\": \"a creature\"}")));
        assertTrue(parser.storeWc(create(new Models.Wc(), "{\"wc\": 100, \"dn\": 80, \"ex\": 1000}")));
        assertTrue(parser.storeWcex(create(new Models.Wcex(), "{\"ex\": 1000, \"tt\": \"noun\"}")));
        parser.read(null);

        // Verify meanings
// Path: src/main/java/org/oscii/lex/Meaning.java
// public class Meaning {
//     public final Expression expression;
//     public final List<String> pos = new ArrayList<>();
//     public final List<Definition> definitions = new ArrayList<>();
//     public final List<Translation> translations = new ArrayList<>();
//     public final List<Expression> synonyms = new ArrayList<>();
// 
//     @Override
//     public String toString() {
//         return "Meaning{" +
//                 "expression=" + expression +
//                 ", definitions=" + definitions +
//                 ", translations=" + translations +
//                 '}';
//     }
// 
//     public Meaning(Expression expression) {
//         this.expression = expression;
//     }
// }


// Path: src/test/java/org/oscii/panlex/PanLexJSONParserTest.java
import com.google.gson.Gson;
import org.junit.Test;
import org.oscii.lex.Meaning;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

package org.oscii.panlex;




public class PanLexJSONParserTest {

    /*
     * Create an object like obj from JSON object s.
     */
    private <T> T create(T obj, String s) {
        return (T) new Gson().fromJson(s, obj.getClass());
    }

    /*
     * Find and return the first element of s matching condition.
     */
    private <T> T getAndCheck(Collection<T> s, Predicate<? super T> condition) {
        Optional<T> maybe = s.stream().filter(condition).findFirst();
        assertTrue(maybe.isPresent());
        return maybe.get();
    }

    @Test
    public void testForEachMeaning() throws Exception {
        Set<String> languages = new HashSet<>(Arrays.asList(new String[]{"spa", "eng"}));
        PanLexJSONParser parser = new PanLexJSONParser(PanLexDir.empty());
        Predicate<Models.Lv> storeLanguage = parser.storeLanguage(languages);
        Predicate<Models.Ex> storeExpression = parser.storeEx(null);

        // Initialize parser
        assertTrue(parser.storeSource(create(new Models.Source(), "{\"ap\": 10, \"li\": \"gp\"}")));
        assertTrue(storeLanguage.test(create(new Models.Lv(), "{\"lv\": 20, \"lc\": \"spa\"}")));
        assertTrue(storeLanguage.test(create(new Models.Lv(), "{\"lv\": 30, \"lc\": \"eng\"}")));
        parser.addLanguages(languages);

        // Load a translation: dog (noun) <-> perro is defined as "a creature"
        assertTrue(storeExpression.test(create(new Models.Ex(), "{\"ex\": 40, \"lv\": 20, \"tt\": \"perro\"}")));
        assertTrue(storeExpression.test(create(new Models.Ex(), "{\"ex\": 50, \"lv\": 30, \"tt\": \"dog\"}")));
        assertTrue(parser.storeMn(create(new Models.Mn(), "{\"mn\": 60, \"ap\": 10}")));
        assertTrue(parser.storeDn(create(new Models.Dn(), "{\"dn\": 70, \"mn\": 60, \"ex\": 40}")));
        assertTrue(parser.storeDn(create(new Models.Dn(), "{\"dn\": 80, \"mn\": 60, \"ex\": 50}")));
        assertTrue(parser.storeDf(create(new Models.Df(), "{\"df\": 90, \"mn\": 60, \"lv\": 30, \"tt\": \"a creature\"}")));
        assertTrue(parser.storeWc(create(new Models.Wc(), "{\"wc\": 100, \"dn\": 80, \"ex\": 1000}")));
        assertTrue(parser.storeWcex(create(new Models.Wcex(), "{\"ex\": 1000, \"tt\": \"noun\"}")));
        parser.read(null);

        // Verify meanings
        List<Meaning> meanings = new ArrayList<>();