@Test
public void buildEmojiFromJSON_computes_the_html_codes() throws UnsupportedEncodingException {
    JSONObject json = new JSONObject("{" + "\"emoji\": \"😄\"," + "\"description\": \"smiling face with open mouth and smiling eyes\"," + "\"aliases\": [\"smile\"]," + "\"tags\": [\"happy\", \"joy\", \"pleased\"]" + "}");
    Emoji emoji = EmojiLoader.buildEmojiFromJSON(json);
    assertEquals("😄", emoji.getUnicode());
    assertEquals("😄", emoji.getHtml());
    assertEquals("😄", emoji.getHtmlDecimal());
    assertEquals("😄", emoji.getHtmlHexidecimal());
}

@Test
public void buildEmojiFromJSON_computes_the_html_codes() throws UnsupportedEncodingException {
    JSONObject json = new JSONObject("{" + "\"emoji\": \"😄\"," + "\"description\": \"smiling face with open mouth and smiling eyes\"," + "\"aliases\": [\"smile\"]," + "\"tags\": [\"happy\", \"joy\", \"pleased\"]" + "}");
    Emoji emoji = EmojiLoader.buildEmojiFromJSON(json);
    assertNotNull(emoji);
    assertEquals("😄", emoji.getUnicode());
    assertEquals("😄", emoji.getHtmlDecimal());
    assertEquals("😄", emoji.getHtmlHexidecimal());
}

@Deprecated
public String getHtml() {
    return this.getHtmlDecimal();
}


@Test
public void testAddingResponseToExistingOneShouldOverrideProperties() {
    var response1 = HtmxResponse.builder().location("location1").pushUrl("url1").redirect("url1").replaceUrl("url1").reswap(HtmxReswap.innerHtml()).retarget("selector1");
    var response2 = HtmxResponse.builder().location("location2").pushUrl("url2").redirect("url2").replaceUrl("url2").reswap(HtmxReswap.outerHtml()).retarget("selector2").refresh();
    response1.and(response2.build());
    assertThat(response1.build()).satisfies(response -> {
        assertThat(response.getLocation()).isEqualTo(new HtmxLocation("location2"));
        assertThat(response.getPushUrl()).isEqualTo(null);
        assertThat(response.getRedirect()).isEqualTo("url2");
        assertThat(response.getReplaceUrl()).isEqualTo("url2");
        assertThat(response.getReswap()).isEqualTo(HtmxReswap.outerHtml());
        assertThat(response.getRetarget()).isEqualTo("selector2");
        assertThat(response.isRefresh()).isEqualTo(true);
    });
}

@Test
public void testAddingResponseToExistingOneShouldOverrideProperties() {
    var response1 = HtmxResponse.builder().retarget("selector1").reswap(HtmxReswap.innerHtml()).redirect("url1").pushUrl("url1");
    var response2 = HtmxResponse.builder().retarget("selector2").reswap(HtmxReswap.outerHtml()).redirect("url2").refresh().pushUrl("url2");
    response1.and(response2.build());
    assertThat(response1.build()).satisfies(response -> {
        assertThat(response.getRetarget()).isEqualTo("selector2");
        assertThat(response.getReswap()).isEqualTo(HtmxReswap.outerHtml());
        assertThat(response.getRedirect()).isEqualTo("url2");
        assertThat(response.isRefresh()).isEqualTo(true);
        assertThat(response.getPushUrl()).isEqualTo("url2");
    });
}

public Builder and(HtmxResponse otherResponse) {
    otherResponse.views.forEach(otherTemplate -> {
        if (this.views.stream().anyMatch(mav -> same(otherTemplate, mav))) {
            LOGGER.warn("Duplicate template '{}' found while merging HtmxResponse", otherTemplate);
        } else {
            views.add(otherTemplate);
        }
    });
    mergeTriggers(this.triggers, otherResponse.triggers);
    mergeTriggers(this.triggersAfterSettle, otherResponse.triggersAfterSettle);
    mergeTriggers(this.triggersAfterSwap, otherResponse.triggersAfterSwap);
    if (otherResponse.location != null) {
        this.location = otherResponse.location;
    }
    if (otherResponse.pushUrl != null) {
        this.pushUrl = otherResponse.pushUrl;
    }
    if (otherResponse.redirect != null) {
        this.redirect = otherResponse.redirect;
    }
    if (otherResponse.refresh) {
        this.refresh = true;
    }
    if (otherResponse.replaceUrl != null) {
        this.replaceUrl = otherResponse.replaceUrl;
    }
    if (otherResponse.reswap != null) {
        this.reswap = otherResponse.reswap;
    }
    if (otherResponse.retarget != null) {
        this.retarget = otherResponse.retarget;
    }
    if (otherResponse.reselect != null) {
        this.reselect = otherResponse.reselect;
    }
    return this;
}

