Confusing Rspec-puppet deprecation warning: defaults mock_with to :mocha - puppet

When running Rspec-puppet tests, a deprecation warning is seen:
Deprecation Warnings:
puppetlabs_spec_helper: defaults `mock_with` to `:mocha`.
See https://github.com/puppetlabs/puppetlabs_spec_helper#mock_with
to choose a sensible value for you
Accordingly, I set up a spec_helper with a block like this:
RSpec.configure do |c|
c.mock_with :mocha
...
end
Just like the documentation here suggests. But the warning persists. What is wrong?

It is actually necessary to open two configuration blocks, whereas the mock_with config must be declared before the puppetlabs_spec_helper is required.
In other words, like this:
RSpec.configure do |c|
c.mock_with :rspec
end
require 'puppetlabs_spec_helper/module_spec_helper'
RSpec.configure do |c|
c.formatter = :documentation
c.tty = true
...
end
See also discussion in here.
I have asked and answered this question here so that this confusing behaviour is documented somewhere because no matter how clear the docs are, this is going to continue to trip people up.

Related

What does --frozen-intrinsics flag do in node.js?

The documentation for --frozen-intrinsics says:
Only the root context is supported. There is no guarantee that globalThis.Array is indeed the default intrinsic reference. Code may break under this flag
I couldn't understand this. Can someone help me understand this in simple words with an example?
Background: I was checking nicolo-ribaudo/jest-light-runner where there is a mention of --frozen-intrinsics.
When you use --frozen-intrinsics, all the built-in JavaScript objects and functions are recursively frozen, except for globalThis.
If you run node --frozen-intrinsics, you can check it:
> Object.isFrozen(Array)
true
> Object.isFrozen(Array.prototype)
true
> Object.isFrozen(globalThis);
false
> Array.isArray = () => true; Array.isArray(2); // you cannot modify built-in properties, this will not return true
false
> globalThis.foo = 3; foo; // you can still define new globals
3
> globalThis.Array = 4; Array; // However, you can also replace existing globals
4
This prevents your code from accidentally modifying globals, so I recommended it in jest-light-runner to prevent tests from accidentally influencing each other (since it doesn't isolate test files like Jest's default runner does).
Note that you still have a communication channel by attaching new properties to the global object, so it's not an isolation mechanism.
Now, lets take a look at the docs you quoted.
Only the root context is supported.
In Node.js, you can create multiple "global contexts" using the vm built-in module. --frozen-intrinsics does not affect those contexts, so if you run node with --frozen-intrinsics:
> Object.isFrozen(Array)
true
> Object.isFrozen(require("vm").runInNewContext("Array"))
false
There is no guarantee that globalThis.Array is indeed the default intrinsic reference.
As mentioned earlier, globalThis.Array could still be replaced. However, if you have a "safe reference" to an object (either using syntax, or by storing the original Array global in a local variable), you can be sure that it's not modified:
let OriginalArray = Array;
require("untrusted-module");
globalThis.Array; // this might have been replaces
[].push; // this is still the original one
OriginalArray.isArray; // this is still the original one
Code may break under this flag
If code needs to modify built-ins, it would obviously stop working. For example, you cannot use polyfills that modify the global objects.

Why is a global `name` variable declared in typescript and can I avoid using it?

A friend refactored some code and moved the definition of a variable called name from the function's top-level scope into a then's body. This variable was used in a subsequent then which caused a ReferenceError since name was not in scope.
We couldn't understand how the code passed compilation until we saw that typescript/lib.d.ts has the following deceleration:
declare const name: never;
Long story short, I have two questions.
Why is name (as well as length and many other globals) added by default to typescript?
From the surrounding code this seems meant for projects intended to run in a browser, we're a node.js project. Can we opt out from having these declarations added for us?
This seems to be a very old browser behaviour. Referring to the MDN both name and length are properties of the window object.
https://developer.mozilla.org/en-US/docs/Web/API/Window/name
https://developer.mozilla.org/en-US/docs/Web/API/Window/length
In order to get rid of all the DOM-specific declarations, you can set the lib property in your tsconfig accordingly. You cann see all options on this page. Take a look at the --lib flag.
An option to tell TypeScript your code runs on Node.JS would be nice. But it seems not yet implemented: https://github.com/Microsoft/TypeScript/issues/9466

Ignore certain TypeScript compile errors?

