Use implicit namespace plugins for import and export (#1216)

* behavior outline
* FIrst pass at allow external plugins
* remove template exporter
* Add listing of active plugins to '--version' output
* Documentation for plugins
* [Docs] add custom imports and exporters to site TOC
* [Docs] better linewrapping
* enforce positive initial linewrap
  Check column widths
  update gitignore
  throw error when linewrap too small
  simply check for large enough linewrap value
* delete unused error message
* PR feedback
  make exception more informative
  update check_linewrap signature in src and test
  make check_linewrap a free function
* delete unused function
* delete else..pass block
* newline for make format
* Include dates_exporter
* Use Base classes for importer and exporters.
* [Docs] improve documentation of custom Importers and Exporters
* [Testing] separate run with external plugin!
* basic behavior test
* prototype unittest for JSON Exporter
  test for unimplemented method
* make format
  delete unused imports
* Remove 'importer' or 'exporter' from filenames where not needed
* [Test] run different tests with or without the external plugins installed
* [Test] move test rot13 plugin into git tree
  from 0dc912af82
* consolidate demo plugins to common package
* [Docs] name page for plugins
* [Docs] include the sample plug in code files directly
* style fixes
* [test] determine whether to run external plug in tests based on installed packages
* improved code documentation
* style fixes for GitHub actions
* Convert "short" and "pretty" (and "default") formaters to plugins
  further to https://github.com/jrnl-org/jrnl/pull/1177
* more code clean up
  tests pass locally...now for GitHub...
* [tests] dynamically determine jrnl version for plugin tests
* [GitHub Actions] direct install of testing plugins
* Remove template code
* [plugins] meta --> collector
* [Docs] create scripted entries using an custom importer
* (closer to) being able to run behave tests outside project root directory
* We already know when exporter to use
  Don't re-calculate it!
* [Tests] don't name test plugin 'testing"
  If so named, pip won't install it.
* [Test] run behave tests with test plugins outside project root
* [Test] behave tests pass locally
* [Docs] fix typo
* [GitHub Actions] run test commands from poetry's shell
* black-ify code
* [GitHub Actions] move downstream (rather than up) to run tests
* [GitHub Actions] set shell to poetry
* [GitHub Workflows] Manually activate virtual environment
* [GitHub Actions] Skip Windows & Python 3.8
  Can't seem to find Python exe?
* [GiotHub Actions] explicitly use virtual env
* [GitHub Actions] create virutal env directly
* [GitHub Actions] better activate of Windows virtual env
* [GitHub Actions] create virtual env on Mac
* [Github Actions] install wheel and upgrade pip
* [GitHub Actions] skip virtual environments altogether
* [GitHub Actions] change directory for behave test
* Remove Windows exclusions from CI as per note -- they should be working now

Co-authored-by: Suhas <sugas182@gmail.com>
Co-authored-by: Micah Jerome Ellison <micah.jerome.ellison@gmail.com>
This commit is contained in:
MinchinWeb 2021-05-29 18:21:45 -06:00 committed by Jonathan Wren
parent cef3a98b4e
commit 4392e29742
45 changed files with 1021 additions and 383 deletions

View file

@ -3,7 +3,6 @@
import ast
from collections import defaultdict
from jrnl.args import parse_args
import os
from pathlib import Path
import re
@ -14,20 +13,23 @@ from behave import given
from behave import then
from behave import when
import keyring
import toml
import yaml
from yaml.loader import SafeLoader
import jrnl.time
from jrnl import Journal
from jrnl import __version__
from jrnl import plugins
from jrnl.args import parse_args
from jrnl.behave_testing import _mock_getpass
from jrnl.behave_testing import _mock_input
from jrnl.behave_testing import _mock_time_parse
from jrnl.cli import cli
from jrnl.config import load_config
from jrnl.os_compat import split_args
from jrnl.override import apply_overrides, _recursively_apply
from jrnl.override import _recursively_apply
from jrnl.override import apply_overrides
import jrnl.time
try:
import parsedatetime.parsedatetime_consts as pdt
@ -279,42 +281,6 @@ def extension_editor_file(context, suffix):
assert filename_suffix == suffix
def _mock_getpass(inputs):
def prompt_return(prompt=""):
if type(inputs) == str:
return inputs
try:
return next(inputs)
except StopIteration:
raise KeyboardInterrupt
return prompt_return
def _mock_input(inputs):
def prompt_return(prompt=""):
try:
val = next(inputs)
print(prompt, val)
return val
except StopIteration:
raise KeyboardInterrupt
return prompt_return
def _mock_time_parse(context):
original_parse = jrnl.time.parse
if "now" not in context:
return original_parse
def wrapper(input, *args, **kwargs):
input = context.now if input == "now" else input
return original_parse(input, *args, **kwargs)
return wrapper
@when('we run "{command}" and enter')
@when('we run "{command}" and enter nothing')
@when('we run "{command}" and enter "{inputs}"')
@ -461,8 +427,9 @@ def run(context, command, text=""):
@given('we load template "{filename}"')
def load_template(context, filename):
full_path = os.path.join("features/data/templates", filename)
exporter = plugins.template_exporter.__exporter_from_file(full_path)
plugins.__exporter_types[exporter.names[0]] = exporter
plugins.collector.__exporter_types[exporter.names[0]] = exporter
@when('we set the keyring password of "{journal}" to "{password}"')
@ -540,6 +507,11 @@ def check_output_version_inline(context):
@then('the output should contain "{text}" or "{text2}"')
def check_output_inline(context, text=None, text2=None):
text = text or context.text
if "<pyproject.toml version>" in text:
pyproject = (Path(__file__) / ".." / ".." / ".." / "pyproject.toml").resolve()
pyproject_contents = toml.load(pyproject)
pyproject_version = pyproject_contents["tool"]["poetry"]["version"]
text = text.replace("<pyproject.toml version>", pyproject_version)
out = context.stdout_capture.getvalue()
assert (text and text in out) or (text2 and text2 in out)

View file

@ -89,6 +89,14 @@ def entry_array_count(context, entry_number, name, items_number):
assert len(out_json["entries"][entry_number - 1][name]) == items_number
@then('entry {entry_number:d} should not have an array "{name}"')
def entry_not_array_item(context, entry_number, name):
# note that entry_number is 1-indexed.
out = context.stdout_capture.getvalue()
out_json = json.loads(out)
assert name not in out_json["entries"][entry_number - 1]
@then("the output should be a valid XML string")
def assert_valid_xml_string(context):
output = context.stdout_capture.getvalue()

View file

@ -1,11 +1,11 @@
from jrnl.jrnl import run
from unittest import mock
# from __future__ import with_statement
from jrnl.args import parse_args
from behave import then
from features.steps.core import _mock_getpass, _mock_time_parse
from jrnl.args import parse_args
from jrnl.behave_testing import _mock_getpass
from jrnl.behave_testing import _mock_time_parse
from jrnl.jrnl import run
@then("the editor {editor} should have been called")