public Builder and(HtmxResponse otherResponse) {
    otherResponse.views.forEach(otherTemplate -> {
        if (this.views.stream().anyMatch(mav -> same(otherTemplate, mav))) {
            LOGGER.warn("Duplicate template '{}' found while merging HtmxResponse", otherTemplate);
        } else {
            views.add(otherTemplate);
        }
    });
    mergeTriggers(this.triggers, otherResponse.triggers);
    mergeTriggers(this.triggersAfterSettle, otherResponse.triggersAfterSettle);
    mergeTriggers(this.triggersAfterSwap, otherResponse.triggersAfterSwap);
    if (otherResponse.pushUrl != null) {
        this.pushUrl = otherResponse.pushUrl;
    }
    if (otherResponse.redirect != null) {
        this.redirect = otherResponse.redirect;
    }
    if (otherResponse.refresh) {
        this.refresh = true;
    }
    if (otherResponse.retarget != null) {
        this.retarget = otherResponse.retarget;
    }
    if (otherResponse.reswap != null) {
        this.reswap = otherResponse.reswap;
    }
    return this;
}


@Test
public void testAddingResponseToExistingOneShouldOverrideProperties() {
    var response1 = HtmxResponse.builder().retarget("selector1").reswap(HxSwapType.INNER_HTML).redirect("url1").pushUrl("url1");
    var response2 = HtmxResponse.builder().retarget("selector2").reswap(HxSwapType.OUTER_HTML).redirect("url2").refresh().pushUrl("url2");
    response1.and(response2.build());
    assertThat(response1.build()).satisfies(response -> {
        assertThat(response.getRetarget()).isEqualTo("selector2");
        assertThat(response.getReswap()).isEqualTo(HxSwapType.OUTER_HTML);
        assertThat(response.getRedirect()).isEqualTo("url2");
        assertThat(response.isRefresh()).isEqualTo(true);
        assertThat(response.getPushUrl()).isEqualTo("url2");
    });
}

public Builder reswap(HtmxReswap reswap) {
    Assert.notNull(reswap, "reswap should not be null");
    this.reswap = reswap;
    return this;
}

@Test
public void testResponseHeaderProperties() {
    var response = HtmxResponse.builder().trigger("my-trigger").pushUrl("/a/history").redirect("/a/new/page").refresh().retarget("#theThing").reswap(HxSwapType.AFTER_BEGIN).build();
    assertThat(response.getTriggers()).containsOnlyKeys("my-trigger");
    assertThat(response.getPushUrl()).isEqualTo("/a/history");
    assertThat(response.getRedirect()).isEqualTo("/a/new/page");
    assertThat(response.isRefresh()).isTrue();
    assertThat(response.getRetarget()).isEqualTo("#theThing");
    assertThat(response.getReswap()).isEqualTo(HxSwapType.AFTER_BEGIN);
}

@Test
public void testResponseHeaderProperties() {
    var response = HtmxResponse.builder().trigger("my-trigger").pushUrl("/a/history").redirect("/a/new/page").refresh().retarget("#theThing").reswap(HtmxReswap.afterBegin()).build();
    assertThat(response.getTriggers()).containsOnlyKeys("my-trigger");
    assertThat(response.getPushUrl()).isEqualTo("/a/history");
    assertThat(response.getRedirect()).isEqualTo("/a/new/page");
    assertThat(response.isRefresh()).isTrue();
    assertThat(response.getRetarget()).isEqualTo("#theThing");
    assertThat(response.getReswap()).isEqualTo(HtmxReswap.afterBegin());
}


@Test
public void testAddingResponseToExistingOneShouldOverrideProperties() {
    var response1 = HtmxResponse.builder().retarget("selector1").reswap(HtmxReswap.innerHtml()).redirect("url1").pushUrl("url1");
    var response2 = HtmxResponse.builder().retarget("selector2").reswap(HtmxReswap.outerHtml()).redirect("url2").refresh().pushUrl("url2");
    response1.and(response2.build());
    assertThat(response1.build()).satisfies(response -> {
        assertThat(response.getRetarget()).isEqualTo("selector2");
        assertThat(response.getReswap()).isEqualTo(HtmxReswap.outerHtml());
        assertThat(response.getRedirect()).isEqualTo("url2");
        assertThat(response.isRefresh()).isEqualTo(true);
        assertThat(response.getPushUrl()).isEqualTo("url2");
    });
}

