mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-07-07 00:36:13 +02:00
Deploy jrnl-org/jrnl to github.com/jrnl-org/jrnl.git:gh-pages
This commit is contained in:
commit
c480368a87
104 changed files with 6140 additions and 0 deletions
60
features/core.feature
Normal file
60
features/core.feature
Normal file
|
@ -0,0 +1,60 @@
|
|||
Feature: Basic reading and writing to a journal
|
||||
|
||||
Scenario: Loading a sample journal
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl -n 2"
|
||||
Then we should get no error
|
||||
and the output should be
|
||||
"""
|
||||
2013-06-09 15:39 My first entry.
|
||||
| Everything is alright
|
||||
|
||||
2013-06-10 15:40 Life is good.
|
||||
| But I'm better.
|
||||
"""
|
||||
|
||||
Scenario: Writing an entry from command line
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl 23 july 2013: A cold and stormy day. I ate crisps on the sofa."
|
||||
Then we should see the message "Entry added"
|
||||
When we run "jrnl -n 1"
|
||||
Then the output should contain "2013-07-23 09:00 A cold and stormy day."
|
||||
|
||||
Scenario: Filtering for dates
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl -on 2013-06-10 --short"
|
||||
Then the output should be "2013-06-10 15:40 Life is good."
|
||||
When we run "jrnl -on 'june 6 2013' --short"
|
||||
Then the output should be "2013-06-10 15:40 Life is good."
|
||||
|
||||
Scenario: Emoji support
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl 23 july 2013: 🌞 sunny day. Saw an 🐘"
|
||||
Then we should see the message "Entry added"
|
||||
When we run "jrnl -n 1"
|
||||
Then the output should contain "🌞"
|
||||
and the output should contain "🐘"
|
||||
|
||||
Scenario: Writing an entry at the prompt
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl" and enter "25 jul 2013: I saw Elvis. He's alive."
|
||||
Then we should get no error
|
||||
and the journal should contain "[2013-07-25 09:00] I saw Elvis."
|
||||
and the journal should contain "He's alive."
|
||||
|
||||
Scenario: Displaying the version number
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl -v"
|
||||
Then we should get no error
|
||||
Then the output should contain "version"
|
||||
|
||||
Scenario: --short displays the short version of entries (only the title)
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl -on 2013-06-10 --short"
|
||||
Then the output should be "2013-06-10 15:40 Life is good."
|
||||
|
||||
Scenario: -s displays the short version of entries (only the title)
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl -on 2013-06-10 -s"
|
||||
Then the output should be "2013-06-10 15:40 Life is good."
|
||||
|
12
features/data/configs/basic.yaml
Normal file
12
features/data/configs/basic.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ""
|
||||
encrypt: false
|
||||
highlight: true
|
||||
journals:
|
||||
default: features/journals/simple.journal
|
||||
linewrap: 80
|
||||
tagsymbols: "@"
|
||||
template: false
|
||||
timeformat: "%Y-%m-%d %H:%M"
|
||||
indent_character: "|"
|
12
features/data/configs/brackets.yaml
Normal file
12
features/data/configs/brackets.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ""
|
||||
encrypt: false
|
||||
highlight: true
|
||||
journals:
|
||||
default: features/journals/brackets.journal
|
||||
linewrap: 80
|
||||
tagsymbols: "@"
|
||||
template: false
|
||||
timeformat: "%Y-%m-%d %H:%M"
|
||||
indent_character: "|"
|
13
features/data/configs/bug153.yaml
Normal file
13
features/data/configs/bug153.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ''
|
||||
encrypt: false
|
||||
highlight: true
|
||||
journals:
|
||||
default: features/journals/bug153.dayone
|
||||
linewrap: 80
|
||||
password: ''
|
||||
tagsymbols: '@'
|
||||
template: false
|
||||
timeformat: '%Y-%m-%d %H:%M'
|
||||
indent_character: "|"
|
13
features/data/configs/bug343.yaml
Normal file
13
features/data/configs/bug343.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ''
|
||||
template: false
|
||||
encrypt: false
|
||||
highlight: true
|
||||
journals:
|
||||
simple: features/journals/simple.journal
|
||||
work: features/journals/work.journal
|
||||
linewrap: 80
|
||||
tagsymbols: '@'
|
||||
timeformat: '%Y-%m-%d %H:%M'
|
||||
indent_character: "|"
|
13
features/data/configs/dayone.yaml
Normal file
13
features/data/configs/dayone.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ''
|
||||
template: false
|
||||
encrypt: false
|
||||
highlight: true
|
||||
journals:
|
||||
default: features/journals/dayone.dayone
|
||||
linewrap: 80
|
||||
password: ''
|
||||
tagsymbols: '@'
|
||||
timeformat: '%Y-%m-%d %H:%M'
|
||||
indent_character: "|"
|
13
features/data/configs/empty_folder.yaml
Normal file
13
features/data/configs/empty_folder.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ''
|
||||
template: false
|
||||
encrypt: false
|
||||
highlight: true
|
||||
journals:
|
||||
default: features/journals/empty_folder
|
||||
linewrap: 80
|
||||
password: ''
|
||||
tagsymbols: '@'
|
||||
timeformat: '%Y-%m-%d %H:%M'
|
||||
indent_character: "|"
|
13
features/data/configs/encrypted.yaml
Normal file
13
features/data/configs/encrypted.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ''
|
||||
encrypt: true
|
||||
template: false
|
||||
highlight: true
|
||||
journals:
|
||||
default: features/journals/encrypted.journal
|
||||
linewrap: 80
|
||||
password: ''
|
||||
tagsymbols: '@'
|
||||
timeformat: '%Y-%m-%d %H:%M'
|
||||
indent_character: "|"
|
13
features/data/configs/encrypted_old.json
Normal file
13
features/data/configs/encrypted_old.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"default_hour": 9,
|
||||
"default_minute": 0,
|
||||
"editor": "",
|
||||
"encrypt": true,
|
||||
"highlight": true,
|
||||
"journals": {
|
||||
"default": "features/journals/encrypted_jrnl-1-9-5.journal"
|
||||
},
|
||||
"linewrap": 80,
|
||||
"tagsymbols": "@",
|
||||
"timeformat": "%Y-%m-%d %H:%M"
|
||||
}
|
11
features/data/configs/encrypted_old.yaml
Normal file
11
features/data/configs/encrypted_old.yaml
Normal file
|
@ -0,0 +1,11 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ''
|
||||
encrypt: true
|
||||
highlight: true
|
||||
journals:
|
||||
default: features/journals/encrypted_jrnl1-9-5.journal
|
||||
linewrap: 80
|
||||
tagsymbols: '@'
|
||||
timeformat: '%Y-%m-%d %H:%M'
|
||||
indent_character: "|"
|
13
features/data/configs/markdown-headings-335.yaml
Normal file
13
features/data/configs/markdown-headings-335.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ''
|
||||
encrypt: false
|
||||
highlight: true
|
||||
template: false
|
||||
journals:
|
||||
default: features/journals/markdown-headings-335.journal
|
||||
linewrap: 80
|
||||
password: ''
|
||||
tagsymbols: '@'
|
||||
timeformat: '%Y-%m-%d %H:%M'
|
||||
indent_character: "|"
|
12
features/data/configs/mostlyreadabledates.yaml
Normal file
12
features/data/configs/mostlyreadabledates.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ""
|
||||
encrypt: false
|
||||
highlight: true
|
||||
journals:
|
||||
default: features/journals/mostlyreadabledates.journal
|
||||
linewrap: 80
|
||||
tagsymbols: "@"
|
||||
template: false
|
||||
timeformat: "%Y-%m-%d %H:%M"
|
||||
indent_character: "|"
|
19
features/data/configs/multiple.yaml
Normal file
19
features/data/configs/multiple.yaml
Normal file
|
@ -0,0 +1,19 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ''
|
||||
encrypt: false
|
||||
highlight: true
|
||||
template: false
|
||||
journals:
|
||||
default: features/journals/simple.journal
|
||||
ideas: features/journals/nothing.journal
|
||||
simple: features/journals/simple.journal
|
||||
work: features/journals/work.journal
|
||||
new_encrypted:
|
||||
encrypt: true
|
||||
journal: features/journals/new_encrypted.journal
|
||||
linewrap: 80
|
||||
password: ''
|
||||
tagsymbols: '@'
|
||||
timeformat: '%Y-%m-%d %H:%M'
|
||||
indent_character: "|"
|
13
features/data/configs/tags-216.yaml
Normal file
13
features/data/configs/tags-216.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ''
|
||||
encrypt: false
|
||||
highlight: true
|
||||
template: false
|
||||
journals:
|
||||
default: features/journals/tags-216.journal
|
||||
linewrap: 80
|
||||
password: ''
|
||||
tagsymbols: '@'
|
||||
timeformat: '%Y-%m-%d %H:%M'
|
||||
indent_character: "|"
|
13
features/data/configs/tags-237.yaml
Normal file
13
features/data/configs/tags-237.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ''
|
||||
encrypt: false
|
||||
highlight: true
|
||||
template: false
|
||||
journals:
|
||||
default: features/journals/tags-237.journal
|
||||
linewrap: 80
|
||||
password: ''
|
||||
tagsymbols: '@'
|
||||
timeformat: '%Y-%m-%d %H:%M'
|
||||
indent_character: "|"
|
13
features/data/configs/tags.yaml
Normal file
13
features/data/configs/tags.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ''
|
||||
encrypt: false
|
||||
highlight: true
|
||||
template: false
|
||||
journals:
|
||||
default: features/journals/tags.journal
|
||||
linewrap: 80
|
||||
password: ''
|
||||
tagsymbols: '@'
|
||||
timeformat: '%Y-%m-%d %H:%M'
|
||||
indent_character: "|"
|
12
features/data/configs/unreadabledates.yaml
Normal file
12
features/data/configs/unreadabledates.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
default_hour: 9
|
||||
default_minute: 0
|
||||
editor: ""
|
||||
encrypt: false
|
||||
highlight: true
|
||||
journals:
|
||||
default: features/journals/unreadabledates.journal
|
||||
linewrap: 80
|
||||
tagsymbols: "@"
|
||||
template: false
|
||||
timeformat: "%Y-%m-%d %H:%M"
|
||||
indent_character: "|"
|
11
features/data/configs/upgrade_from_195.json
Normal file
11
features/data/configs/upgrade_from_195.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"default_hour": 9,
|
||||
"timeformat": "%Y-%m-%d %H:%M",
|
||||
"linewrap": 80,
|
||||
"encrypt": false,
|
||||
"editor": "",
|
||||
"default_minute": 0,
|
||||
"highlight": true,
|
||||
"journals": {"default": "features/journals/simple_jrnl-1-9-5.journal"},
|
||||
"tagsymbols": "@"
|
||||
}
|
2
features/data/journals/brackets.journal
Normal file
2
features/data/journals/brackets.journal
Normal file
|
@ -0,0 +1,2 @@
|
|||
[2019-07-08 05:42] Entry subject
|
||||
[1] line starting with 1
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
||||
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Creation Date</key>
|
||||
<date>2013-10-27T02:27:27Z</date>
|
||||
<key>Creator</key>
|
||||
<dict>
|
||||
<key>Device Agent</key>
|
||||
<string>iPhone/iPhone3,1</string>
|
||||
<key>Generation Date</key>
|
||||
<date>2013-10-27T07:02:27Z</date>
|
||||
<key>Host Name</key>
|
||||
<string>omrt104001</string>
|
||||
<key>OS Agent</key>
|
||||
<string>iOS/7.0.3</string>
|
||||
<key>Software Agent</key>
|
||||
<string>Day One (iOS)/1.11.4</string>
|
||||
</dict>
|
||||
<key>Entry Text</key>
|
||||
<string>Some text.</string>
|
||||
<key>Location</key>
|
||||
<dict>
|
||||
<key>Administrative Area</key>
|
||||
<string>Östergötlands län</string>
|
||||
<key>Country</key>
|
||||
<string>Sverige</string>
|
||||
<key>Latitude</key>
|
||||
<real>58.383400000000000</real>
|
||||
<key>Locality</key>
|
||||
<string>City</string>
|
||||
<key>Longitude</key>
|
||||
<real>15.577170000000000</real>
|
||||
<key>Place Name</key>
|
||||
<string>Street</string>
|
||||
</dict>
|
||||
<key>Starred</key>
|
||||
<false/>
|
||||
<key>Time Zone</key>
|
||||
<string>Europe/Stockholm</string>
|
||||
<key>UUID</key>
|
||||
<string>B40EE704E15846DE8D45C44118A4D511</string>
|
||||
<key>Weather</key>
|
||||
<dict>
|
||||
<key>Celsius</key>
|
||||
<string>12</string>
|
||||
<key>Description</key>
|
||||
<string>Clear</string>
|
||||
<key>Fahrenheit</key>
|
||||
<string>54</string>
|
||||
<key>IconName</key>
|
||||
<string>sunnyn.png</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,52 @@
|
|||
<dict>
|
||||
<key>Creation Date</key>
|
||||
<date>2013-10-27T02:27:27Z</date>
|
||||
<key>Creator</key>
|
||||
<dict>
|
||||
<key>Device Agent</key>
|
||||
<string>iPhone/iPhone3,1</string>
|
||||
<key>Generation Date</key>
|
||||
<date>2013-10-27T07:02:27Z</date>
|
||||
<key>Host Name</key>
|
||||
<string>omrt104001</string>
|
||||
<key>OS Agent</key>
|
||||
<string>iOS/7.0.3</string>
|
||||
<key>Software Agent</key>
|
||||
<string>Day One (iOS)/1.11.4</string>
|
||||
</dict>
|
||||
<key>Entry Text</key>
|
||||
<string>This is not a valid plist.</string>
|
||||
<key>Location</key>
|
||||
<dict>
|
||||
<key>Administrative Area</key>
|
||||
<string>Östergötlands län</string>
|
||||
<key>Country</key>
|
||||
<string>Sverige</string>
|
||||
<key>Latitude</key>
|
||||
<real>58.383400000000000</real>
|
||||
<key>Locality</key>
|
||||
<string>City</string>
|
||||
<key>Longitude</key>
|
||||
<real>15.577170000000000</real>
|
||||
<key>Place Name</key>
|
||||
<string>Street</string>
|
||||
</dict>
|
||||
<key>Starred</key>
|
||||
<false/>
|
||||
<key>Time Zone</key>
|
||||
<string>Europe/Stockholm</string>
|
||||
<key>UUID</key>
|
||||
<string>B40EE704E15846DE8D45C44118A4D511</string>
|
||||
<key>Weather</key>
|
||||
<dict>
|
||||
<key>Celsius</key>
|
||||
<string>12</string>
|
||||
<key>Description</key>
|
||||
<string>Clear</string>
|
||||
<key>Fahrenheit</key>
|
||||
<string>54</string>
|
||||
<key>IconName</key>
|
||||
<string>sunnyn.png</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Creation Date</key>
|
||||
<date>2013-05-17T18:39:20Z</date>
|
||||
<key>Creator</key>
|
||||
<dict>
|
||||
<key>Device Agent</key>
|
||||
<string>Macintosh/MacBookAir5,2</string>
|
||||
<key>Generation Date</key>
|
||||
<date>2013-08-17T18:39:20Z</date>
|
||||
<key>Host Name</key>
|
||||
<string>Egeria</string>
|
||||
<key>OS Agent</key>
|
||||
<string>Mac OS X/10.8.4</string>
|
||||
<key>Software Agent</key>
|
||||
<string>Day One (Mac)/1.8</string>
|
||||
</dict>
|
||||
<key>Entry Text</key>
|
||||
<string>This entry has tags!</string>
|
||||
<key>Starred</key>
|
||||
<false/>
|
||||
<key>Tags</key>
|
||||
<array>
|
||||
<string>work</string>
|
||||
<string>PLaY</string>
|
||||
</array>
|
||||
<key>Time Zone</key>
|
||||
<string>America/Los_Angeles</string>
|
||||
<key>UUID</key>
|
||||
<string>044F3747A38546168B572C2E3F217FA2</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Creation Date</key>
|
||||
<date>2013-06-17T18:38:29Z</date>
|
||||
<key>Creator</key>
|
||||
<dict>
|
||||
<key>Device Agent</key>
|
||||
<string>Macintosh/MacBookAir5,2</string>
|
||||
<key>Generation Date</key>
|
||||
<date>2013-08-17T18:38:29Z</date>
|
||||
<key>Host Name</key>
|
||||
<string>Egeria</string>
|
||||
<key>OS Agent</key>
|
||||
<string>Mac OS X/10.8.4</string>
|
||||
<key>Software Agent</key>
|
||||
<string>Day One (Mac)/1.8</string>
|
||||
</dict>
|
||||
<key>Entry Text</key>
|
||||
<string>This entry has a location.</string>
|
||||
<key>Location</key>
|
||||
<dict>
|
||||
<key>Administrative Area</key>
|
||||
<string>California</string>
|
||||
<key>Country</key>
|
||||
<string>Germany</string>
|
||||
<key>Latitude</key>
|
||||
<real>52.4979764</real>
|
||||
<key>Locality</key>
|
||||
<string>Berlin</string>
|
||||
<key>Longitude</key>
|
||||
<real>13.2404758</real>
|
||||
<key>Place Name</key>
|
||||
<string>Abandoned Spy Tower</string>
|
||||
</dict>
|
||||
<key>Starred</key>
|
||||
<false/>
|
||||
<key>Tags</key>
|
||||
<array/>
|
||||
<key>Time Zone</key>
|
||||
<string>Europe/Berlin</string>
|
||||
<key>UUID</key>
|
||||
<string>0BDDD6CDA43C4A9AA2681517CC35AD9D</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Creation Date</key>
|
||||
<date>2013-07-17T18:38:08Z</date>
|
||||
<key>Creator</key>
|
||||
<dict>
|
||||
<key>Device Agent</key>
|
||||
<string>Macintosh/MacBookAir5,2</string>
|
||||
<key>Generation Date</key>
|
||||
<date>2013-08-17T18:38:08Z</date>
|
||||
<key>Host Name</key>
|
||||
<string>Egeria</string>
|
||||
<key>OS Agent</key>
|
||||
<string>Mac OS X/10.8.4</string>
|
||||
<key>Software Agent</key>
|
||||
<string>Day One (Mac)/1.8</string>
|
||||
</dict>
|
||||
<key>Entry Text</key>
|
||||
<string>This entry is starred!</string>
|
||||
<key>Starred</key>
|
||||
<true/>
|
||||
<key>Tags</key>
|
||||
<array/>
|
||||
<key>Time Zone</key>
|
||||
<string>America/Los_Angeles</string>
|
||||
<key>UUID</key>
|
||||
<string>422BC895507944A291E6FC44FC6B8BFC</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Creation Date</key>
|
||||
<date>2013-01-17T18:37:50Z</date>
|
||||
<key>Creator</key>
|
||||
<dict>
|
||||
<key>Device Agent</key>
|
||||
<string>Macintosh/MacBookAir5,2</string>
|
||||
<key>Generation Date</key>
|
||||
<date>2013-08-17T18:37:50Z</date>
|
||||
<key>Host Name</key>
|
||||
<string>Egeria</string>
|
||||
<key>OS Agent</key>
|
||||
<string>Mac OS X/10.8.4</string>
|
||||
<key>Software Agent</key>
|
||||
<string>Day One (Mac)/1.8</string>
|
||||
</dict>
|
||||
<key>Entry Text</key>
|
||||
<string>This is a DayOne entry without Timezone.</string>
|
||||
<key>Starred</key>
|
||||
<false/>
|
||||
<key>Tags</key>
|
||||
<array/>
|
||||
<key>UUID</key>
|
||||
<string>4BB1F46946AD439996C9B59DE7C4DDC1</string>
|
||||
</dict>
|
||||
</plist>
|
1
features/data/journals/empty_folder/empty.txt
Normal file
1
features/data/journals/empty_folder/empty.txt
Normal file
|
@ -0,0 +1 @@
|
|||
Nothing to see here
|
1
features/data/journals/encrypted.journal
Normal file
1
features/data/journals/encrypted.journal
Normal file
|
@ -0,0 +1 @@
|
|||
gAAAAABVIHB7tnwKExG7aC5ZbAbBL9SG2oY2GENeoOJ22i1PZigOvCYvrQN3kpsu0KGr7ay5K-_46R5YFlqJvtQ8anPH2FSITsaZy-l5Lz_5quw3rmzhLwAR1tc0icgtR4MEpXEdsuQ7cyb12Xq-JLDrnATs0id5Vow9Ri_tE7Xe4BXgXaySn3aRPwWKoninVxVPVvETY3MXHSUEXV9OZ-pH5kYBLGYbLA==
|
BIN
features/data/journals/encrypted_jrnl-1-9-5.journal
Normal file
BIN
features/data/journals/encrypted_jrnl-1-9-5.journal
Normal file
Binary file not shown.
42
features/data/journals/markdown-headings-335.journal
Normal file
42
features/data/journals/markdown-headings-335.journal
Normal file
|
@ -0,0 +1,42 @@
|
|||
[2015-04-14 13:23] Heading Test
|
||||
|
||||
H1-1
|
||||
=
|
||||
|
||||
H1-2
|
||||
===
|
||||
|
||||
H1-3
|
||||
============================
|
||||
|
||||
H2-1
|
||||
-
|
||||
|
||||
H2-2
|
||||
---
|
||||
|
||||
H2-3
|
||||
----------------------------------
|
||||
|
||||
Horizontal Rules (ignore)
|
||||
|
||||
---
|
||||
|
||||
===
|
||||
|
||||
# ATX H1
|
||||
|
||||
## ATX H2
|
||||
|
||||
### ATX H3
|
||||
|
||||
#### ATX H4
|
||||
|
||||
##### ATX H5
|
||||
|
||||
###### ATX H6
|
||||
|
||||
Stuff
|
||||
|
||||
More stuff
|
||||
more stuff again
|
8
features/data/journals/mostlyreadabledates.journal
Normal file
8
features/data/journals/mostlyreadabledates.journal
Normal file
|
@ -0,0 +1,8 @@
|
|||
[2019-07-18 14:23] Entry subject
|
||||
Time machines are possible. I know, because I've built one in my garage.
|
||||
|
||||
[2019-07-19 14:23] Entry subject
|
||||
I'm going to activate the machine. Nobody knows what comes next after this. Or before this?
|
||||
|
||||
[2019-07 14:23] Entry subject
|
||||
I've crossed so many timelines. Is there any going back?
|
5
features/data/journals/simple.journal
Normal file
5
features/data/journals/simple.journal
Normal file
|
@ -0,0 +1,5 @@
|
|||
[2013-06-09 15:39] My first entry.
|
||||
Everything is alright
|
||||
|
||||
[2013-06-10 15:40] Life is good.
|
||||
But I'm better.
|
13
features/data/journals/simple_jrnl-1-9-5.journal
Normal file
13
features/data/journals/simple_jrnl-1-9-5.journal
Normal file
|
@ -0,0 +1,13 @@
|
|||
2010-06-10 15:00 A life without chocolate is like a bad analogy.
|
||||
|
||||
2013-06-10 15:40 He said "[this] is the best time to be alive".
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada
|
||||
quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque
|
||||
augue et venenatis facilisis.
|
||||
|
||||
[2019-08-03 12:55] Some chat log or something
|
||||
|
||||
Suspendisse potenti. Sed dignissim sed nisl eu consequat. Aenean ante ex,
|
||||
elementum ut interdum et, mattis eget lacus. In commodo nulla nec tellus
|
||||
placerat, sed ultricies metus bibendum. Duis eget venenatis erat. In at dolor
|
||||
dui.
|
2
features/data/journals/tags-216.journal
Normal file
2
features/data/journals/tags-216.journal
Normal file
|
@ -0,0 +1,2 @@
|
|||
[2013-06-10 15:40] I programmed for @OS/2.
|
||||
Almost makes me want to go back to @C++, though. (Still better than @C#).
|
3
features/data/journals/tags-237.journal
Normal file
3
features/data/journals/tags-237.journal
Normal file
|
@ -0,0 +1,3 @@
|
|||
[2014-07-22 11:11] This entry has an email.
|
||||
@Newline tag should show as a tag.
|
||||
Kyla's @email is kyla@clevelandunderdog.org and Guinness's is guinness@fortheloveofpits.org.
|
8
features/data/journals/tags.journal
Normal file
8
features/data/journals/tags.journal
Normal file
|
@ -0,0 +1,8 @@
|
|||
[2013-04-09 15:39] I have an @idea:
|
||||
(1) write a command line @journal software
|
||||
(2) ???
|
||||
(3) PROFIT!
|
||||
|
||||
[2013-06-10 15:40] I met with @dan.
|
||||
As alway's he shared his latest @idea on how to rule the world with me.
|
||||
inst
|
5
features/data/journals/unreadabledates.journal
Normal file
5
features/data/journals/unreadabledates.journal
Normal file
|
@ -0,0 +1,5 @@
|
|||
[ashasd7zdskhz7asdkjasd] Entry subject
|
||||
I've lost track of time.
|
||||
|
||||
[sadfhakjsdf88sdf7sdff] Entry subject
|
||||
Time has no meaning.
|
0
features/data/journals/work.journal
Normal file
0
features/data/journals/work.journal
Normal file
19
features/data/templates/sample.template
Normal file
19
features/data/templates/sample.template
Normal file
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
extension: txt
|
||||
---
|
||||
|
||||
{% block journal %}
|
||||
{% for entry in entries %}
|
||||
{% include entry %}
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block entry %}
|
||||
{{ entry.title }}
|
||||
{{ "-" * len(entry.title) }}
|
||||
|
||||
{{ entry.body }}
|
||||
|
||||
{% endblock %}
|
||||
`
|
31
features/encryption.feature
Normal file
31
features/encryption.feature
Normal file
|
@ -0,0 +1,31 @@
|
|||
Feature: Encrypted journals
|
||||
Scenario: Loading an encrypted journal
|
||||
Given we use the config "encrypted.yaml"
|
||||
When we run "jrnl -n 1" and enter "bad doggie no biscuit"
|
||||
Then we should see the message "Password"
|
||||
and the output should contain "2013-06-10 15:40 Life is good"
|
||||
|
||||
Scenario: Decrypting a journal
|
||||
Given we use the config "encrypted.yaml"
|
||||
When we run "jrnl --decrypt" and enter "bad doggie no biscuit"
|
||||
Then the config for journal "default" should have "encrypt" set to "bool:False"
|
||||
Then we should see the message "Journal decrypted"
|
||||
and the journal should have 2 entries
|
||||
|
||||
Scenario: Encrypting a journal
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl --encrypt" and enter "swordfish"
|
||||
Then we should see the message "Journal encrypted"
|
||||
and the config for journal "default" should have "encrypt" set to "bool:True"
|
||||
When we run "jrnl -n 1" and enter "swordfish"
|
||||
Then we should see the message "Password"
|
||||
and the output should contain "2013-06-10 15:40 Life is good"
|
||||
|
||||
Scenario: Storing a password in Keychain
|
||||
Given we use the config "multiple.yaml"
|
||||
When we run "jrnl simple --encrypt" and enter "sabertooth"
|
||||
When we set the keychain password of "simple" to "sabertooth"
|
||||
Then the config for journal "simple" should have "encrypt" set to "bool:True"
|
||||
When we run "jrnl simple -n 1"
|
||||
Then we should not see the message "Password"
|
||||
and the output should contain "2013-06-10 15:40 Life is good"
|
42
features/environment.py
Normal file
42
features/environment.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
from behave import *
|
||||
import shutil
|
||||
import os
|
||||
import jrnl
|
||||
try:
|
||||
from io import StringIO
|
||||
except ImportError:
|
||||
from cStringIO import StringIO
|
||||
|
||||
def before_scenario(context, scenario):
|
||||
"""Before each scenario, backup all config and journal test data."""
|
||||
context.messages = StringIO()
|
||||
jrnl.util.STDERR = context.messages
|
||||
jrnl.util.TEST = True
|
||||
|
||||
# Clean up in case something went wrong
|
||||
for folder in ("configs", "journals"):
|
||||
working_dir = os.path.join("features", folder)
|
||||
if os.path.exists(working_dir):
|
||||
shutil.rmtree(working_dir)
|
||||
|
||||
|
||||
for folder in ("configs", "journals"):
|
||||
original = os.path.join("features", "data", folder)
|
||||
working_dir = os.path.join("features", folder)
|
||||
if not os.path.exists(working_dir):
|
||||
os.mkdir(working_dir)
|
||||
for filename in os.listdir(original):
|
||||
source = os.path.join(original, filename)
|
||||
if os.path.isdir(source):
|
||||
shutil.copytree(source, os.path.join(working_dir, filename))
|
||||
else:
|
||||
shutil.copy2(source, working_dir)
|
||||
|
||||
def after_scenario(context, scenario):
|
||||
"""After each scenario, restore all test data and remove working_dirs."""
|
||||
context.messages.close()
|
||||
context.messages = None
|
||||
for folder in ("configs", "journals"):
|
||||
working_dir = os.path.join("features", folder)
|
||||
if os.path.exists(working_dir):
|
||||
shutil.rmtree(working_dir)
|
85
features/exporting.feature
Normal file
85
features/exporting.feature
Normal file
|
@ -0,0 +1,85 @@
|
|||
Feature: Exporting a Journal
|
||||
|
||||
Scenario: Exporting to json
|
||||
Given we use the config "tags.yaml"
|
||||
When we run "jrnl --export json"
|
||||
Then we should get no error
|
||||
and the output should be parsable as json
|
||||
and "entries" in the json output should have 2 elements
|
||||
and "tags" in the json output should contain "@idea"
|
||||
and "tags" in the json output should contain "@journal"
|
||||
and "tags" in the json output should contain "@dan"
|
||||
|
||||
Scenario: Exporting using filters should only export parts of the journal
|
||||
Given we use the config "tags.yaml"
|
||||
When we run "jrnl -until 'may 2013' --export json"
|
||||
# Then we should get no error
|
||||
Then the output should be parsable as json
|
||||
and "entries" in the json output should have 1 element
|
||||
and "tags" in the json output should contain "@idea"
|
||||
and "tags" in the json output should contain "@journal"
|
||||
and "tags" in the json output should not contain "@dan"
|
||||
|
||||
Scenario: Exporting using custom templates
|
||||
Given we use the config "basic.yaml"
|
||||
Given we load template "sample.template"
|
||||
When we run "jrnl --export sample"
|
||||
Then the output should be
|
||||
"""
|
||||
My first entry.
|
||||
---------------
|
||||
|
||||
Everything is alright
|
||||
|
||||
Life is good.
|
||||
-------------
|
||||
|
||||
But I'm better.
|
||||
"""
|
||||
|
||||
Scenario: Increasing Headings on Markdown export
|
||||
Given we use the config "markdown-headings-335.yaml"
|
||||
When we run "jrnl --export markdown"
|
||||
Then the output should be
|
||||
"""
|
||||
# 2015
|
||||
|
||||
## April
|
||||
|
||||
### 2015-04-14 13:23 Heading Test
|
||||
|
||||
#### H1-1
|
||||
|
||||
#### H1-2
|
||||
|
||||
#### H1-3
|
||||
|
||||
##### H2-1
|
||||
|
||||
##### H2-2
|
||||
|
||||
##### H2-3
|
||||
|
||||
Horizontal Rules (ignore)
|
||||
|
||||
---
|
||||
|
||||
===
|
||||
|
||||
#### ATX H1
|
||||
|
||||
##### ATX H2
|
||||
|
||||
###### ATX H3
|
||||
|
||||
####### ATX H4
|
||||
|
||||
######## ATX H5
|
||||
|
||||
######### ATX H6
|
||||
|
||||
Stuff
|
||||
|
||||
More stuff
|
||||
more stuff again
|
||||
"""
|
46
features/multiple_journals.feature
Normal file
46
features/multiple_journals.feature
Normal file
|
@ -0,0 +1,46 @@
|
|||
Feature: Multiple journals
|
||||
|
||||
Scenario: Loading a config with two journals
|
||||
Given we use the config "multiple.yaml"
|
||||
Then journal "default" should have 2 entries
|
||||
and journal "work" should have 0 entries
|
||||
|
||||
Scenario: Write to default config by default
|
||||
Given we use the config "multiple.yaml"
|
||||
When we run "jrnl this goes to default"
|
||||
Then journal "default" should have 3 entries
|
||||
and journal "work" should have 0 entries
|
||||
|
||||
Scenario: Write to specified journal
|
||||
Given we use the config "multiple.yaml"
|
||||
When we run "jrnl work a long day in the office"
|
||||
Then journal "default" should have 2 entries
|
||||
and journal "work" should have 1 entry
|
||||
|
||||
Scenario: Tell user which journal was used
|
||||
Given we use the config "multiple.yaml"
|
||||
When we run "jrnl work a long day in the office"
|
||||
Then we should see the message "Entry added to work journal"
|
||||
|
||||
Scenario: Write to specified journal with a timestamp
|
||||
Given we use the config "multiple.yaml"
|
||||
When we run "jrnl work 23 july 2012: a long day in the office"
|
||||
Then journal "default" should have 2 entries
|
||||
and journal "work" should have 1 entry
|
||||
and journal "work" should contain "2012-07-23"
|
||||
|
||||
Scenario: Create new journals as required
|
||||
Given we use the config "multiple.yaml"
|
||||
Then journal "ideas" should not exist
|
||||
When we run "jrnl ideas 23 july 2012: sell my junk on ebay and make lots of money"
|
||||
Then journal "ideas" should have 1 entry
|
||||
|
||||
Scenario: Don't crash if no default journal is specified
|
||||
Given we use the config "bug343.yaml"
|
||||
When we run "jrnl a long day in the office"
|
||||
Then we should see the message "No default journal configured"
|
||||
|
||||
Scenario: Don't crash if no file exists for a configured encrypted journal
|
||||
Given we use the config "multiple.yaml"
|
||||
When we run "jrnl new_encrypted Adding first entry" and enter "these three eyes"
|
||||
Then we should see the message "Journal 'new_encrypted' created"
|
64
features/regression.feature
Normal file
64
features/regression.feature
Normal file
|
@ -0,0 +1,64 @@
|
|||
Feature: Zapped bugs should stay dead.
|
||||
|
||||
Scenario: Writing an entry does not print the entire journal
|
||||
# https://github.com/maebert/jrnl/issues/87
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl 23 july 2013: A cold and stormy day. I ate crisps on the sofa."
|
||||
Then we should see the message "Entry added"
|
||||
When we run "jrnl -n 1"
|
||||
Then the output should not contain "Life is good"
|
||||
|
||||
Scenario: Date with time should be parsed correctly
|
||||
# https://github.com/maebert/jrnl/issues/117
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl 2013-11-30 15:42: Project Started."
|
||||
Then we should see the message "Entry added"
|
||||
and the journal should contain "[2013-11-30 15:42] Project Started."
|
||||
|
||||
Scenario: Date in the future should be parsed correctly
|
||||
# https://github.com/maebert/jrnl/issues/185
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl 26/06/2019: Planet? Earth. Year? 2019."
|
||||
Then we should see the message "Entry added"
|
||||
and the journal should contain "[2019-06-26 09:00] Planet?"
|
||||
|
||||
Scenario: Loading entry with ambiguous time stamp
|
||||
#https://github.com/maebert/jrnl/issues/153
|
||||
Given we use the config "bug153.yaml"
|
||||
When we run "jrnl -1"
|
||||
Then we should get no error
|
||||
and the output should be
|
||||
"""
|
||||
2013-10-27 03:27 Some text.
|
||||
"""
|
||||
|
||||
Scenario: Title with an embedded period.
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl 04-24-2014: Created a new website - empty.com. Hope to get a lot of traffic."
|
||||
Then we should see the message "Entry added"
|
||||
When we run "jrnl -1"
|
||||
Then the output should be
|
||||
"""
|
||||
2014-04-24 09:00 Created a new website - empty.com.
|
||||
| Hope to get a lot of traffic.
|
||||
"""
|
||||
|
||||
Scenario: Integers in square brackets should not be read as dates
|
||||
Given we use the config "brackets.yaml"
|
||||
When we run "jrnl -1"
|
||||
Then the output should contain "[1] line starting with 1"
|
||||
|
||||
Scenario: Journals with unreadable dates should still be viewable
|
||||
Given we use the config "unreadabledates.yaml"
|
||||
When we run "jrnl -2"
|
||||
Then the output should contain "I've lost track of time."
|
||||
Then the output should contain "Time has no meaning."
|
||||
|
||||
Scenario: Journals with readable dates AND unreadable dates should still contain all data.
|
||||
Given we use the config "mostlyreadabledates.yaml"
|
||||
When we run "jrnl -3"
|
||||
Then the output should contain "Time machines are possible."
|
||||
When we run "jrnl -1"
|
||||
Then the output should contain "I'm going to activate the machine."
|
||||
Then the output should contain "I've crossed so many timelines. Is there any going back?"
|
||||
|
20
features/starring.feature
Normal file
20
features/starring.feature
Normal file
|
@ -0,0 +1,20 @@
|
|||
Feature: Starring entries
|
||||
|
||||
Scenario: Starring an entry will mark it in the journal file
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl 20 july 2013 *: Best day of my life!"
|
||||
Then we should see the message "Entry added"
|
||||
and the journal should contain "[2013-07-20 09:00] Best day of my life! *"
|
||||
|
||||
Scenario: Filtering by starred entries
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl -starred"
|
||||
Then the output should be
|
||||
"""
|
||||
"""
|
||||
When we run "jrnl 20 july 2013 *: Best day of my life!"
|
||||
When we run "jrnl -starred"
|
||||
Then the output should be
|
||||
"""
|
||||
2013-07-20 09:00 Best day of my life!
|
||||
"""
|
260
features/steps/core.py
Normal file
260
features/steps/core.py
Normal file
|
@ -0,0 +1,260 @@
|
|||
from __future__ import unicode_literals
|
||||
from __future__ import absolute_import
|
||||
|
||||
from behave import given, when, then
|
||||
from jrnl import cli, install, Journal, util, plugins
|
||||
from jrnl import __version__
|
||||
from dateutil import parser as date_parser
|
||||
from collections import defaultdict
|
||||
import os
|
||||
import json
|
||||
import yaml
|
||||
import keyring
|
||||
|
||||
|
||||
class TestKeyring(keyring.backend.KeyringBackend):
|
||||
"""A test keyring that just stores its valies in a hash"""
|
||||
|
||||
priority = 1
|
||||
keys = defaultdict(dict)
|
||||
|
||||
def set_password(self, servicename, username, password):
|
||||
self.keys[servicename][username] = password
|
||||
|
||||
def get_password(self, servicename, username):
|
||||
return self.keys[servicename].get(username)
|
||||
|
||||
def delete_password(self, servicename, username, password):
|
||||
self.keys[servicename][username] = None
|
||||
|
||||
# set the keyring for keyring lib
|
||||
keyring.set_keyring(TestKeyring())
|
||||
|
||||
|
||||
try:
|
||||
from io import StringIO
|
||||
except ImportError:
|
||||
from cStringIO import StringIO
|
||||
import tzlocal
|
||||
import shlex
|
||||
import sys
|
||||
|
||||
|
||||
def ushlex(command):
|
||||
if sys.version_info[0] == 3:
|
||||
return shlex.split(command)
|
||||
return map(lambda s: s.decode('UTF8'), shlex.split(command.encode('utf8')))
|
||||
|
||||
|
||||
def read_journal(journal_name="default"):
|
||||
config = util.load_config(install.CONFIG_FILE_PATH)
|
||||
with open(config['journals'][journal_name]) as journal_file:
|
||||
journal = journal_file.read()
|
||||
return journal
|
||||
|
||||
|
||||
def open_journal(journal_name="default"):
|
||||
config = util.load_config(install.CONFIG_FILE_PATH)
|
||||
journal_conf = config['journals'][journal_name]
|
||||
if type(journal_conf) is dict: # We can override the default config on a by-journal basis
|
||||
config.update(journal_conf)
|
||||
else: # But also just give them a string to point to the journal file
|
||||
config['journal'] = journal_conf
|
||||
return Journal.open_journal(journal_name, config)
|
||||
|
||||
|
||||
@given('we use the config "{config_file}"')
|
||||
def set_config(context, config_file):
|
||||
full_path = os.path.join("features/configs", config_file)
|
||||
install.CONFIG_FILE_PATH = os.path.abspath(full_path)
|
||||
if config_file.endswith("yaml"):
|
||||
# Add jrnl version to file for 2.x journals
|
||||
with open(install.CONFIG_FILE_PATH, 'a') as cf:
|
||||
cf.write("version: {}".format(__version__))
|
||||
|
||||
|
||||
@when('we run "{command}" and enter')
|
||||
@when('we run "{command}" and enter "{inputs}"')
|
||||
def run_with_input(context, command, inputs=None):
|
||||
text = inputs or context.text
|
||||
args = ushlex(command)[1:]
|
||||
buffer = StringIO(text.strip())
|
||||
util.STDIN = buffer
|
||||
try:
|
||||
cli.run(args or [])
|
||||
context.exit_status = 0
|
||||
except SystemExit as e:
|
||||
context.exit_status = e.code
|
||||
|
||||
|
||||
@when('we run "{command}"')
|
||||
def run(context, command):
|
||||
args = ushlex(command)[1:]
|
||||
try:
|
||||
cli.run(args or None)
|
||||
context.exit_status = 0
|
||||
except SystemExit as e:
|
||||
context.exit_status = e.code
|
||||
|
||||
|
||||
@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
|
||||
|
||||
|
||||
@when('we set the keychain password of "{journal}" to "{password}"')
|
||||
def set_keychain(context, journal, password):
|
||||
keyring.set_password('jrnl', journal, password)
|
||||
|
||||
|
||||
@then('we should get an error')
|
||||
def has_error(context):
|
||||
assert context.exit_status != 0, context.exit_status
|
||||
|
||||
|
||||
@then('we should get no error')
|
||||
def no_error(context):
|
||||
assert context.exit_status is 0, context.exit_status
|
||||
|
||||
|
||||
@then('the output should be parsable as json')
|
||||
def check_output_json(context):
|
||||
out = context.stdout_capture.getvalue()
|
||||
assert json.loads(out), out
|
||||
|
||||
|
||||
@then('"{field}" in the json output should have {number:d} elements')
|
||||
@then('"{field}" in the json output should have 1 element')
|
||||
def check_output_field(context, field, number=1):
|
||||
out = context.stdout_capture.getvalue()
|
||||
out_json = json.loads(out)
|
||||
assert field in out_json, [field, out_json]
|
||||
assert len(out_json[field]) == number, len(out_json[field])
|
||||
|
||||
|
||||
@then('"{field}" in the json output should not contain "{key}"')
|
||||
def check_output_field_not_key(context, field, key):
|
||||
out = context.stdout_capture.getvalue()
|
||||
out_json = json.loads(out)
|
||||
assert field in out_json
|
||||
assert key not in out_json[field]
|
||||
|
||||
|
||||
@then('"{field}" in the json output should contain "{key}"')
|
||||
def check_output_field_key(context, field, key):
|
||||
out = context.stdout_capture.getvalue()
|
||||
out_json = json.loads(out)
|
||||
assert field in out_json
|
||||
assert key in out_json[field]
|
||||
|
||||
|
||||
@then('the json output should contain {path} = "{value}"')
|
||||
def check_json_output_path(context, path, value):
|
||||
""" E.g.
|
||||
the json output should contain entries.0.title = "hello"
|
||||
"""
|
||||
out = context.stdout_capture.getvalue()
|
||||
struct = json.loads(out)
|
||||
|
||||
for node in path.split('.'):
|
||||
try:
|
||||
struct = struct[int(node)]
|
||||
except ValueError:
|
||||
struct = struct[node]
|
||||
assert struct == value, struct
|
||||
|
||||
|
||||
@then('the output should be')
|
||||
@then('the output should be "{text}"')
|
||||
def check_output(context, text=None):
|
||||
text = (text or context.text).strip().splitlines()
|
||||
out = context.stdout_capture.getvalue().strip().splitlines()
|
||||
assert len(text) == len(out), "Output has {} lines (expected: {})".format(len(out), len(text))
|
||||
for line_text, line_out in zip(text, out):
|
||||
assert line_text.strip() == line_out.strip(), [line_text.strip(), line_out.strip()]
|
||||
|
||||
|
||||
@then('the output should contain "{text}" in the local time')
|
||||
def check_output_time_inline(context, text):
|
||||
out = context.stdout_capture.getvalue()
|
||||
local_tz = tzlocal.get_localzone()
|
||||
utc_time = date_parser.parse(text)
|
||||
local_date = utc_time.astimezone(local_tz).strftime("%Y-%m-%d %H:%M")
|
||||
assert local_date in out, local_date
|
||||
|
||||
|
||||
@then('the output should contain')
|
||||
@then('the output should contain "{text}"')
|
||||
def check_output_inline(context, text=None):
|
||||
text = text or context.text
|
||||
out = context.stdout_capture.getvalue()
|
||||
if isinstance(out, bytes):
|
||||
out = out.decode('utf-8')
|
||||
assert text in out, text
|
||||
|
||||
|
||||
@then('the output should not contain "{text}"')
|
||||
def check_output_not_inline(context, text):
|
||||
out = context.stdout_capture.getvalue()
|
||||
if isinstance(out, bytes):
|
||||
out = out.decode('utf-8')
|
||||
assert text not in out
|
||||
|
||||
|
||||
@then('we should see the message "{text}"')
|
||||
def check_message(context, text):
|
||||
out = context.messages.getvalue()
|
||||
assert text in out, [text, out]
|
||||
|
||||
|
||||
@then('we should not see the message "{text}"')
|
||||
def check_not_message(context, text):
|
||||
out = context.messages.getvalue()
|
||||
assert text not in out, [text, out]
|
||||
|
||||
|
||||
@then('the journal should contain "{text}"')
|
||||
@then('journal "{journal_name}" should contain "{text}"')
|
||||
def check_journal_content(context, text, journal_name="default"):
|
||||
journal = read_journal(journal_name)
|
||||
assert text in journal, journal
|
||||
|
||||
|
||||
@then('journal "{journal_name}" should not exist')
|
||||
def journal_doesnt_exist(context, journal_name="default"):
|
||||
with open(install.CONFIG_FILE_PATH) as config_file:
|
||||
config = yaml.load(config_file, Loader=yaml.FullLoader)
|
||||
journal_path = config['journals'][journal_name]
|
||||
assert not os.path.exists(journal_path)
|
||||
|
||||
|
||||
@then('the config should have "{key}" set to "{value}"')
|
||||
@then('the config for journal "{journal}" should have "{key}" set to "{value}"')
|
||||
def config_var(context, key, value, journal=None):
|
||||
t, value = value.split(":")
|
||||
value = {
|
||||
"bool": lambda v: v.lower() == "true",
|
||||
"int": int,
|
||||
"str": str
|
||||
}[t](value)
|
||||
config = util.load_config(install.CONFIG_FILE_PATH)
|
||||
if journal:
|
||||
config = config["journals"][journal]
|
||||
assert key in config
|
||||
assert config[key] == value
|
||||
|
||||
|
||||
@then('the journal should have {number:d} entries')
|
||||
@then('the journal should have {number:d} entry')
|
||||
@then('journal "{journal_name}" should have {number:d} entries')
|
||||
@then('journal "{journal_name}" should have {number:d} entry')
|
||||
def check_journal_entries(context, number, journal_name="default"):
|
||||
journal = open_journal(journal_name)
|
||||
assert len(journal.entries) == number
|
||||
|
||||
|
||||
@then('fail')
|
||||
def debug_fail(context):
|
||||
assert False
|
84
features/tagging.feature
Normal file
84
features/tagging.feature
Normal file
|
@ -0,0 +1,84 @@
|
|||
Feature: Tagging
|
||||
|
||||
Scenario: Displaying tags
|
||||
Given we use the config "tags.yaml"
|
||||
When we run "jrnl --tags"
|
||||
Then we should get no error
|
||||
and the output should be
|
||||
"""
|
||||
@idea : 2
|
||||
@journal : 1
|
||||
@dan : 1
|
||||
"""
|
||||
|
||||
Scenario: Filtering journals should also filter tags
|
||||
Given we use the config "tags.yaml"
|
||||
When we run "jrnl -from 'may 2013' --tags"
|
||||
Then we should get no error
|
||||
and the output should be
|
||||
"""
|
||||
@idea : 1
|
||||
@dan : 1
|
||||
"""
|
||||
|
||||
Scenario: Tags should allow certain special characters
|
||||
Given we use the config "tags-216.yaml"
|
||||
When we run "jrnl --tags"
|
||||
Then we should get no error
|
||||
and the output should be
|
||||
"""
|
||||
@os/2 : 1
|
||||
@c++ : 1
|
||||
@c# : 1
|
||||
"""
|
||||
Scenario: An email should not be a tag
|
||||
Given we use the config "tags-237.yaml"
|
||||
When we run "jrnl --tags"
|
||||
Then we should get no error
|
||||
and the output should be
|
||||
"""
|
||||
@newline : 1
|
||||
@email : 1
|
||||
"""
|
||||
|
||||
Scenario: Entry cans start and end with tags
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl today: @foo came over, we went to a @bar"
|
||||
When we run "jrnl --tags"
|
||||
Then the output should be
|
||||
"""
|
||||
@foo : 1
|
||||
@bar : 1
|
||||
"""
|
||||
|
||||
Scenario: Excluding a tag should filter it
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl today: @foo came over, we went to a bar"
|
||||
When we run "jrnl I have decided I did not enjoy that @bar"
|
||||
When we run "jrnl --tags -not @bar"
|
||||
Then the output should be
|
||||
"""
|
||||
@foo : 1
|
||||
"""
|
||||
|
||||
Scenario: Excluding a tag should filter an entry, even if an unfiltered tag is in that entry
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl today: I do @not think this will show up @thought"
|
||||
When we run "jrnl today: I think this will show up @thought"
|
||||
When we run "jrnl --tags -not @not"
|
||||
Then the output should be
|
||||
"""
|
||||
@thought : 1
|
||||
"""
|
||||
|
||||
Scenario: Excluding multiple tags should filter them
|
||||
Given we use the config "basic.yaml"
|
||||
When we run "jrnl today: I do @not think this will show up @thought"
|
||||
When we run "jrnl today: I think this will show up @thought"
|
||||
When we run "jrnl today: This should @never show up @thought"
|
||||
When we run "jrnl today: What a nice day for filtering @thought"
|
||||
When we run "jrnl --tags -not @not @never"
|
||||
Then the output should be
|
||||
"""
|
||||
@thought : 2
|
||||
"""
|
23
features/upgrade.feature
Normal file
23
features/upgrade.feature
Normal file
|
@ -0,0 +1,23 @@
|
|||
Feature: Upgrading Journals from 1.x.x to 2.x.x
|
||||
|
||||
Scenario: Upgrade and parse journals with square brackets
|
||||
Given we use the config "upgrade_from_195.json"
|
||||
When we run "jrnl -9" and enter "Y"
|
||||
Then the output should contain
|
||||
"""
|
||||
2010-06-10 15:00 A life without chocolate is like a bad analogy.
|
||||
|
||||
2013-06-10 15:40 He said "[this] is the best time to be alive".
|
||||
"""
|
||||
Then the journal should have 2 entries
|
||||
|
||||
Scenario: Upgrading a journal encrypted with jrnl 1.x
|
||||
Given we use the config "encrypted_old.json"
|
||||
When we run "jrnl -n 1" and enter
|
||||
"""
|
||||
Y
|
||||
bad doggie no biscuit
|
||||
bad doggie no biscuit
|
||||
"""
|
||||
Then we should see the message "Password"
|
||||
and the output should contain "2013-06-10 15:40 Life is good"
|
Loading…
Add table
Add a link
Reference in a new issue