#elixir-lang - 09 May 2019
« Back 1 day Forward 1 day »
[07:53:49] micmus: gamache: if you haven't found solutions yet, killed usually means some linked process was "brutally terminated" with the untrappable kill reason. It's probably not the only process terminating you'll find in the logs
[10:12:28] gonz_: I switched back to my trusty XMonad-centric Linux workflow, but I have two Win10 Pro licenses and I'd be happy to use them in some context if Windows stops feeling like a second hand choice for dev
[10:14:55] jkva: My google-fu is failing me; can I use pattern matching to ensure an argument is of a certain struct? Without inspecting its data much further?
[10:16:59] gonz_: Implicitly the `__struct__` field in the map will be checked (or so I've always assumed)
[10:39:31] jkva: dysfun: do you know if there's a list of builtin language functions / macros? I see an existing function being used called `struct` but I can't find where that is defined
[11:43:35] Sentreen: Hey guys, is there some way to force iex to not truncate long binaries (and to print them as strings)?
[11:46:45] Sentreen: Right, but is there a way to automatically apply this to any value iex receives?
[11:47:16] Sentreen: Context: I'm a debugging session where erlport is throwing a lot of errors from python, which are trick to catch and inspect.
[12:05:01] nickjj: this article is nearly 2 years old, is a better method for sharing fixtures between modules available than what's been posted here? https://medium.com/@ejpcmac/sharing-fixtures-between-test-modules-in-elixir-15add7c7cbd2
[12:07:24] nickjj: the docs mostly just say to inline functions that create resources for that specific file, but then you get yourself into the problem that the article covers
[12:09:37] dysfun: okay, so we have test/support/helpers.ex with a bunch of functions in for creating records in the database, they all use the bang variants so it errors if they failed to insert
[12:09:58] dysfun: this is ultimately powered by faker (at the minute), which is just a cheap way of generating vaguely realistic looking data
[12:10:43] nickjj: code example would definitely help, i am 100% following you so far but i still get hung up with syntax at this point
[12:12:31] dysfun: the Map.put_new_lazy puts a value from a function if the key is not already defined
[12:13:23] dysfun: so we specify the fields we care about for this test and let it generate the rest
[12:13:26] nickjj: ah, so it ends up filling out a complete user, but you can overwrite whatever field you want on a per test basis?
[12:14:06] dysfun: we have a whole load of functions like that that generate data for all our models
[12:14:40] nickjj: how does &uuid end up turning into a uuid? do you have a private function in there that simply generates a random uuid with faker?
[12:14:46] dysfun: and we have the advantage of not having to keep open the seeds.exs or fixtures file at the same time
[12:15:31] nickjj: any reason for that being outside of this user function but the name and phone are in user? are those 2 fields just specific to users but you use emails and is_admin all over the place?
[12:16:47] dysfun: here are those utilities for making faker do what we want. i think that's everything it needs
[12:17:34] nickjj: thanks, that looks a bit more involved than what i envisioned in my head for guaranteeing uniqueness
[12:18:16] dysfun: heh, it was thrown together quickly because i needed some guarantees for my tests
[12:19:02] nickjj: yeah, i'm a big fan of faker (i've used it in other languages for tests and seeding development dbs)
[12:19:49] nickjj: it's interesting, your strategy is similiar to what changelog.com is doing -- but i couldn't reverse engineer how a certain function was able to be called
[12:20:05] nickjj: because the code base didn't have a single function definition for the function they were calling
[12:21:17] nickjj: because they have examples like this all over their tests: ep1 = insert(:published_episode, title: "The Best", subtitle: "Evar!")
[12:21:38] nickjj: but it's the same strategy as you explained , it creates a published episode and overwrites the title/subtitle on demand
[12:22:01] nickjj: but then they also use it like this to make a different resource: p = insert(:podcast, slug: "jsparty")
[12:24:07] dysfun: i haven't looked, but i'm guessing they start with a `use` which inserts that behind the scenes
[12:24:23] nickjj: they have this: https://github.com/thechangelog/changelog.com/blob/master/lib/changelog/schema/factory.ex
[12:25:00] nickjj: and then they import that factory in their support/data_case (they renamed it to schema_case) https://github.com/thechangelog/changelog.com/blob/master/test/support/schema_case.ex
[12:27:13] nickjj: in the sense that, this factory module becomes something you can use in the way they use it
[12:28:48] nickjj: going by the docs maybe exmachina isn't even needed if you set up your own fixtures/etc. with faker?
[12:30:18] nickjj: if anything it's an abstraction of your strategy (whether it's good or bad is debatable)
[12:30:58] nickjj: personally i'd rather have ~50 lines of test support code i own than pull in something like that
[12:33:01] mdbm: what is the difference between "use" and "@behaviour", why do I write use GenServer and not @behaviour GenServer
[12:33:05] nickjj: btw, why did you put it in test/support/helpers.ex and not test/test_helpers.exs?
[12:36:30] dysfun: actually i slightly lied. the fake data generators are in test/support/fake.ex and we wrap them together with a call to changeset and repo.insert in test/support/helpers.ex
[12:39:10] nickjj: just for completeness would you be able to provide an example of fake_user(opts) in helpers.ex?
[12:40:41] dysfun: others take a map of options, but in this case, the only thing we care about is is_admin
[12:44:24] dysfun: some of them take the mandatory arguments first then the last is an optional overrides map
[12:45:14] nickjj: so like this then? https://gist.github.com/nickjj/9b3ab019700006d56dffd2305abd83f1
[12:45:25] dysfun: (this is how we handle foreign keys, for example, you pass in the fake user to make the fake shop etc.
[12:48:10] dysfun: in our case it's users and tenants are linked together rather than users and shops
[12:49:01] nickjj: does the fake_user_tenant function look pretty much the same as the fake_user gist?
[12:52:38] nickjj: haha, i was actually about to say "hey, if you have a blog, you should make a write up of this at some point"
[12:53:31] nickjj: my elixir knowledge is still lackluster but i do have 200+ posts on my site (sucky or not is also debatable!)
[12:55:17] nickjj: mine isn't very oriented towards elixir yet, it's on all sorts of programming related topics https://nickjanetakis.com/blog/
[13:02:00] nickjj: no, i was being semi-sarcastic, honestly i write most of my posts as personal documentation and publish it in off chance it can help someone else, 0 expectations basically
[13:02:34] mdbm: nickjj, yeah I found two interesting articles for me, most recent are about Docker and I still don't know why I need this lol
[13:02:40] dysfun: i'm only interested in having a blog again so i can link people to these things rather than explain them again
[13:06:52] nickjj: dysfun, if you like writing, it's definitely fun, and not too demanding to get up and running with so many static site generators being available
[13:08:00] mdbm: if I didn't write what I learned, with all there is to learn, I would forget most, that's why I'm writing on my blog as well, more like personal notes
[13:10:08] nickjj: yeah it's scary when you start racking up years of experience but at the same time you can't remember what you had for dinner 4 nights ago
[13:14:28] nickjj: was it harder than finding out you needed to add "a" after a list of strings using the ~w() syntax when upgrading to phoenix 1.4?
[13:14:59] nickjj: because that took like 15min of googling and i think i had like 20 tabs open before i found the answer
[13:15:17] Nicd-: so in my experience that was very very easy as you just told it to me without having to look for it
[13:16:51] nickjj: OliverMT, yes but after upgrading i was getting errors due to not having that, but the error wasn't entirely clear for someone who is still not 100% comfy with elixir yet, the stack trace made it seem like the error was cased by a different part of code
[13:21:11] nickjj: Nicd-, in that case your way makes sense, i probably had just copied the syntax over from another place that had 4-5 fields instead of 1
[13:26:13] nickjj: dysfun, you know, after all that, i stumbled on that PDF "what's new in ecto 2.0", have you glanced this at some point?
[13:27:23] nickjj: it has a blurb on creating test data using a pretty similar strategy as you (they don't use faker but that would be easy enough to add in later)
[13:44:06] za1b1tsu: so basically I have an email service that sends html emails, I want to use .html.eex. It's not a phoenix project, although I have phoenix as a common dependency in the umbrella. I understand that I could simply use EEx and read the file, but from my google I have found "you'll lose certain performance benefits since the templates won't be known at compile time". Should I try to extract and only use Phoenix.View?
[13:56:45] mdbm: isn't Enum a protocol? I read that protocols extend functionality of modules; I can say that Enum extend the functionality of List, Map, etc.
[13:58:39] benwilson512: mdbm: Enumerable is a protocol. Protocols dynamically dispatch based on datastructure
[14:02:23] mdbm: benwilson512, if I use Enum.at/3 (or any other function actually), I guess code varies whether I operate on a List, Map, ... So I guess that Enum uses functions inside Enumerable that does this dispatch according to datastructure
[14:03:40] benwilson512: mdbm: essentially, yes. the Enum module also has some optimizations for certain fundamental data structures (like lists). Notably, Enum and Stream both make use of the Enumerable protocol. Enum functions operate on Enumerables eagerly, and Stream does so lazily
[16:42:37] nickjj: has anyone successfully used assert_email_delivered_with when testing emails with bamboo's test adapter?
[16:44:30] lpil: Huh, I was going to try elixir-ls but if it's running dialyzer in the background I might have to skip it. :/
[16:46:52] OvermindDL1: lpil: It is configureable yes, but realtime dialyzer is *way* too nice to not use, and if you have a free core it doesn't matter anyway. :-)
[16:47:29] lpil: I've never had any good experiences with dialyzer but if elixir-ls can change than then I will be happy
[16:49:06] lpil: We're talking about the language server implementation for Elixir that's called elixir-ls
[16:49:31] lpil: It speaks the language server protocol which is can be used from various different editors
[16:49:39] icecreamcohen: righto, I was kind of hoping they’ve made some progress with the emacs integration. Last time I checked, it was not-worky
[16:51:43] dysfun: i tried it with rust and it turns out it's completely fucking unusable if you're writing procedural macros
[16:54:46] icecreamcohen: I have a lot of anxiety over updating emacs… I don’t want my config to break
[17:31:36] nickjj: would you guys say it's a best practice to put a count function in your project's repo.ex module so you can do things like Repo.count(User)? or would you rather expose a count_users functions in a context? or do both?
[17:50:54] nickjj: this is what i'm doing now but it feels a little boilerplate'y, but if one purpose of a context is to abstract away the Repo so it's not directly callable in your controllers/tests then i guess this is the way to do it? https://gist.github.com/nickjj/a439eac604ba76666ecaa5e026cf5ac6
[19:11:58] antranigv: so, guys, here's what I'm able to do. I can do bin/myapp console_clean, then run my command "Mix.Tasks.IlSched.Create.run["somedata"]", but I want to automate that process using custom commands in distillery.
[19:15:33] antranigv: it's actually mnesia stuff, so it says that the node is not accessible, but isn't distillery supposed to start the node?
[19:19:36] Nicd-: the "Mix tasks" section here along with the last warning explains how to do it: https://hexdocs.pm/distillery/extensibility/custom_commands.html
[20:00:56] uplime: would someone mind giving me a hint what I'm doing wrong here? https://clbin.com/wfNRW
[20:03:44] OvermindDL1: Yep, a struct in most languages would lower to a tuple, but in elixir it lowers to a map, which gives it a different algorithmic speed but perfectly sufficient for 99.99% of uses, and it makes working with them like maps far more simple. ^.^
[20:04:16] OvermindDL1: Technically a struct is just a map with a `__struct__: SomeModule` key and the rest of the keys in it match the SomeModule's specification of it
[22:28:53] nickjj: am i going down a bad path by having a factory.ex file for tests to build structs for various resources (users, etc.) but then using @create_attrs Map.from_struct(build(:user)) so i can use variations in my tests?
[22:29:28] nickjj: i also went as far as creating an invalid function in the factory file which returns just the map , so i can do things like @invalid_attrs invalid(:user) , not really sure how to improve this type of set up