@Test
public void testAddingResponseToExistingOneShouldOverrideProperties() {
    var response1 = HtmxResponse.builder().retarget("selector1").reswap(HxSwapType.INNER_HTML).redirect("url1").pushUrl("url1");
    var response2 = HtmxResponse.builder().retarget("selector2").reswap(HxSwapType.OUTER_HTML).redirect("url2").refresh().pushUrl("url2");
    response1.and(response2.build());
    assertThat(response1.build()).satisfies(response -> {
        assertThat(response.getRetarget()).isEqualTo("selector2");
        assertThat(response.getReswap()).isEqualTo(HxSwapType.OUTER_HTML);
        assertThat(response.getRedirect()).isEqualTo("url2");
        assertThat(response.isRefresh()).isEqualTo(true);
        assertThat(response.getPushUrl()).isEqualTo("url2");
    });
}

public Builder reswap(HtmxReswap reswap) {
    Assert.notNull(reswap, "reswap should not be null");
    this.reswap = reswap;
    return this;
}

@Test
public void testResponseHeaderProperties() {
    var response = HtmxResponse.builder().trigger("my-trigger").pushUrl("/a/history").redirect("/a/new/page").refresh().retarget("#theThing").reswap(HtmxReswap.afterBegin()).build();
    assertThat(response.getTriggers()).containsOnlyKeys("my-trigger");
    assertThat(response.getPushUrl()).isEqualTo("/a/history");
    assertThat(response.getRedirect()).isEqualTo("/a/new/page");
    assertThat(response.isRefresh()).isTrue();
    assertThat(response.getRetarget()).isEqualTo("#theThing");
    assertThat(response.getReswap()).isEqualTo(HtmxReswap.afterBegin());
}

@Test
public void testResponseHeaderProperties() {
    var response = HtmxResponse.builder().trigger("my-trigger").pushUrl("/a/history").redirect("/a/new/page").refresh().retarget("#theThing").reswap(HxSwapType.AFTER_BEGIN).build();
    assertThat(response.getTriggers()).containsOnlyKeys("my-trigger");
    assertThat(response.getPushUrl()).isEqualTo("/a/history");
    assertThat(response.getRedirect()).isEqualTo("/a/new/page");
    assertThat(response.isRefresh()).isTrue();
    assertThat(response.getRetarget()).isEqualTo("#theThing");
    assertThat(response.getReswap()).isEqualTo(HxSwapType.AFTER_BEGIN);
}


@Test(expected = IllegalStateException.class)
public void naoDevePermitirValorAliquotaNulo() {
    final NFNotaInfoItemImpostoCOFINSQuantidade cofinsQuantidade = new NFNotaInfoItemImpostoCOFINSQuantidade();
    cofinsQuantidade.setQuantidadeVendida(new BigDecimal("99999999999"));
    cofinsQuantidade.setSituacaoTributaria(NFNotaInfoSituacaoTributariaCOFINS.OPERACAO_AQUISICAO_ALIQUOTA_ZERO);
    cofinsQuantidade.setValorTributo(new BigDecimal("999999999999.00"));
    cofinsQuantidade.toString();
}

@Test(expected = IllegalStateException.class)
public void naoDevePermitirValorAliquotaNulo() {
    final NFNotaInfoItemImpostoCOFINSQuantidade cofinsQuantidade = new NFNotaInfoItemImpostoCOFINSQuantidade();
    cofinsQuantidade.setQuantidadeVendida(new BigDecimal("99999999999"));
    cofinsQuantidade.setSituacaoTributaria(NFNotaInfoSituacaoTributariaCOFINS.CST_73);
    cofinsQuantidade.setValorTributo(new BigDecimal("999999999999.00"));
    cofinsQuantidade.toString();
}

public void setSituacaoTributaria(final NFNotaInfoSituacaoTributariaCOFINS situacaoTributaria) {
    if (!NFNotaInfoSituacaoTributariaCOFINS.OPERACAO_TRIBUTAVEL_QUANTIDADE_VENDIDA_POR_ALIQUOTA_POR_UNIDADE_PRODUTO.equals(situacaoTributaria)) {
        throw new IllegalStateException("Situacao tributaria invalida no item COFINS quantidade.");
    }
    this.situacaoTributaria = situacaoTributaria;
}

public void setSituacaoTributaria(final NFNotaInfoSituacaoTributariaCOFINS situacaoTributaria) {
    if (!NFNotaInfoSituacaoTributariaCOFINS.CST_03.equals(situacaoTributaria)) {
        throw new IllegalStateException("Situacao tributaria invalida no item COFINS quantidade.");
    }
    this.situacaoTributaria = situacaoTributaria;
}

