from collections import OrderedDict
from unittest import TestCase

from pyjsonnlp import validation

from flairjsonnlp import FlairPipeline
from . import mocks
import pytest

text = "Autonomous cars from the countryside of France shift insurance liability toward manufacturers. People are afraid that they will crash."


def strip_scores(j):
    """Scores are non-deterministic"""
    for s in j['documents'][1]['sentences']:
        for label in s.get('labels', []):
            label['scores']['label'] = 0
    for e in j['documents'][1]['expressions']:
        e['scores']['type'] = 0
    for t in j['documents'][1]['tokenList']:
        t['scores']['upos'] = 0
        t['scores']['xpos'] = 0
        t['scores']['entity'] = 0
        if 'synsets' in t:
            t['synsets'][0]['scores']['wordnetId'] = 0


class TestFlair(TestCase):
    def test_process(self):
        actual = FlairPipeline().process(text, fast=False, use_ontonotes=False)
        assert isinstance(actual, OrderedDict)  # can't decide on some of the pos tags...
        # strip_scores(actual)
        # expected = OrderedDict([('DC.conformsTo', 0.1), ('DC.source', 'Flair 0.4.1'), ('DC.created', '2019-01-25T17:04:34'), ('DC.date', '2019-01-25T17:04:34'), ('DC.creator', ''), ('DC.publisher', ''), ('DC.title', ''), ('DC.description', ''), ('DC.identifier', ''), ('DC.language', 'en'), ('conll', {}), ('documents', [OrderedDict([('text', 'Autonomous cars from the countryside of France shift insurance liability toward manufacturers. People are afraid that they will crash.'), ('tokenList', [{'id': 1, 'text': 'Autonomous', 'characterOffsetBegin': 0, 'characterOffsetEnd': 10, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADJ', 'xpos': 'JJ', 'entity_iob': 'O'}, {'id': 2, 'text': 'cars', 'characterOffsetBegin': 11, 'characterOffsetEnd': 15, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NNS', 'entity_iob': 'O'}, {'id': 3, 'text': 'from', 'characterOffsetBegin': 16, 'characterOffsetEnd': 20, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADP', 'xpos': 'IN', 'entity_iob': 'O'}, {'id': 4, 'text': 'the', 'characterOffsetBegin': 21, 'characterOffsetEnd': 24, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'DET', 'xpos': 'DT', 'entity_iob': 'O'}, {'id': 5, 'text': 'countryside', 'characterOffsetBegin': 25, 'characterOffsetEnd': 36, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NN', 'entity_iob': 'O'}, {'id': 6, 'text': 'of', 'characterOffsetBegin': 37, 'characterOffsetEnd': 39, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADP', 'xpos': 'IN', 'entity_iob': 'O'}, {'id': 7, 'text': 'France', 'characterOffsetBegin': 40, 'characterOffsetEnd': 46, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'PROPN', 'xpos': 'NNP', 'entity': 'S-LOC', 'entity_iob': 'B'}, {'id': 8, 'text': 'shift', 'characterOffsetBegin': 47, 'characterOffsetEnd': 52, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'VERB', 'xpos': 'VBP', 'entity_iob': 'O', 'synsets': [{'wordnetId': 'shift.v.01', 'scores': {'wordnetId': 0}}]}, {'id': 9, 'text': 'insurance', 'characterOffsetBegin': 53, 'characterOffsetEnd': 62, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NN', 'entity_iob': 'O'}, {'id': 10, 'text': 'liability', 'characterOffsetBegin': 63, 'characterOffsetEnd': 72, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NN', 'entity_iob': 'O'}, {'id': 11, 'text': 'toward', 'characterOffsetBegin': 73, 'characterOffsetEnd': 79, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADP', 'xpos': 'IN', 'entity_iob': 'O'}, {'id': 12, 'text': 'manufacturers.', 'characterOffsetBegin': 80, 'characterOffsetEnd': 94, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NN', 'entity_iob': 'O'}, {'id': 13, 'text': 'People', 'characterOffsetBegin': 0, 'characterOffsetEnd': 6, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NNS', 'entity_iob': 'O'}, {'id': 14, 'text': 'are', 'characterOffsetBegin': 7, 'characterOffsetEnd': 10, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'AUX', 'xpos': 'VBP', 'entity_iob': 'O', 'synsets': [{'wordnetId': 'be.a.01', 'scores': {'wordnetId': 0}}]}, {'id': 15, 'text': 'afraid', 'characterOffsetBegin': 11, 'characterOffsetEnd': 17, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADJ', 'xpos': 'JJ', 'entity_iob': 'O'}, {'id': 16, 'text': 'that', 'characterOffsetBegin': 18, 'characterOffsetEnd': 22, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'SCONJ', 'xpos': 'IN', 'entity_iob': 'O'}, {'id': 17, 'text': 'they', 'characterOffsetBegin': 23, 'characterOffsetEnd': 27, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'PRON', 'xpos': 'PRP', 'entity_iob': 'O'}, {'id': 18, 'text': 'will', 'characterOffsetBegin': 28, 'characterOffsetEnd': 32, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'AUX', 'xpos': 'MD', 'entity_iob': 'O'}, {'id': 19, 'text': 'crash.', 'characterOffsetBegin': 33, 'characterOffsetEnd': 39, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'VERB', 'xpos': 'VB', 'entity_iob': 'O', 'synsets': [{'wordnetId': 'crash.v.01', 'scores': {'wordnetId': 0}}]}]), ('clauses', []), ('sentences', [{'id': '0', 'tokenFrom': 1, 'tokenTo': 13, 'tokens': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 'labels': [{'type': 'sentiment', 'label': 'POSITIVE', 'scores': {'label': 0}}]}, {'id': '1', 'tokenFrom': 13, 'tokenTo': 20, 'tokens': [13, 14, 15, 16, 17, 18, 19], 'labels': [{'type': 'sentiment', 'label': 'POSITIVE', 'scores': {'label': 0}}]}]), ('paragraphs', []), ('dependenciesBasic', []), ('dependenciesEnhanced', []), ('coreferences', []), ('constituents', []), ('expressions', [{'type': 'VP', 'scores': {'type': 0}, 'tokens': [18, 19]}])])])])
        # assert actual == expected, actual

    def test_process_fast(self):
        actual = FlairPipeline().process(text, fast=True, use_ontonotes=False)
        assert isinstance(actual, OrderedDict)  # can't decide on some of the pos tags...
        # strip_scores(actual)
        # expected = OrderedDict([('DC.conformsTo', 0.1), ('DC.source', 'Flair 0.4.1'), ('DC.created', '2019-01-25T17:04:34'), ('DC.date', '2019-01-25T17:04:34'), ('DC.creator', ''), ('DC.publisher', ''), ('DC.title', ''), ('DC.description', ''), ('DC.identifier', ''), ('DC.language', 'en'), ('conll', {}), ('documents', [OrderedDict([('text', 'Autonomous cars from the countryside of France shift insurance liability toward manufacturers. People are afraid that they will crash.'), ('tokenList', [{'id': 1, 'text': 'Autonomous', 'characterOffsetBegin': 0, 'characterOffsetEnd': 10, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADJ', 'xpos': 'JJ', 'entity_iob': 'O'}, {'id': 2, 'text': 'cars', 'characterOffsetBegin': 11, 'characterOffsetEnd': 15, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NNS', 'entity_iob': 'O'}, {'id': 3, 'text': 'from', 'characterOffsetBegin': 16, 'characterOffsetEnd': 20, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADP', 'xpos': 'IN', 'entity_iob': 'O'}, {'id': 4, 'text': 'the', 'characterOffsetBegin': 21, 'characterOffsetEnd': 24, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'DET', 'xpos': 'DT', 'entity_iob': 'O'}, {'id': 5, 'text': 'countryside', 'characterOffsetBegin': 25, 'characterOffsetEnd': 36, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NN', 'entity_iob': 'O'}, {'id': 6, 'text': 'of', 'characterOffsetBegin': 37, 'characterOffsetEnd': 39, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADP', 'xpos': 'IN', 'entity_iob': 'O'}, {'id': 7, 'text': 'France', 'characterOffsetBegin': 40, 'characterOffsetEnd': 46, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'PROPN', 'xpos': 'NNP', 'entity': 'S-LOC', 'entity_iob': 'B'}, {'id': 8, 'text': 'shift', 'characterOffsetBegin': 47, 'characterOffsetEnd': 52, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'VERB', 'xpos': 'VBP', 'entity_iob': 'O', 'synsets': [{'wordnetId': 'shift.v.01', 'scores': {'wordnetId': 0}}]}, {'id': 9, 'text': 'insurance', 'characterOffsetBegin': 53, 'characterOffsetEnd': 62, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NN', 'entity_iob': 'O'}, {'id': 10, 'text': 'liability', 'characterOffsetBegin': 63, 'characterOffsetEnd': 72, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NN', 'entity_iob': 'O'}, {'id': 11, 'text': 'toward', 'characterOffsetBegin': 73, 'characterOffsetEnd': 79, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADP', 'xpos': 'IN', 'entity_iob': 'O'}, {'id': 12, 'text': 'manufacturers.', 'characterOffsetBegin': 80, 'characterOffsetEnd': 94, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NNS', 'entity_iob': 'O'}, {'id': 13, 'text': 'People', 'characterOffsetBegin': 0, 'characterOffsetEnd': 6, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NNS', 'entity_iob': 'O'}, {'id': 14, 'text': 'are', 'characterOffsetBegin': 7, 'characterOffsetEnd': 10, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'AUX', 'xpos': 'VBP', 'entity_iob': 'O', 'synsets': [{'wordnetId': 'be.a.01', 'scores': {'wordnetId': 0}}]}, {'id': 15, 'text': 'afraid', 'characterOffsetBegin': 11, 'characterOffsetEnd': 17, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADJ', 'xpos': 'JJ', 'entity_iob': 'O'}, {'id': 16, 'text': 'that', 'characterOffsetBegin': 18, 'characterOffsetEnd': 22, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'SCONJ', 'xpos': 'IN', 'entity_iob': 'O'}, {'id': 17, 'text': 'they', 'characterOffsetBegin': 23, 'characterOffsetEnd': 27, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'PRON', 'xpos': 'PRP', 'entity_iob': 'O'}, {'id': 18, 'text': 'will', 'characterOffsetBegin': 28, 'characterOffsetEnd': 32, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'AUX', 'xpos': 'MD', 'entity_iob': 'O'}, {'id': 19, 'text': 'crash.', 'characterOffsetBegin': 33, 'characterOffsetEnd': 39, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'VERB', 'xpos': '.', 'entity_iob': 'O'}]), ('clauses', []), ('sentences', [{'id': '0', 'tokenFrom': 1, 'tokenTo': 13, 'tokens': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 'labels': [{'type': 'sentiment', 'label': 'POSITIVE', 'scores': {'label': 0}}]}, {'id': '1', 'tokenFrom': 13, 'tokenTo': 20, 'tokens': [13, 14, 15, 16, 17, 18, 19], 'labels': [{'type': 'sentiment', 'label': 'POSITIVE', 'scores': {'label': 0}}]}]), ('paragraphs', []), ('dependenciesBasic', []), ('dependenciesEnhanced', []), ('coreferences', []), ('constituents', []), ('expressions', [{'type': 'VP', 'scores': {'type': 0}, 'tokens': [18, 19]}])])])])
        # assert actual == expected, actual

    def test_process_ontonotes(self):
        actual = FlairPipeline().process(text, fast=True, use_ontonotes=True)
        assert isinstance(actual, OrderedDict)  # can't decide on some of the pos tags...
        # strip_scores(actual)
        # expected = OrderedDict([('DC.conformsTo', 0.1), ('DC.source', 'Flair 0.4.1'), ('DC.created', '2019-01-25T17:04:34'), ('DC.date', '2019-01-25T17:04:34'), ('DC.creator', ''), ('DC.publisher', ''), ('DC.title', ''), ('DC.description', ''), ('DC.identifier', ''), ('DC.language', 'en'), ('conll', {}), ('documents', [OrderedDict([('text', 'Autonomous cars from the countryside of France shift insurance liability toward manufacturers. People are afraid that they will crash.'), ('tokenList', [{'id': 1, 'text': 'Autonomous', 'characterOffsetBegin': 0, 'characterOffsetEnd': 10, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADJ', 'xpos': 'JJ', 'entity_iob': 'O'}, {'id': 2, 'text': 'cars', 'characterOffsetBegin': 11, 'characterOffsetEnd': 15, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NNS', 'entity_iob': 'O'}, {'id': 3, 'text': 'from', 'characterOffsetBegin': 16, 'characterOffsetEnd': 20, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADP', 'xpos': 'IN', 'entity_iob': 'O'}, {'id': 4, 'text': 'the', 'characterOffsetBegin': 21, 'characterOffsetEnd': 24, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'DET', 'xpos': 'DT', 'entity_iob': 'O'}, {'id': 5, 'text': 'countryside', 'characterOffsetBegin': 25, 'characterOffsetEnd': 36, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NN', 'entity_iob': 'O'}, {'id': 6, 'text': 'of', 'characterOffsetBegin': 37, 'characterOffsetEnd': 39, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADP', 'xpos': 'IN', 'entity_iob': 'O'}, {'id': 7, 'text': 'France', 'characterOffsetBegin': 40, 'characterOffsetEnd': 46, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'PROPN', 'xpos': 'NNP', 'entity': 'S-GPE', 'entity_iob': 'B'}, {'id': 8, 'text': 'shift', 'characterOffsetBegin': 47, 'characterOffsetEnd': 52, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'VERB', 'xpos': 'VBP', 'entity_iob': 'O', 'synsets': [{'wordnetId': 'shift.v.01', 'scores': {'wordnetId': 0}}]}, {'id': 9, 'text': 'insurance', 'characterOffsetBegin': 53, 'characterOffsetEnd': 62, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NN', 'entity_iob': 'O'}, {'id': 10, 'text': 'liability', 'characterOffsetBegin': 63, 'characterOffsetEnd': 72, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NN', 'entity_iob': 'O'}, {'id': 11, 'text': 'toward', 'characterOffsetBegin': 73, 'characterOffsetEnd': 79, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADP', 'xpos': 'IN', 'entity_iob': 'O'}, {'id': 12, 'text': 'manufacturers.', 'characterOffsetBegin': 80, 'characterOffsetEnd': 94, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NNS', 'entity_iob': 'O'}, {'id': 13, 'text': 'People', 'characterOffsetBegin': 0, 'characterOffsetEnd': 6, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'xpos': 'NNS', 'entity_iob': 'O'}, {'id': 14, 'text': 'are', 'characterOffsetBegin': 7, 'characterOffsetEnd': 10, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'AUX', 'xpos': 'VBP', 'entity_iob': 'O', 'synsets': [{'wordnetId': 'be.a.01', 'scores': {'wordnetId': 0}}]}, {'id': 15, 'text': 'afraid', 'characterOffsetBegin': 11, 'characterOffsetEnd': 17, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADJ', 'xpos': 'JJ', 'entity_iob': 'O'}, {'id': 16, 'text': 'that', 'characterOffsetBegin': 18, 'characterOffsetEnd': 22, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'SCONJ', 'xpos': 'IN', 'entity_iob': 'O'}, {'id': 17, 'text': 'they', 'characterOffsetBegin': 23, 'characterOffsetEnd': 27, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'PRON', 'xpos': 'PRP', 'entity_iob': 'O'}, {'id': 18, 'text': 'will', 'characterOffsetBegin': 28, 'characterOffsetEnd': 32, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'AUX', 'xpos': 'MD', 'entity_iob': 'O'}, {'id': 19, 'text': 'crash.', 'characterOffsetBegin': 33, 'characterOffsetEnd': 39, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'VERB', 'xpos': 'VB', 'entity_iob': 'O'}]), ('clauses', []), ('sentences', [{'id': '0', 'tokenFrom': 1, 'tokenTo': 13, 'tokens': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 'labels': [{'type': 'sentiment', 'label': 'POSITIVE', 'scores': {'label': 0}}]}, {'id': '1', 'tokenFrom': 13, 'tokenTo': 20, 'tokens': [13, 14, 15, 16, 17, 18, 19], 'labels': [{'type': 'sentiment', 'label': 'POSITIVE', 'scores': {'label': 0}}]}]), ('paragraphs', []), ('dependenciesBasic', []), ('dependenciesEnhanced', []), ('coreferences', []), ('constituents', []), ('expressions', [{'type': 'VP', 'scores': {'type': 0}, 'tokens': [18, 19]}])])])])
        # assert actual == expected, actual

    def test_process_multi(self):
        actual = FlairPipeline().process(text, lang='multi', fast=True, use_ontonotes=False)
        assert isinstance(actual, OrderedDict)  # can't decide on some of the pos tags...
        # strip_scores(actual)
        # expected = OrderedDict([('DC.conformsTo', 0.1), ('DC.source', 'Flair 0.4.1'), ('DC.created', '2019-01-25T17:04:34'), ('DC.date', '2019-01-25T17:04:34'), ('DC.creator', ''), ('DC.publisher', ''), ('DC.title', ''), ('DC.description', ''), ('DC.identifier', ''), ('DC.language', 'multi'), ('conll', {}), ('documents', [OrderedDict([('text', 'Autonomous cars from the countryside of France shift insurance liability toward manufacturers. People are afraid that they will crash.'), ('tokenList', [{'id': 1, 'text': 'Autonomous', 'characterOffsetBegin': 0, 'characterOffsetEnd': 10, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADJ', 'entity_iob': 'O'}, {'id': 2, 'text': 'cars', 'characterOffsetBegin': 11, 'characterOffsetEnd': 15, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'entity_iob': 'O'}, {'id': 3, 'text': 'from', 'characterOffsetBegin': 16, 'characterOffsetEnd': 20, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADP', 'entity_iob': 'O'}, {'id': 4, 'text': 'the', 'characterOffsetBegin': 21, 'characterOffsetEnd': 24, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'DET', 'entity_iob': 'O'}, {'id': 5, 'text': 'countryside', 'characterOffsetBegin': 25, 'characterOffsetEnd': 36, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'entity_iob': 'O'}, {'id': 6, 'text': 'of', 'characterOffsetBegin': 37, 'characterOffsetEnd': 39, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADP', 'entity_iob': 'O'}, {'id': 7, 'text': 'France', 'characterOffsetBegin': 40, 'characterOffsetEnd': 46, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'entity': 0, 'xpos': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'PROPN', 'entity': 'S-LOC', 'entity_iob': 'B'}, {'id': 8, 'text': 'shift', 'characterOffsetBegin': 47, 'characterOffsetEnd': 52, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'VERB', 'entity_iob': 'O'}, {'id': 9, 'text': 'insurance', 'characterOffsetBegin': 53, 'characterOffsetEnd': 62, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'entity_iob': 'O'}, {'id': 10, 'text': 'liability', 'characterOffsetBegin': 63, 'characterOffsetEnd': 72, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'entity_iob': 'O'}, {'id': 11, 'text': 'toward', 'characterOffsetBegin': 73, 'characterOffsetEnd': 79, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADP', 'entity_iob': 'O'}, {'id': 12, 'text': 'manufacturers.', 'characterOffsetBegin': 80, 'characterOffsetEnd': 94, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'entity_iob': 'O'}, {'id': 13, 'text': 'People', 'characterOffsetBegin': 0, 'characterOffsetEnd': 6, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'NOUN', 'entity_iob': 'O'}, {'id': 14, 'text': 'are', 'characterOffsetBegin': 7, 'characterOffsetEnd': 10, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'AUX', 'entity_iob': 'O'}, {'id': 15, 'text': 'afraid', 'characterOffsetBegin': 11, 'characterOffsetEnd': 17, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'ADJ', 'entity_iob': 'O'}, {'id': 16, 'text': 'that', 'characterOffsetBegin': 18, 'characterOffsetEnd': 22, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'SCONJ', 'entity_iob': 'O'}, {'id': 17, 'text': 'they', 'characterOffsetBegin': 23, 'characterOffsetEnd': 27, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'PRON', 'entity_iob': 'O'}, {'id': 18, 'text': 'will', 'characterOffsetBegin': 28, 'characterOffsetEnd': 32, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'AUX', 'entity_iob': 'O'}, {'id': 19, 'text': 'crash.', 'characterOffsetBegin': 33, 'characterOffsetEnd': 39, 'features': {'Overt': 'Yes'}, 'scores': {'upos': 0, 'xpos': 0, 'entity': 0}, 'misc': {'SpaceAfter': 'Yes'}, 'upos': 'VERB', 'entity_iob': 'O'}]), ('clauses', []), ('sentences', [{'id': '0', 'tokenFrom': 1, 'tokenTo': 13, 'tokens': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]}, {'id': '1', 'tokenFrom': 13, 'tokenTo': 20, 'tokens': [13, 14, 15, 16, 17, 18, 19]}]), ('paragraphs', []), ('dependenciesBasic', []), ('dependenciesEnhanced', []), ('coreferences', []), ('constituents', []), ('expressions', [])])])])
        # assert actual == expected, actual

    def test_invalid_language(self):
        with pytest.raises(TypeError):
            FlairPipeline().process(text, lang='martian')

    def test_validation(self):
        assert validation.is_valid(FlairPipeline.process(text, lang='en'))


