1 module unittesting.articlegenerator; 2 3 import std.datetime; 4 import std.random; 5 import std.range; 6 7 import vibe.data.json; 8 9 import devto.api; 10 11 @safe: 12 13 string articleTemplate = `{ 14 "published_at":null, 15 "canonical_url":"https://dev.to/username/articleslug", 16 "comments_count":0, 17 "page_views_count":0, 18 "id":111111, 19 "published_timestamp":"2020-01-16T01:22:00Z", 20 "positive_reactions_count":0, 21 "published":false, 22 "body_markdown":"Text used in the article.", 23 "title":"Title of the Article", 24 "url":"https://dev.to/username/articleslug", 25 "user":{ 26 "username":"username", 27 "profile_image":"https://res.cloudinary.com/practicaldev/SomeImage.png", 28 "github_username":"GitHubUserName", 29 "profile_image_90":"https://res.cloudinary.com/practicaldev/SomeImage.png", 30 "website_url":"https://www.example.com", 31 "twitter_username":null, 32 "name":"User Name" 33 }, 34 "cover_image":null, 35 "slug":"articleslug", 36 "description":"", 37 "path":"/username/articleslug", 38 "tag_list":[ 39 "testing" 40 ], 41 "type_of":"article" 42 }`; 43 44 /** 45 * Provides an initial article template for testing. 46 * 47 * It is expected to be combined with std.range.generate and seqence. 48 * 49 * `generate!fakeArticleMe.seqence().take(3);` 50 */ 51 auto fakeArticleMe() { 52 // Deep copy Json object 53 return articleTemplate.parseJsonString; 54 } 55 56 /** 57 */ 58 auto seqence(R)(R articles, SysTime newestDate = Clock.currTime) 59 if(is(ElementType!R == Json)) { 60 struct DateSequencing { 61 DateTime date; 62 uint id = 10_000; 63 R inner; 64 65 auto empty () { 66 if(inner.empty) return true; 67 if(id < 2) return true; 68 return false; 69 } 70 71 auto front() { 72 auto ans = inner.front; 73 ans["id"] = Json(id); 74 // DateTime has no timezone, we pretend it is UTC after cast 75 ans["published_timestamp"] = Json(date.toISOExtString ~ "Z"); 76 return ans; 77 } 78 79 auto popFront() { 80 inner.popFront(); 81 id--; 82 date -= dur!"days"(uniform(1,12)); 83 } 84 } 85 86 DateSequencing ds; 87 ds.date = cast(DateTime) newestDate; 88 ds.inner = articles; 89 return ds; 90 } unittest { 91 import std.algorithm : equal, map, isSorted; 92 auto seq = generate!fakeArticleMe.seqence(Clock.currTime).take(3); 93 assert(seq.map!(x => x["id"].get!uint).equal([10_000, 9_999, 9_998])); 94 assert(seq.map!(x => x["published_timestamp"].get!string).array.isSorted!"a > b"); 95 }