@Test(expected = IllegalStateException.class)
public void naoDevePermitirValorTributoNulo() {
    final NFNotaInfoItemImpostoCOFINSQuantidade cofinsQuantidade = new NFNotaInfoItemImpostoCOFINSQuantidade();
    cofinsQuantidade.setQuantidadeVendida(new BigDecimal("99999999999"));
    cofinsQuantidade.setSituacaoTributaria(NFNotaInfoSituacaoTributariaCOFINS.OPERACAO_AQUISICAO_ALIQUOTA_ZERO);
    cofinsQuantidade.setValorAliquota(new BigDecimal("9999999999.0000"));
    cofinsQuantidade.toString();
}

@Test(expected = IllegalStateException.class)
public void naoDevePermitirValorTributoNulo() {
    final NFNotaInfoItemImpostoCOFINSQuantidade cofinsQuantidade = new NFNotaInfoItemImpostoCOFINSQuantidade();
    cofinsQuantidade.setQuantidadeVendida(new BigDecimal("99999999999"));
    cofinsQuantidade.setSituacaoTributaria(NFNotaInfoSituacaoTributariaCOFINS.CST_73);
    cofinsQuantidade.setValorAliquota(new BigDecimal("9999999999.0000"));
    cofinsQuantidade.toString();
}

@Test(expected = IllegalStateException.class)
public void naoDevePermitirQuantidadeVendidoNulo() {
    final NFNotaInfoItemImpostoCOFINSQuantidade cofinsQuantidade = new NFNotaInfoItemImpostoCOFINSQuantidade();
    cofinsQuantidade.setSituacaoTributaria(NFNotaInfoSituacaoTributariaCOFINS.OPERACAO_AQUISICAO_ALIQUOTA_ZERO);
    cofinsQuantidade.setValorAliquota(new BigDecimal("9999999999.0000"));
    cofinsQuantidade.setValorTributo(new BigDecimal("999999999999.00"));
    cofinsQuantidade.toString();
}

@Test(expected = IllegalStateException.class)
public void naoDevePermitirQuantidadeVendidoNulo() {
    final NFNotaInfoItemImpostoCOFINSQuantidade cofinsQuantidade = new NFNotaInfoItemImpostoCOFINSQuantidade();
    cofinsQuantidade.setSituacaoTributaria(NFNotaInfoSituacaoTributariaCOFINS.CST_73);
    cofinsQuantidade.setValorAliquota(new BigDecimal("9999999999.0000"));
    cofinsQuantidade.setValorTributo(new BigDecimal("999999999999.00"));
    cofinsQuantidade.toString();
}


@Test
public void deveGerarXMLDeAcordoComOPadraoEstabelecidoQuantidadeValorUnidadeTributavel() {
    final NFNotaInfoItemImpostoIPITributado ipiTributado = new NFNotaInfoItemImpostoIPITributado();
    ipiTributado.setSituacaoTributaria(NFNotaInfoSituacaoTributariaIPI.OUTRAS_ENTRADAS);
    ipiTributado.setQuantidade(new BigDecimal("99999999999.9999"));
    ipiTributado.setValorUnidadeTributavel(new BigDecimal("9999999999.9999"));
    ipiTributado.setValorTributo(new BigDecimal("999999999999.99"));
    final String xmlEsperado = "<NFNotaInfoItemImpostoIPITributado><CST>49</CST><qUnid>99999999999.9999</qUnid><vUnid>9999999999.9999</vUnid><vIPI>999999999999.99</vIPI></NFNotaInfoItemImpostoIPITributado>";
    Assert.assertEquals(xmlEsperado, ipiTributado.toString());
}

@Test
public void deveGerarXMLDeAcordoComOPadraoEstabelecidoQuantidadeValorUnidadeTributavel() {
    final NFNotaInfoItemImpostoIPITributado ipiTributado = new NFNotaInfoItemImpostoIPITributado();
    ipiTributado.setSituacaoTributaria(NFNotaInfoSituacaoTributariaIPI.CST_49);
    ipiTributado.setQuantidade(new BigDecimal("99999999999.9999"));
    ipiTributado.setValorUnidadeTributavel(new BigDecimal("9999999999.9999"));
    ipiTributado.setValorTributo(new BigDecimal("999999999999.99"));
    final String xmlEsperado = "<NFNotaInfoItemImpostoIPITributado><CST>49</CST><qUnid>99999999999.9999</qUnid><vUnid>9999999999.9999</vUnid><vIPI>999999999999.99</vIPI></NFNotaInfoItemImpostoIPITributado>";
    Assert.assertEquals(xmlEsperado, ipiTributado.toString());
}

