Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 40 additions & 40 deletions fixtures/clippings_en.result.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,240 +3,240 @@
"title":"Bad Blood: Secrets and Lies in a Silicon Valley Startup",
"content":"the reader called a photomultiplier",
"pageAt": "#27",
"createdAt":"2019-02-19T19:32:33Z"
"createdAt":"2019-02-19T19:32:33+00:00"
},
{
"title":"Bad Blood: Secrets and Lies in a Silicon Valley Startup",
"content":"Susan was mortified, but Elizabeth kept her composure and blamed a minor technical glitch.",
"pageAt": "#50",
"createdAt":"2019-02-26T09:46:01Z"
"createdAt":"2019-02-26T09:46:01+00:00"
},
{
"title":"Bad Blood: Secrets and Lies in a Silicon Valley Startup",
"content":"He was reminded of an old saying: “When you strike at the king, you must kill him.”",
"pageAt": "#51",
"createdAt":"2019-02-26T09:52:21Z"
"createdAt":"2019-02-26T09:52:21+00:00"
},
{
"title":"Bad Blood: Secrets and Lies in a Silicon Valley Startup",
"content":"Nor did he have the patience to listen to the scientists’ explanations. It was easier to just blame the cellular connection.",
"pageAt": "#73",
"createdAt":"2019-03-06T09:27:40Z"
"createdAt":"2019-03-06T09:27:40+00:00"
},
{
"title":"Bad Blood: Secrets and Lies in a Silicon Valley Startup",
"content":"In her relentless drive to be a successful startup founder, she had built a bubble around herself that was cutting her off from reality.",
"pageAt": "#80",
"createdAt":"2019-03-08T09:43:28Z"
"createdAt":"2019-03-08T09:43:28+00:00"
},
{
"title":"Bad Blood: Secrets and Lies in a Silicon Valley Startup",
"content":"They were all in their mid- to late twenties with good educations, but they valued different things.",
"pageAt": "#100",
"createdAt":"2019-03-15T09:45:52Z"
"createdAt":"2019-03-15T09:45:52+00:00"
},
{
"title":"Bad Blood: Secrets and Lies in a Silicon Valley Startup",
"content":"Not long after, a chill descended",
"pageAt": "#101",
"createdAt":"2019-03-15T09:52:16Z"
"createdAt":"2019-03-15T09:52:16+00:00"
},
{
"title":"论法的精神",
"content":"我们对局部的观察是为了对整体作出判断;研究所有的原因,是为了审视所有的结果。",
"pageAt": "#99-99",
"createdAt":"2019-03-21T09:53:15Z"
"createdAt":"2019-03-21T09:53:15+00:00"
},
{
"title":"论法的精神",
"content":"人类一旦置身于社会,软弱的情感便荡然无存;原本存在于人们之间的平等也随之消失,于是战争状态便开始了",
"pageAt": "#186-187",
"createdAt":"2019-03-21T20:43:15Z"
"createdAt":"2019-03-21T20:43:15+00:00"
},
{
"title":"论法的精神",
"content":"在和平时期,各国应该尽其所能谋求彼此间的利益的最大限度的提高;在战争状态下,尽可能地减少损失,不至于毁灭各自真正的切身利益",
"pageAt": "#194-195",
"createdAt":"2019-03-21T20:45:33Z"
"createdAt":"2019-03-21T20:45:33+00:00"
},
{
"title":"论法的精神",
"content":"事物总是要向前发展,并且要遵循某种规律运行,既不能太缓慢,也不能太迅速。但是人民的行为往往总是过于积极,或是过于消极。有时候十万只手臂能掀翻一",
"pageAt": "#263-264",
"createdAt":"2019-03-21T20:52:05Z"
"createdAt":"2019-03-21T20:52:05+00:00"
},
{
"title":"论法的精神",
"content":"这正是罗马的专政统治时间很短的原因所在,因为人民总是按照热情而绝非按规划行事。独裁官员必须具有骇人的能力,因为他们的目的在于恫吓民众,并非去惩处人民;独裁官只是为某一件事而设立,他们也只能在这件事上享有无限的权力",
"pageAt": "#317-320",
"createdAt":"2019-03-22T09:46:23Z"
"createdAt":"2019-03-22T09:46:23+00:00"
},
{
"title":"凤凰项目 一个IT运维的传奇故事",
"content":"过去十年间,CIO每两年肯定会轮换一次,就像钟表一样规律。他们在位的时间仅够理解各种首字母缩写的含义,知道卫生间在哪里,推行一堆计划和倡议,然后梦想破灭,然后走人",
"pageAt": "#5",
"createdAt":"2019-03-25T09:46:24Z"
"createdAt":"2019-03-25T09:46:24+00:00"
},
{
"title":"凤凰项目 一个IT运维的传奇故事",
"content":"我想我更关心公司的生存,而不是用不用原来的流程。",
"pageAt": "#70",
"createdAt":"2019-03-27T19:48:11Z"
"createdAt":"2019-03-27T19:48:11+00:00"
},
{
"title":"凤凰项目 一个IT运维的传奇故事",
"content":"不应该根据第一个工作站的效率来安排工作,而是根据瓶颈资源所能完成工作的速度来安排工作",
"pageAt": "#78",
"createdAt":"2019-03-27T19:56:38Z"
"createdAt":"2019-03-27T19:56:38+00:00"
},
{
"title":"凤凰项目 一个IT运维的传奇故事",
"content":"创建约束理论的艾利·高德拉特告诉我们,在瓶颈之外的任何地方作出的改进都是假象。难以置信,但千真万确!在瓶颈之后作出任何改进都是徒劳的,因为只能干等着瓶颈把工作传送过来。而在瓶颈之前作出的任何改进则只会导致瓶颈处堆积更多的库存",
"pageAt": "#78",
"createdAt":"2019-03-27T19:57:26Z"
"createdAt":"2019-03-27T19:57:26+00:00"
},
{
"title":"凤凰项目 一个IT运维的传奇故事",
"content":"“如果换作是我,我会想方设法辩解说这活儿只需要短短几分钟……”帕蒂说,“也许确实如此,但每个人的请求积少成多,这就要了命了。”",
"pageAt": "#104",
"createdAt":"2019-03-28T09:59:07Z"
"createdAt":"2019-03-28T09:59:07+00:00"
},
{
"title":"凤凰项目 一个IT运维的传奇故事",
"content":"流程是用来保护人的",
"pageAt": "#104",
"createdAt":"2019-03-28T09:59:23Z"
"createdAt":"2019-03-28T09:59:23+00:00"
},
{
"title":"凤凰项目 一个IT运维的传奇故事",
"content":"我们在接受工作之前,不对工作能力和工作要求作任何形式的分析。也就是说,我们总是在赶工,不得不走捷径,那就意味着在生产中出现更多脆弱的应用程序。也就意味着将来会出现更多的计划外工作和救火工作。因此,我们一直在原地打转",
"pageAt": "#182",
"createdAt":"2019-04-03T09:40:48Z"
"createdAt":"2019-04-03T09:40:48+00:00"
},
{
"title":"凤凰项目 一个IT运维的传奇故事",
"content":"改进日常工作比开展日常工作更重要",
"pageAt": "#200",
"createdAt":"2019-04-03T21:16:17Z"
"createdAt":"2019-04-03T21:16:17+00:00"
},
{
"title":"凤凰项目 一个IT运维的传奇故事",
"content":"代码投产之前,实际上并未产生任何价值,因为那只是困在系统里的半成品。",
"pageAt": "#282",
"createdAt":"2019-04-07T09:59:31Z"
"createdAt":"2019-04-07T09:59:31+00:00"
},
{
"title":"凤凰项目 一个IT运维的传奇故事",
"content":"有个智者曾经告诉我,‘一时的救世主固然好,但普世的圣经则更有用’。",
"pageAt": "#322",
"createdAt":"2019-04-07T11:18:42Z"
"createdAt":"2019-04-07T11:18:42+00:00"
},
{
"title":"凤凰项目 一个IT运维的传奇故事",
"content":"LinkedIn在2011年成功实施IPO之后六个月,在问题部署上吃尽苦头,于是发起了“逆向操作”行动——为期两个月的功能冻结,并因此得以彻底检修其计算环境、部署和架构体系。",
"pageAt": "#324",
"createdAt":"2019-04-08T08:58:31Z"
"createdAt":"2019-04-08T08:58:31+00:00"
},
{
"title":"凤凰项目 一个IT运维的传奇故事",
"content":"这形成了埃瑞克第三工作法的基础。他解释道:“它是关于如何建立一种文化,既能鼓励探索、从失败中吸取教训,又能理解反复的实践是精通工作的先决条件。",
"pageAt": "#324",
"createdAt":"2019-04-08T09:07:51Z"
"createdAt":"2019-04-08T09:07:51+00:00"
},
{
"title":"论法的精神",
"content":"当苏拉意欲将自由重新赋予罗马的时候,罗马却不再接受自由了。它只残留下微弱的品德。由于它的品德日益减少,所以在经历了恺撒、提贝留斯、盖犹斯、格老狄乌斯、尼禄和多密先之后,罗马仍然没有清醒过来,倒是受奴役的程度日益加深,所有的攻击都指向暴君,却没有一次是针对暴政",
"pageAt": "#410-413",
"createdAt":"2019-04-08T09:19:45Z"
"createdAt":"2019-04-08T09:19:45+00:00"
},
{
"title":"论法的精神",
"content":"生活在平民政治中的希腊政治家知道,支持他们的惟一力量来自于品德。今天的希腊人只给我们谈工艺、贸易、财政、财富,甚至谈论奢侈。",
"pageAt": "#413-414",
"createdAt":"2019-04-08T09:20:19Z"
"createdAt":"2019-04-08T09:20:19+00:00"
},
{
"title":"论法的精神",
"content":"当品德丧失时,野心便占据了易于接受它的人们的心灵,并且贪婪地占据几乎所有人的心灵",
"pageAt": "#415-416",
"createdAt":"2019-04-08T09:20:52Z"
"createdAt":"2019-04-08T09:20:52+00:00"
},
{
"title":"论法的精神",
"content":"贵族团体抑制其他人轻而易举,然而抑制自己并非易事[4]。这种政体的性质就是如此,似乎将贵族置于法律权威之下,又将他们排除在法律之外",
"pageAt": "#438-439",
"createdAt":"2019-04-08T09:24:27Z"
"createdAt":"2019-04-08T09:24:27+00:00"
},
{
"title":"论法的精神",
"content":"节制是贵族政治的灵魂。我所指的是那种建立在品德基础之上的节制,而并非那来自怯懦和精神上的怠惰的节制",
"pageAt": "#442-443",
"createdAt":"2019-04-08T09:24:47Z"
"createdAt":"2019-04-08T09:24:47+00:00"
},
{
"title":"论法的精神",
"content":"我非常了解有品德的君主并不少,然而我所说的是,在君主国里人民要具有品德是非常困难的",
"pageAt": "#453-454",
"createdAt":"2019-04-08T09:25:55Z"
"createdAt":"2019-04-08T09:25:55+00:00"
},
{
"title":"论法的精神",
"content":"专制国家的原则绝不是荣誉。那里的人们完全平等,没有人自恃优越;那里的人们也都是奴隶,没有人能比别人更一无所有",
"pageAt": "#478-479",
"createdAt":"2019-04-08T09:27:53Z"
"createdAt":"2019-04-08T09:27:53+00:00"
},
{
"title":"论法的精神",
"content":"教育的法律在各种政体中也有所区别。在君主国里,教育的法律应该是荣誉;在共和国里,则应该是品德;在专制国里就是恐怖了",
"pageAt": "#531-532",
"createdAt":"2019-04-08T20:48:25Z"
"createdAt":"2019-04-08T20:48:25+00:00"
},
{
"title":"论法的精神",
"content":"人们向我们展示的品德,往往在于自我应尽的义务,而对于他人应尽的义务却少于前者。这些品德,与其说是召唤我们去接近自己的同伴,还不如说是使我们有别于自己的同胞。",
"pageAt": "#536-538",
"createdAt":"2019-04-08T20:49:27Z"
"createdAt":"2019-04-08T20:49:27+00:00"
},
{
"title":"论法的精神",
"content":"评判人们行为的标准并不是好与坏,而是美与丑;不是正确与否,而是伟大与否;不是合理与否,而是非凡与否",
"pageAt": "#538-539",
"createdAt":"2019-04-08T20:49:47Z"
"createdAt":"2019-04-08T20:49:47+00:00"
},
{
"title":"论法的精神",
"content":"荣誉完全许可我们重视我们的财富,却绝对不许可我们重视我们的生命",
"pageAt": "#575-576",
"createdAt":"2019-04-08T20:54:13Z"
"createdAt":"2019-04-08T20:54:13+00:00"
},
{
"title":"论法的精神",
"content":"君主国家的教育致力于提高人们的心志,而专制国家的教育所追求的则是降低人民的心志",
"pageAt": "#579-580",
"createdAt":"2019-04-08T20:55:22Z"
"createdAt":"2019-04-08T20:55:22+00:00"
},
{
"title":"论法的精神",
"content":"绝对的服从便意味着服从者是愚蠢的,甚至发出命令的人也是愚蠢的,因为他丝毫不需要去思索、怀疑或者推理,他仅仅只需要表达一下自己的意愿就够了",
"pageAt": "#581-583",
"createdAt":"2019-04-08T20:55:45Z"
"createdAt":"2019-04-08T20:55:45+00:00"
},
{
"title":"论法的精神",
"content":"社会教育给予我们的说教,将父亲和师长教育的全部理念都推翻了。",
"pageAt": "#594-595",
"createdAt":"2019-04-08T20:57:05Z"
"createdAt":"2019-04-08T20:57:05+00:00"
},
{
"title":"论法的精神",
"content":"但是只有中等富裕的人才能交纳或容忍这类补偿。因为对于巨富们而言,一切与他们的权利和荣誉不相符合的东西,都会被视为是某种侮辱。",
"pageAt": "#753-754",
"createdAt":"2019-04-08T21:15:42Z"
"createdAt":"2019-04-08T21:15:42+00:00"
},
{
"title":"论法的精神",
"content":"如果说,围绕着君王们的显赫与豪华是他们权利的一部分的话,那么贵族们表面上的谦逊和朴实就是他们的力量所在[13]。当他们不矫揉造作地显示高贵时,当他们混迹于民众之中时,当他们与平民同穿素衣时,当他们与民共享所有快乐时,平民便会忘记自己的贫弱。",
"pageAt": "#819-822",
"createdAt":"2019-04-08T21:21:17Z"
"createdAt":"2019-04-08T21:21:17+00:00"
}
]
22 changes: 11 additions & 11 deletions internal/commands/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ func TestParseAllFixtures(t *testing.T) {
txtFile string
resultFile string
}{
{"English", "fixtures/clippings_en.txt", "fixtures/clippings_en.result.json"},
{"Chinese", "fixtures/clippings_zh.txt", "fixtures/clippings_zh.result.json"},
{"Other", "fixtures/clippings_other.txt", "fixtures/clippings_other.result.json"},
{"Rare", "fixtures/clippings_rare.txt", "fixtures/clippings_rare.result.json"},
{"Ric", "fixtures/clippings_ric.txt", "fixtures/clippings_ric.result.json"},
{"English", "../../fixtures/clippings_en.txt", "../../fixtures/clippings_en.result.json"},
{"Chinese", "../../fixtures/clippings_zh.txt", "../../fixtures/clippings_zh.result.json"},
{"Other", "../../fixtures/clippings_other.txt", "../../fixtures/clippings_other.result.json"},
{"Rare", "../../fixtures/clippings_rare.txt", "../../fixtures/clippings_rare.result.json"},
{"Ric", "../../fixtures/clippings_ric.txt", "../../fixtures/clippings_ric.result.json"},
Comment on lines +54 to +58

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This slice of test cases is duplicated in TestParseFixturesJSON (lines 230-234). To reduce code duplication and make the tests easier to maintain, consider defining this slice as a single package-level variable that both test functions can share.

For example, you could define this at the top of your test file:

var fixtureTestCases = []struct {
    name       string
    txtFile    string
    resultFile string
}{
    {"English", "../../fixtures/clippings_en.txt", "../../fixtures/clippings_en.result.json"},
    {"Chinese", "../../fixtures/clippings_zh.txt", "../../fixtures/clippings_zh.result.json"},
    {"Other", "../../fixtures/clippings_other.txt", "../../fixtures/clippings_other.result.json"},
    {"Rare", "../../fixtures/clippings_rare.txt", "../../fixtures/clippings_rare.result.json"},
    {"Ric", "../../fixtures/clippings_ric.txt", "../../fixtures/clippings_ric.result.json"},
}

Then, both TestParseAllFixtures and TestParseFixturesJSON can simply iterate over fixtureTestCases.

}