class TestFlairEmbeddings(TestCase):
    def test_no_embeddings(self):
        actual = FlairPipeline().process(text, lang='multi', fast=True, use_embeddings='', char_embeddings=False, bpe_size=0)
        assert all(map(lambda t: 'embeddings' not in t, actual['documents'][1]['tokenList'].values())), actual['documents'][1]['tokenList'][1]['embeddings'][0]['model']

    def test_default_embeddings(self):
        actual = FlairPipeline().process(text, lang='multi', fast=True, use_embeddings='default', char_embeddings=False, bpe_size=0)
        assert all(map(lambda t: t['embeddings'][0]['model'] == 'Flair glove,multi-forward,multi-backward',
                       actual['documents'][1]['tokenList'].values())), actual['documents'][1]['tokenList'][1]['embeddings'][0]['model']

    def test_character_embeddings(self):
        actual = FlairPipeline().process(text, lang='multi', fast=True, use_embeddings='', char_embeddings=True, bpe_size=0)
        assert all(map(lambda t: t['embeddings'][0]['model'] == 'Flair ,char',
                       actual['documents'][1]['tokenList'].values())), actual['documents'][1]['tokenList'][1]['embeddings'][0]['model']

    def test_bpe(self):
        actual = FlairPipeline().process(text, lang='en', fast=True, use_embeddings='', char_embeddings=False, bpe_size=50)
        assert all(map(lambda t: t['embeddings'][0]['model'] == 'Flair ,byte-pair_50',
                       actual['documents'][1]['tokenList'].values())), actual['documents'][1]['tokenList'][1]['embeddings'][0]['model']
        with pytest.raises(ValueError):
            FlairPipeline().process(text, lang='multi', fast=True, use_embeddings='', char_embeddings=False, bpe_size=50)
        with pytest.raises(ValueError):
            FlairPipeline().process(text, lang='en', bpe_size=45)

    def test_invalid(self):
        with pytest.raises(ValueError):
            FlairPipeline().process(text, lang='multi', fast=True, use_embeddings='martian', char_embeddings=False, bpe_size=0)

    def test_validation_default(self):
        assert validation.is_valid(FlairPipeline.process(text, lang='en', use_embeddings='default'))

    def test_validation_bpe(self):
        assert validation.is_valid(FlairPipeline.process(text, lang='en', bpe_size=50))

    def test_validation_chars(self):
        assert validation.is_valid(FlairPipeline.process(text, lang='en', char_embeddings=True))