public void setSituacaoTributaria(final NFNotaInfoSituacaoTributariaIPI situacaoTributaria) {
    if (!situacaoTributaria.equals(NFNotaInfoSituacaoTributariaIPI.ENTRADA_RECUPERACAO_CREDITO) && !situacaoTributaria.equals(NFNotaInfoSituacaoTributariaIPI.OUTRAS_ENTRADAS) && !situacaoTributaria.equals(NFNotaInfoSituacaoTributariaIPI.SAIDA_TRIBUTADA) && !situacaoTributaria.equals(NFNotaInfoSituacaoTributariaIPI.OUTRAS_SAIDAS)) {
        throw new IllegalStateException("Situacao tributaria invalido no item IPI tributado.");
    }
    this.situacaoTributaria = situacaoTributaria;
}

public void setSituacaoTributaria(final NFNotaInfoSituacaoTributariaIPI situacaoTributaria) {
    if (!situacaoTributaria.equals(NFNotaInfoSituacaoTributariaIPI.CST_00) && !situacaoTributaria.equals(NFNotaInfoSituacaoTributariaIPI.CST_49) && !situacaoTributaria.equals(NFNotaInfoSituacaoTributariaIPI.CST_50) && !situacaoTributaria.equals(NFNotaInfoSituacaoTributariaIPI.CST_99)) {
        throw new IllegalStateException("Situacao tributaria invalido no item IPI tributado.");
    }
    this.situacaoTributaria = situacaoTributaria;
}


@Test(expected = IllegalStateException.class)
public void naoDevePermitrValorAliquotaNulo() {
    final NFNotaInfoItemImpostoPISQuantidade pisQuantidade = new NFNotaInfoItemImpostoPISQuantidade();
    pisQuantidade.setQuantidadeVendida(new BigDecimal("99999999999.9999"));
    pisQuantidade.setSituacaoTributaria(NFNotaInfoSituacaoTributariaPIS.CREDITO_PRESUMIDO_OPERACAO_AQUISICAO_VINCULADA_EXCLUSIVAMENTE_A_RECEITA_NAO_TRIBUTADA_MERCADO_INTERNO);
    pisQuantidade.setValorTributo(new BigDecimal("999999999999.99"));
    pisQuantidade.toString();
}

@Test(expected = IllegalStateException.class)
public void naoDevePermitrValorAliquotaNulo() {
    final NFNotaInfoItemImpostoPISQuantidade pisQuantidade = new NFNotaInfoItemImpostoPISQuantidade();
    pisQuantidade.setQuantidadeVendida(new BigDecimal("99999999999.9999"));
    pisQuantidade.setSituacaoTributaria(NFNotaInfoSituacaoTributariaPIS.CST_61);
    pisQuantidade.setValorTributo(new BigDecimal("999999999999.99"));
    pisQuantidade.toString();
}

public void setSituacaoTributaria(final NFNotaInfoSituacaoTributariaPIS situacaoTributaria) {
    if (!NFNotaInfoSituacaoTributariaPIS.OPERACAO_TRIBUTAVEL_QUANTIDADE_VENDIDA_POR_ALIQUOTA_POR_UNIDADE_PRODUTO.equals(situacaoTributaria)) {
        throw new IllegalStateException("Situacao tributaria invalido no item PIS Quantidade");
    }
    this.situacaoTributaria = situacaoTributaria;
}

public void setSituacaoTributaria(final NFNotaInfoSituacaoTributariaPIS situacaoTributaria) {
    if (!NFNotaInfoSituacaoTributariaPIS.CST_03.equals(situacaoTributaria)) {
        throw new IllegalStateException("Situacao tributaria invalido no item PIS Quantidade");
    }
    this.situacaoTributaria = situacaoTributaria;
}

@Test(expected = IllegalStateException.class)
public void naoDevePermitrValorTributoNulo() {
    final NFNotaInfoItemImpostoPISQuantidade pisQuantidade = new NFNotaInfoItemImpostoPISQuantidade();
    pisQuantidade.setQuantidadeVendida(new BigDecimal("99999999999.9999"));
    pisQuantidade.setSituacaoTributaria(NFNotaInfoSituacaoTributariaPIS.CREDITO_PRESUMIDO_OPERACAO_AQUISICAO_VINCULADA_EXCLUSIVAMENTE_A_RECEITA_NAO_TRIBUTADA_MERCADO_INTERNO);
    pisQuantidade.setValorAliquota(new BigDecimal("9999999999.9999"));
    pisQuantidade.toString();
}