for _, tc := range testCases {
Expand Down Expand Up @@ -142,7 +142,7 @@ func TestParseAllFixtures(t *testing.T) {
// TestParseFixturesDiscovery automatically discovers all fixture files
func TestParseFixturesDiscovery(t *testing.T) {
// Get all .txt files in fixtures directory
txtFiles, err := filepath.Glob("fixtures/*.txt")
txtFiles, err := filepath.Glob("../../fixtures/*.txt")
if err != nil {
t.Fatalf("Failed to find fixture files: %v", err)
}
Expand Down Expand Up @@ -227,11 +227,11 @@ func TestParseFixturesJSON(t *testing.T) {
txtFile string
resultFile string
}{
{"English", "fixtures/clippings_en.txt", "fixtures/clippings_en.result.json"},
{"Chinese", "fixtures/clippings_zh.txt", "fixtures/clippings_zh.result.json"},
{"Other", "fixtures/clippings_other.txt", "fixtures/clippings_other.result.json"},
{"Rare", "fixtures/clippings_rare.txt", "fixtures/clippings_rare.result.json"},
{"Ric", "fixtures/clippings_ric.txt", "fixtures/clippings_ric.result.json"},
{"English", "../../fixtures/clippings_en.txt", "../../fixtures/clippings_en.result.json"},
{"Chinese", "../../fixtures/clippings_zh.txt", "../../fixtures/clippings_zh.result.json"},
{"Other", "../../fixtures/clippings_other.txt", "../../fixtures/clippings_other.result.json"},
{"Rare", "../../fixtures/clippings_rare.txt", "../../fixtures/clippings_rare.result.json"},
{"Ric", "../../fixtures/clippings_ric.txt", "../../fixtures/clippings_ric.result.json"},
}

for _, tc := range testCases {
Expand Down
4 changes: 2 additions & 2 deletions internal/models/clipping.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (c ClippingItem) MarshalJSON() ([]byte, error) {
CreatedAt string `json:"createdAt"`
}{
Alias: (*Alias)(&c),
CreatedAt: c.CreatedAt.UTC().Format(time.RFC3339),
CreatedAt: c.CreatedAt.UTC().Format("2006-01-02T15:04:05+00:00"),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This custom date format string is duplicated on line 64. To improve maintainability and avoid using 'magic strings', consider defining it as a package-level constant.

For example, you could add this at the top of the file:

const RFC3339Custom = "2006-01-02T15:04:05+00:00"

And then use it here and on line 64:

CreatedAt: c.CreatedAt.UTC().Format(RFC3339Custom),

This makes the code cleaner and easier to update if the format needs to change in the future.

})
}

Expand Down Expand Up @@ -61,7 +61,7 @@ func (c ClippingItem) ToClippingInput() ClippingInput {
Content: c.Content,
BookID: "0", // Default book ID
PageAt: c.PageAt,
CreatedAt: c.CreatedAt.UTC().Format(time.RFC3339),
CreatedAt: c.CreatedAt.UTC().Format("2006-01-02T15:04:05+00:00"),
Source: "kindle",
}
}
4 changes: 2 additions & 2 deletions internal/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ This is another highlight from a different book.
t.Errorf("Expected title 'The Great Gatsby', got '%s'", first.Title)
}

if first.PageAt != "#100-101" {
t.Errorf("Expected pageAt '#100-101', got '%s'", first.PageAt)
if first.PageAt != "#7" {
t.Errorf("Expected pageAt '#7', got '%s'", first.PageAt)
}

expectedContent := "In his blue gardens men and girls came and went like moths among the whisperings and the champagne and the stars."
Expand Down
Loading