I am wondering if there is a way to ignore certain TypeScript errors upon compilation?
I basically have the same issues most people with large projects have around using the this keyword, and I don't want to put all my classes methods into the constructor.
So I have got an example like so:
TypeScript Example
Which seems to create perfectly valid JS and allows me to get around the this keyword issue, however as you can see in the example the typescript compiler tells me that I cannot compile that code as the keyword this is not valid within that scope. However I don't see why it is an error as it produces okay code.
So is there a way to tell it to ignore certain errors? I am sure given time there will be a nice way to manage the this keyword, but currently I find it pretty dire.
== Edit ==
(Do not read unless you care about context of this question and partial rant)
Just to add some context to all this to show that I'm not just some nut-job (I am sure a lot of you will still think I am) and that I have some good reasons why I want to be able to allow these errors to go through.
Here are some previous questions I have made which highlight some major problems (imo) with TypeScript current this implementation.
Using lawnchair with Typescript
Issue with child scoping of this in Typescript
https://typescript.codeplex.com/discussions/429350 (And some comments I make down the bottom)
The underlying problem I have is that I need to guarantee that all logic is within a consistent scope, I need to be able to access things within knockout, jQuery etc and the local instance of a class. I used to do this with the var self = this; within the class declaration in JavaScript and worked great. As mentioned in some of these previous questions I cannot do that now, so the only way I can guarantee the scope is to use lambda methods, and the only way I can define one of these as a method within a class is within the constructor, and this part is HEAVILY down to personal preference, but I find it horrific that people seem to think that using that syntax is classed as a recommended pattern and not just a work around.
I know TypeScript is in alpha phase and a lot will change, and I HOPE so much that we get some nicer way to deal with this but currently I either make everything a huge mess just to get typescript working (and this is within Hundreds of files which I'm migrating over to TypeScript ) or I just make the call that I know better than the compiler in this case (VERY DANGEROUS I KNOW) so I can keep my code nice and hopefully when a better pattern comes out for handling this I can migrate it then.
Also just on a side note I know a lot of people are loving the fact that TypeScript is embracing and trying to stay as close to the new JavaScript features and known syntax as possible which is great, but typescript is NOT the next version of JavaScript so I don't see a problem with adding some syntactic sugar to the language as people who want to use the latest and greatest official JavaScript implementation can still do so.
The author's specific issue with this seems to be solved but the question is posed about ignoring errors, and for those who end up here looking how to ignore errors:
If properly fixing the error or using more decent workarounds like already suggested here are not an option, as of TypeScript 2.6 (released on Oct 31, 2017), now there is a way to ignore all errors from a specific line using // #ts-ignore comments before the target line.
The mendtioned documentation is succinct enough, but to recap:
// #ts-ignore
const s : string = false
disables error reporting for this line.
However, this should only be used as a last resort when fixing the error or using hacks like (x as any) is much more trouble than losing all type checking for a line.
As for specifying certain errors, the current (mid-2018) state is discussed here, in Design Meeting Notes (2/16/2018) and further comments, which is basically
"no conclusion yet"
and strong opposition to introducing this fine tuning.
I think your question as posed is an XY problem. What you're going for is how can I ensure that some of my class methods are guaranteed to have a correct this context?
For that problem, I would propose this solution:
class LambdaMethods {
constructor(private message: string) {
this.DoSomething = this.DoSomething.bind(this);
}
public DoSomething() {
alert(this.message);
}
}
This has several benefits.
First, you're being explicit about what's going on. Most programmers are probably not going to understand the subtle semantics about what the difference between the member and method syntax are in terms of codegen.
Second, it makes it very clear, from looking at the constructor, which methods are going to have a guaranteed this context. Critically, from a performance, perspective, you don't want to write all your methods this way, just the ones that absolutely need it.
Finally, it preserves the OOP semantics of the class. You'll actually be able to use super.DoSomething from a derived class implementation of DoSomething.
I'm sure you're aware of the standard form of defining a function without the arrow notation. There's another TypeScript expression that generates the exact same code but without the compile error:
class LambdaMethods {
private message: string;
public DoSomething: () => void;
constructor(message: string) {
this.message = message;
this.DoSomething = () => { alert(this.message); };
}
}
So why is this legal and the other one isn't? Well according to the spec: an arrow function expression preserves the this of its enclosing context. So it preserves the meaning of this from the scope it was declared. But declaring a function at the class level this doesn't actually have a meaning.
Here's an example that's wrong for the exact same reason that might be more clear:
class LambdaMethods {
private message: string;
constructor(message: string) {
this.message = message;
}
var a = this.message; // can't do this
}
The way that initializer works by being combined with the constructor is an implementation detail that can't be relied upon. It could change.
I am sure given time there will be a nice way to manage the this keyword, but currently I find it pretty dire.
One of the high-level goals (that I love) in TypeScript is to extend the JavaScript language and work with it, not fight it. How this operates is tricky but worth learning.

What's a DRY solution for routes and controller with a polymorphic resource attached to both of a pair of nested resources?

Disclaimer: first month of developing with rails, but I have read everything I could find.
Edit: Somehow I missed this very similar question with a similar final answer.
I have polymorphic flags:
Class Flag...
belongs_to :flaggable, :polymorphic => true
...
end
I have nested resources that have the appropriate has_many :flags, :as => :flaggable statement.
resources :posts do
resources :comments
end
I would like both posts and comments and in the future other things on the site to be flaggable. What is the DRY/standard way (I'm using Rails 3.1) to do this with regard to routes and controller?
What I did for routes:
Mostly based on this rails cast, I made flags as a nested resource of both posts and comments. Already, I think I'm on the wrong track because it seems to be re-stating the polymorphic relationships in the models as well as breaking the guideline that "Resources should never be nested more than 1 level deep."
resources :posts do
resources :flags
resources :comments do
resources :flags
end
end
Alternatively, I thought to implement the flaggable routes separately as below. But again, this doesn't seem DRY and additionally makes non-desired independent routes for comments.
resources :posts do
resources :flags
end
resources :comments do
resources :flags
end
Finally, I wondered if I could make a generic resource for flaggables. I couldn't find any way to implement this and it has the same problem of the previous method of making general routes available for the generic flaggable type.
resources :flaggable do
resources :flags
end
What I did for the controller for the nested resources above:
I implemented find_flaggable, but realized that with nested resources, the parameter that gets converted to a flaggable class could be either Post or Comment since both end up in parameters (post_id and comment_id). I could solve the below with an id priority list for the current setup, but that is not a general solution and makes it even less DRY than it already is.
def find_flaggable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
So this is where I stopped (actually implemented a limited solution only for Posts and Comments) and realized I don't know a satisfying way to accomplish this. Can anyone help?
Just to solve the bit of DRYing up the code in your routes, a simple way would be to use
[:posts, :comments, :yet_another_resource].each do |resource_type|
resources resource_type do
resources :flags
end
end
instead of
resources :posts do
resources :flags
end
resources :comments do
resources :flags
end
This starts becoming really clean and useful when you have a lot of actions under your nested resources. Sort of like a simple version of the "Extract method" refactoring for your routes.
EDIT
In case you missed my comment, I think polymorphic_url is the right thing you are looking for!!
Since you're only trying to flag article instead of manipulate a flag resource collection I would just create a flag method in the Controllers on the resources you might want to flag.
From there you can just build the flag from the resource itself.
class PostsController < ApllicationController
...
def flag
#post = Post.find(params[:id])
flag = #post.flags.build(params[:flag])
if flag.save
flash[:notice] = "Post flagged"
else
flash[:notice] = "Unable to flag post"
end
render #post
end
end
routes.rb:
resources :posts do
post 'flag', :on => member
resources :comments do
post 'flag', :on => member
end
end
Something like that should work, it's not the DRYest way to do it. But it's probably how I would implement it.
Thanks for the answers. Here is what I ended up using, although I'm not totally satisfied with it. It seems like half-made polymorphism since the polymorphic resource's parent actually needs to be directly "typed" somewhere along the line. In jake's solution within the controller. In Azolo's by the routing of flags into various controllers. I had hoped to find a way to let Rails do the typing and simplify the application code.
To answer my first question about routes, it seems that no one is bothered about having unused routes caused by putting, for example, comments at a base level with flags as a child resource (as in Jake's answer). So I took Jake's answer there as the way to setup the routes. The polymorphic path helpers are nice too.
[:posts, :comments, :yet_another_resource].each do |resource_type|
resources resource_type do
resources :flags
end
end
That would then lead to using a flag controller that accepts the various polymorphic path helpers with something like find_flaggable from the railscast in my question.
def find_flaggable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
Thanks again for the help.

compiler warning on (ambiguous) method resolution with named parameters

One question regarding whether the following code should yield a compiler warning or not (it doesn't). It declares two methods of the same name/return type, one has an additional named/optional parameter with default value.
NOTE: technically the resolution isn't ambiguous, because the rules clearly state that the first method will get called. See here, Overload resolution, third bullet point. This behavior is also intuitive to me, no question.
public void Foo(int arg) { ... }
public void Foo(int arg, bool bar = true) { ...}
Foo(42); // shouldn't this give a compiler warning?
I think a compiler warning would be kind of intuitive here. Though the code technically is clean (whether it is a sound design is a different question:)).
I disagree that it needs a warning, actually. The main issue is, that code is potentially legitimate, and if that's the case you would have to explicitly disable the warning.
What I mean is, in general when you get a warning, you will be able to change your code to get rid of the warning (and presumably make the code better at the same time). But in this case, it may be that you did it like that intentionally and would not be able to change your code to get rid of the warning.
For example, the "unreachable code" warning is something you can just delete the unreachable code to get rid of the warning. Or the "could not find reference" warning - this is usually a signal that you're going to get "undefined type" errors, but if not then you can simply delete the reference. Or maybe "A previous catch clause already catches all exceptions" warning: in this case, you need to change your code so that either the new clause comes before the catch-all, or remove the catch altogether.
But the point is that in every case when you get a warning, you should change your code, and making the change will always result in "better" code. However, in the case of this question, the call is not ambiguous (as far as the compiler is concerned) and I don't think you can argue that it's always a mistake to write code like that, so therefore there shouldn't be a warning.
If the compiler issued a warning about every case where you do something that's probably not the best idea, then we'd be inundated with warnings!
Warnings are to notify programmers of potentially dumb mistakes. This is an area that could generate a dumb mistake, so yes, it should generate a warning. Are you trying to form a petition?

Resources