@Test(expected = IllegalStateException.class)
public void naoDevePermitrValorTributoNulo() {
    final NFNotaInfoItemImpostoPISQuantidade pisQuantidade = new NFNotaInfoItemImpostoPISQuantidade();
    pisQuantidade.setQuantidadeVendida(new BigDecimal("99999999999.9999"));
    pisQuantidade.setSituacaoTributaria(NFNotaInfoSituacaoTributariaPIS.CST_61);
    pisQuantidade.setValorAliquota(new BigDecimal("9999999999.9999"));
    pisQuantidade.toString();
}

@Test(expected = IllegalStateException.class)
public void naoDevePermitrQuantidadeVendidaNulo() {
    final NFNotaInfoItemImpostoPISQuantidade pisQuantidade = new NFNotaInfoItemImpostoPISQuantidade();
    pisQuantidade.setSituacaoTributaria(NFNotaInfoSituacaoTributariaPIS.CREDITO_PRESUMIDO_OPERACAO_AQUISICAO_VINCULADA_EXCLUSIVAMENTE_A_RECEITA_NAO_TRIBUTADA_MERCADO_INTERNO);
    pisQuantidade.setValorAliquota(new BigDecimal("9999999999.9999"));
    pisQuantidade.setValorTributo(new BigDecimal("999999999999.99"));
    pisQuantidade.toString();
}

@Test(expected = IllegalStateException.class)
public void naoDevePermitrQuantidadeVendidaNulo() {
    final NFNotaInfoItemImpostoPISQuantidade pisQuantidade = new NFNotaInfoItemImpostoPISQuantidade();
    pisQuantidade.setSituacaoTributaria(NFNotaInfoSituacaoTributariaPIS.CST_61);
    pisQuantidade.setValorAliquota(new BigDecimal("9999999999.9999"));
    pisQuantidade.setValorTributo(new BigDecimal("999999999999.99"));
    pisQuantidade.toString();
}


@Test
public void deveObterCpfEmitenteDaChave() {
    NotaFiscalChaveParser notaFiscalChaveParser = new NotaFiscalChaveParser("42151100038883975022640884579133596141399591");
    Assert.assertTrue(notaFiscalChaveParser.isEmitentePessoaFisica());
    Assert.assertEquals("38883975022", notaFiscalChaveParser.getCpfEmitente());
    Assert.assertFalse(notaFiscalChaveParser.isEmitentePessoaJuridica());
    Assert.assertNull(notaFiscalChaveParser.getCnpjEmitente());
}

@Test
public void deveObterCpfEmitenteDaChave() {
    NotaFiscalChaveParser notaFiscalChaveParser = new NotaFiscalChaveParser("42151100038883975022649694579133596141399591");
    Assert.assertTrue(notaFiscalChaveParser.isEmitentePessoaFisica());
    Assert.assertEquals("38883975022", notaFiscalChaveParser.getCpfEmitente());
    Assert.assertFalse(notaFiscalChaveParser.isEmitentePessoaJuridica());
    Assert.assertNull(notaFiscalChaveParser.getCnpjEmitente());
}

public boolean isEmitentePessoaFisica() {
    return DFUtils.isCpfValido(this.chave.substring(9, 20));
}

public boolean isEmitentePessoaFisica() {
    return DFUtils.isCpfValido(this.chave.substring(9, 20)) && this.isSerieReservadaPessoaFisica();
}


@Test
public void catalogName() throws SQLException {
    assertThat(meta.getCatalogName(1)).isEqualTo("People");
}

@Test
public void catalogName() throws SQLException {
    assertThat(meta.getCatalogName(1)).isEqualTo("");
}

public String getCatalogName(int col) throws SQLException {
    return safeGetColumnTableName(col);
}

public String getCatalogName(int col) throws SQLException {
    return "";
}


@Test
public void test3() {
    Analyzer analyzer = new ChineseWordAnalyzer();
    List<String> sentences = new ArrayList<>();
    sentences.add("杨尚川是APDPlat应用级产品开发平台的作者");
    sentences.add("他说的确实在理");
    sentences.add("提高人民生活水平");
    sentences.add("他俩儿谈恋爱是从头年元月开始的");
    sentences.add("王府饭店的设施和服务是一流的");
    sentences.add("和服务于三日后裁制完毕，并呈送将军府中");
    sentences.add("研究生命的起源");
    sentences.add("他明天起身去北京");
    sentences.add("在这些企业中国有企业有十个");
    sentences.add("他站起身来");
    sentences.add("他们是来查金泰撞人那件事的");
    sentences.add("行侠仗义的查金泰远近闻名");
    sentences.add("长春市长春节致辞");
    sentences.add("他从马上摔下来了,你马上下来一下");
    sentences.add("乒乓球拍卖完了");
    sentences.add("咬死猎人的狗");
    sentences.add("地面积了厚厚的雪");
    sentences.add("这几块地面积还真不小");
    sentences.add("大学生活象白纸");
    sentences.add("结合成分子式");
    sentences.add("有意见分歧");
    sentences.add("发展中国家兔的计划");
    sentences.add("明天他将来北京");
    sentences.add("税收制度将来会更完善");
    sentences.add("依靠群众才能做好工作");
    sentences.add("现在是施展才能的好机会");
    sentences.add("把手举起来");
    sentences.add("茶杯的把手断了");
    sentences.add("以新的姿态出现在世界东方");
    sentences.add("使节约粮食进一步形成风气");
    sentences.add("反映了一个人的精神面貌");
    sentences.add("美国加州大学的科学家发现");
    sentences.add("我好不挺好");
    sentences.add("木有");
    sentences.add("下雨天留客天天留我不留");
    sentences.add("叔叔亲了我妈妈也亲了我");
    sentences.add("白马非马");
    sentences.add("学生会写文章");
    sentences.add("张掖市民陈军");
    sentences.add("张掖市明乐县");
    sentences.add("中华人民共和国万岁万岁万万岁");
    sentences.add("word是一个中文分词项目，作者是杨尚川，杨尚川的英文名叫ysc");
    IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
    config.setUseCompoundFile(false);
    File index = new File("target/indexes");
    Utils.deleteDir(index);
    try (Directory directory = new SimpleFSDirectory(index);
        IndexWriter indexWriter = new IndexWriter(directory, config)) {
        for (String sentence : sentences) {
            Document doc = new Document();
            Field field = new TextField("text", sentence, Field.Store.YES);
            doc.add(field);
            indexWriter.addDocument(doc);
        }
        indexWriter.commit();
    } catch (Exception e) {
        fail("索引失败" + e.getMessage());
    }
    try (Directory directory = new SimpleFSDirectory(index);
        DirectoryReader directoryReader = DirectoryReader.open(directory)) {
        IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
        QueryParser queryParser = new QueryParser("text", analyzer);
        Query query = queryParser.parse("text:杨尚川");
        TopDocs docs = indexSearcher.search(query, Integer.MAX_VALUE);
        assertEquals(2, docs.totalHits);
        assertEquals("word是一个中文分词项目，作者是杨尚川，杨尚川的英文名叫ysc", indexSearcher.doc(docs.scoreDocs[0].doc).get("text"));
        assertEquals("杨尚川是APDPlat应用级产品开发平台的作者", indexSearcher.doc(docs.scoreDocs[1].doc).get("text"));
        query = queryParser.parse("text:生命");
        docs = indexSearcher.search(query, Integer.MAX_VALUE);
        assertEquals(1, docs.totalHits);
        assertEquals("研究生命的起源", indexSearcher.doc(docs.scoreDocs[0].doc).get("text"));
    } catch (Exception e) {
        fail("搜索失败" + e.getMessage());
    }
}

@Test
public void test3() {
    Analyzer analyzer = new ChineseWordAnalyzer();
    List<String> sentences = new ArrayList<>();
    sentences.add("杨尚川是APDPlat应用级产品开发平台的作者");
    sentences.add("他说的确实在理");
    sentences.add("提高人民生活水平");
    sentences.add("他俩儿谈恋爱是从头年元月开始的");
    sentences.add("王府饭店的设施和服务是一流的");
    sentences.add("和服务于三日后裁制完毕，并呈送将军府中");
    sentences.add("研究生命的起源");
    sentences.add("他明天起身去北京");
    sentences.add("在这些企业中国有企业有十个");
    sentences.add("他站起身来");
    sentences.add("他们是来查金泰撞人那件事的");
    sentences.add("行侠仗义的查金泰远近闻名");
    sentences.add("长春市长春节致辞");
    sentences.add("他从马上摔下来了,你马上下来一下");
    sentences.add("乒乓球拍卖完了");
    sentences.add("咬死猎人的狗");
    sentences.add("地面积了厚厚的雪");
    sentences.add("这几块地面积还真不小");
    sentences.add("大学生活象白纸");
    sentences.add("结合成分子式");
    sentences.add("有意见分歧");
    sentences.add("发展中国家兔的计划");
    sentences.add("明天他将来北京");
    sentences.add("税收制度将来会更完善");
    sentences.add("依靠群众才能做好工作");
    sentences.add("现在是施展才能的好机会");
    sentences.add("把手举起来");
    sentences.add("茶杯的把手断了");
    sentences.add("以新的姿态出现在世界东方");
    sentences.add("使节约粮食进一步形成风气");
    sentences.add("反映了一个人的精神面貌");
    sentences.add("美国加州大学的科学家发现");
    sentences.add("我好不挺好");
    sentences.add("木有");
    sentences.add("下雨天留客天天留我不留");
    sentences.add("叔叔亲了我妈妈也亲了我");
    sentences.add("白马非马");
    sentences.add("学生会写文章");
    sentences.add("张掖市民陈军");
    sentences.add("张掖市明乐县");
    sentences.add("中华人民共和国万岁万岁万万岁");
    sentences.add("word是一个中文分词项目，作者是杨尚川，杨尚川的英文名叫ysc");
    IndexWriterConfig config = new IndexWriterConfig(analyzer);
    config.setUseCompoundFile(false);
    File index = new File("target/indexes");
    Utils.deleteDir(index);
    try (Directory directory = new SimpleFSDirectory(index.toPath());
        IndexWriter indexWriter = new IndexWriter(directory, config)) {
        for (String sentence : sentences) {
            Document doc = new Document();
            Field field = new TextField("text", sentence, Field.Store.YES);
            doc.add(field);
            indexWriter.addDocument(doc);
        }
        indexWriter.commit();
    } catch (Exception e) {
        e.printStackTrace();
        fail("索引失败" + e.getMessage());
    }
    try (Directory directory = new SimpleFSDirectory(index.toPath());
        DirectoryReader directoryReader = DirectoryReader.open(directory)) {
        IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
        QueryParser queryParser = new QueryParser("text", analyzer);
        Query query = queryParser.parse("text:杨尚川");
        TopDocs docs = indexSearcher.search(query, Integer.MAX_VALUE);
        assertEquals(2, docs.totalHits);
        assertEquals("word是一个中文分词项目，作者是杨尚川，杨尚川的英文名叫ysc", indexSearcher.doc(docs.scoreDocs[0].doc).get("text"));
        assertEquals("杨尚川是APDPlat应用级产品开发平台的作者", indexSearcher.doc(docs.scoreDocs[1].doc).get("text"));
        query = queryParser.parse("text:生命");
        docs = indexSearcher.search(query, Integer.MAX_VALUE);
        assertEquals(1, docs.totalHits);
        assertEquals("研究生命的起源", indexSearcher.doc(docs.scoreDocs[0].doc).get("text"));
    } catch (Exception e) {
        fail("搜索失败" + e.getMessage());
    }
}

@Override
protected TokenStreamComponents createComponents(String string, Reader reader) {
    Tokenizer tokenizer = new ChineseWordTokenizer(reader, segmentation);
    return new TokenStreamComponents(tokenizer);
}

@Override
protected TokenStreamComponents createComponents(String fieldName) {
    Tokenizer tokenizer = new ChineseWordTokenizer(segmentation);
    return new TokenStreamComponents(tokenizer);
}

@Test
public void test2() {
    try {
        Analyzer analyzer = new ChineseWordAnalyzer();
        TokenStream tokenStream = analyzer.tokenStream("text", "叔叔亲了我妈妈也亲了我");
        List<String> words = new ArrayList<>();
        while (tokenStream.incrementToken()) {
            CharTermAttribute charTermAttribute = tokenStream.getAttribute(CharTermAttribute.class);
            words.add(charTermAttribute.toString());
        }
        String expResult = "[叔叔, 亲了, 妈妈, 亲了]";
        assertEquals(expResult, words.toString());
    } catch (IOException e) {
        fail("分词出错" + e.getMessage());
    }
}

@Test
public void test2() {
    try {
        Analyzer analyzer = new ChineseWordAnalyzer();
        TokenStream tokenStream = analyzer.tokenStream("text", "叔叔亲了我妈妈也亲了我");
        List<String> words = new ArrayList<>();
        tokenStream.reset();
        while (tokenStream.incrementToken()) {
            CharTermAttribute charTermAttribute = tokenStream.getAttribute(CharTermAttribute.class);
            words.add(charTermAttribute.toString());
        }
        tokenStream.close();
        String expResult = "[叔叔, 亲了, 妈妈, 亲了]";
        assertEquals(expResult, words.toString());
    } catch (IOException e) {
        fail("分词出错" + e.getMessage());
    }
}