These are chat archives for opal/opal

23rd
Apr 2016
Martin Becker
@Thermatix
Apr 23 2016 12:38
I was wondering, is there a specific opal/sinatra integration gem? if not I was thinking of releasing my integration module as a gem
by integration, I mean running sprockets/opal as a part of the main sinatra app instead of running the sprockets service that opal naturally provides
Austin Erlandson
@erlandsona
Apr 23 2016 21:32
Anyone here know how to set up opal-rspec? I’ve got a Trailblazer application and I translated an infinite-scroll.coffee into an opal class but I can’t get opal-rspec to work so testing it is still a noop for me. Thoughts?
Brady Wied
@wied03
Apr 23 2016 21:44
Sure. can you be more specific about what's not working ?
@erlandsona
Austin Erlandson
@erlandsona
Apr 23 2016 21:50

Absolutely, I’ve got opal-rails in the gem file
added the configs from the opal-rails README
Followed the setup for a “legacy rails app” from here…
http://rubyist.jaredwhite.com/2015/07/22/how-to-introduce-opal-gently-into-a-legacy-rails-app/
And I rewrote / debugged a handrolled jQuery infinite-scroll in Opal which was such a refreshing experience, BTW!

Next step was to get some specs running so I could test the InfiniteScroll class I’d just sparked. But first thing I ran into was where do I put the _spec.opal file… Then once I as able to get the browser route /opal_spec working at this point I noticed in the console it showed that Opal was not defined for the spec file. I added a require to the file and then describe was an undefined method so I added require ‘opal-rspec’ and the console errors went away but the specs still aren’t executing.

I’ve tried both opal-rails with opal 0.8 and opal 0.9+ and I much prefer the spec runner template for 0.9+ obviously but specs still aren’t executing…

Austin Erlandson
@erlandsona
Apr 23 2016 22:01
# require 'opal'
# require 'opal-rspec'

describe 'a spec' do
  it 'has successful examples' do
    expect('I run').to =~ /run/
  end
end
Brady Wied
@wied03
Apr 23 2016 22:04
hmm. I'm an opal-rspec maintainer, but I don't use opal-rails but I'll take a quick look. You're using opal-rspec-rails, right ?
opal-rails is now meant to be test framework agnostic, but I guess from looking further that @elia hasn't released opal-rspec-rails yet
spec-opal is where he puts them in the 0.8.1 opal-rails test app
Austin Erlandson
@erlandsona
Apr 23 2016 22:10

So I’ve tried both the opal 0.8 implementation of opal-rails and the opal 0.9+ implementation of opal-rails with the extra opal-rspec-rails gem and in both cases I can get to the browser spec template… the whole /opal_spec (0.8) or /spec-opal (0.9) and it shows the spec file I want it to run but it doesn’t actually run any specs…

My main thought is that I must not have phantomjs setup properly? My assumption is that phantom comes pre built into the spec gem but I also did an npm install -g phantomjs just to be safe…

I also found the opal-rspec documentation about how to run the specs with a rake task but not sure about where in my stack that code should go.

I’m happy to screenshare if it would help? I’m in Nashville, TN.
Brady Wied
@wied03
Apr 23 2016 22:12
Phantom is not bundled in there, that's separate. I'm trying to get up to speed. elia is out of town this weekend as well
but when you hit that browser page, the browser is what should run them, not phantom
I think I know what might be missing from the docs
Austin Erlandson
@erlandsona
Apr 23 2016 22:15

Hmmm… yeah that’s what I was thinking too. I thought it was odd that the Opal object wasn’t available to the spec file. I’ve also moved the spec file to a number of different directory locations. I’ve tried putting it in the following locations…

app/assets/javascripts/spec/browser_spec.opal
spec/solutions/search/browser_spec.opal
spec/browser_spec.opal

etc...

Brady Wied
@wied03
Apr 23 2016 22:17
opal-rails uses a different mechanism to run than core opal-rspec does, but I think the approach he was leaning towards with opal-rails is that you'd need to do something like this in your spec_helper
```ruby
at_exit { RSpec::Core::Runner.autorun }
I can't say for sure what direction he's going with opal-rails, but you might want to do that because it sounds like your opal-rails install scans your app for spec files but the thing to make RSpec actually run isn't present in your code (or opal-rails 0.8.1 code)
As to opal itself, latest is always best, so I'd recommend Opal 0.9.2 (should work fine with opal-rails, including 0.8.1)
Austin Erlandson
@erlandsona
Apr 23 2016 22:22

Yeah just installed 0.9.2 again, I’ve been switching back and forth between them wondering if either was a more stable version that might just work out of the box but no luck with either. Regardless gitter has completely changed my life in Open Source being able to communicate with the authors of this code that I use on a daily basis is so powerful!

Anyways,

So something like…

require 'rubygems'
require 'simplecov'
SimpleCov.start 'rails'

ENV['RAILS_ENV'] = 'test'
ENV['CLOUDINARY_CLOUD_NAME'] = 'test'
ENV['VERSION_TOKEN'] = 'test_version_token'

require File.expand_path("../../config/environment", __FILE__)
require 'avocado/rspec'
require 'rspec/rails'

WebMock.disable_net_connect! allow: [ ENV['ELASTICSEARCH_URL'] ], allow_localhost: true
ActiveRecord::Migration.maintain_test_schema!

# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

RSpec.configure do |config|
  config.order = :random
  config.use_transactional_fixtures = true
  config.infer_base_class_for_anonymous_controllers = false
  config.infer_spec_type_from_file_location!
  config.render_views = true
  config.global_fixtures = :all
  config.fixture_path = Rails.root.join('spec', 'fixtures')
  config.include Capybara::DSL
  config.include Devise::TestHelpers, type: :controller
  config.include ActiveJob::TestHelper
  config.include Warden::Test::Helpers
  config.before :suite do
    Warden.test_mode!
  end

  Shoulda::Matchers.configure do |config|
    config.integrate do |with|
      with.test_framework :rspec
      with.library :rails
    end
  end
  # Blacklist any HTTP calls that might be made during JS tests, such
  # as hard-coded image URLs, Google fonts, etc
  Capybara::Webkit.configure do |config|
    config.block_unknown_urls
  end
  # config.before :each, js: true do
  #   page.driver.browser.url_blacklist = %w()
  # end
  #

  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
    expectations.syntax = :expect
  end

  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
    mocks.syntax = :expect
  end
end

at_exit { RSpec::Core::Runner.autorun }

The key line being ^

Brady Wied
@wied03
Apr 23 2016 22:22
the test app @ https://github.com/opal/opal-rails/blob/v0.8.1/test_app/spec-opal/spec_helper.rb has some code like that, but unless you can guarantee the autorun statement runs last after opal-rails 'requires' all of your specs, then you'll miss some, thus I think you need that
Yes, except you need a separate spec_helper in the spec_opal directory where you put your tests. you can't/shouldn't use the same one that you have in spec for your typical MRI based tests
How RSpec works (which is different that say test-unit) but similar to Mocha or Jasmine is that requiring the specs (which I think opal-rails does for you and opal-rspec's standalone stuff also does) just tells RSpec about which tests (examples) and example groups you have. It doesn't run them though until it sees that 1 line.
If some of this could be easier, feel free to document some of it in a github issue on the opal-rails project. Some of this might be that elia is a busy guy and he hasn't got a chance to release his current opal-rails/opal-rspec-rails work that make this clearer
Austin Erlandson
@erlandsona
Apr 23 2016 22:28
Just tried it out… I’ve currently got my browser_spec.opal file under
app/concepts/solutions/search/browser.opal
app/concepts/solutions/search/browser_spec.opal
And in my config/application.rb I set the
config.opal.spec_location = “app/concepts”
Here’s what I’ve got…
Screen Shot 2016-04-23 at 5.26.56 PM.png
Ideally I’d eventually like to put my tests in the same directory as my source given that most of the code I’m writing at this point is all component based. EG: Trailblazer, and eventually probably React.rb.
Not sure how to get there though.
Brady Wied
@wied03
Apr 23 2016 22:33
I'm not sure why you'd want tests in the same dir as the source, but that's another conversation
:)
I never use the Opal suffix, I use _spec.rb as the suffix, not sure if that is the issue or not
that should work though (after looking @ the code)
are you requiring a spec_helper.opal file that's located inside app/concepts from within browser_spec.opal ?
name is immaterial, is long as you require it and it has the at_exit code above in it
might want to check your browser's console as well and see what errors are showing up there if any
Austin Erlandson
@erlandsona
Apr 23 2016 22:38

Component based file organization, helps me to keep the business domain and isolate dependencies, enabling faster and more stable refactoring of code.
When it’s all in different directories based on file type it can be hard to keep in your head which code touches which parts of the app.
It’s also a best practice in most front-end frameworks at this point.
RE: http://www.johnpapa.net/angular-app-structuring-guidelines/

Oh and you mean requiring the spec_helper from the manifest file right?! How could I forget! Freaking dependencies man! I love it!

Brady Wied
@wied03
Apr 23 2016 22:39
I'm not sure what you mean by manifest file
I think that's an Angular habit I'm happy to not adopt
habit/practice
I do agree that separation of concerns is a problem in the Rails world. I usually would go a different route to achieve that.
Austin Erlandson
@erlandsona
Apr 23 2016 22:42

It’s actually a React concept that Angular adopted and now being adopted by more and more frameworks like Ember in their V2’s…

Added the require to app/concepts/browser_manifest.opal

Here’s my dependency tree to make opal work with the current setup it’s a bit to follow but here goes…
app/assets/javascripts/app_js_manifest.js

//= require jquery.smartWizard
//= require lodash
//= require slick
//= require survey-responses
//= require selectize
//= require login/email-matcher
//= require login/organizations-input
//= require javascripts
//= require project_boards

app/assets/javascripts/application.opal

require 'jquery'
require 'jquery_ujs'
require 'opal'
require 'opal_ujs'
# 0.9.2 is required
# require 'console'
require 'app_js_manifest'
require 'browser_manifest'

app/concepts/browser_manifest.opal

require 'spec_helper'
require 'solutions/search/browser'

Here’s the actual opal source for the infinite scroll
app/concepts/solutions/search/browser.opal

module Solutions
  module Search
    class InfiniteScroll
      def initialize(elem, pixels = 400)
        @scrollable_element = elem
        @loading_next_page = false
        @pixels_from_bottom = pixels     # pixels above the bottom
        @page = 2
        @image = Element.parse "<center><div class='loader'></div></center>"
        @back_to_top = Element.parse "<center><a class='top' target='_blank'>Top</a></center>"
        @more_results = true
      end

      def load_next_page
        return if @loading_next_page
        start_loading_next_page
        current_params = `window.location.href.split("?")[1]`
        HTTP.get "/solutions/more?#{current_params}&page=#{@page}" do |response|
          result = response.json[:html]
          unless result.empty?
            @scrollable_element.append(result)
            @page += 1
          else
            @more_results = false
            @scrollable_element.append(@back_to_top)
          end
          stop_loading_next_page
        end
      end

      def approaching_bottom_of_page
        elem = `this.scrollable_element[0]`
        view_port_height = `elem.scrollHeight` - `elem.clientHeight`
        `elem.scrollTop` > view_port_height - @pixels_from_bottom
      end

      def start_loading_next_page
        @loading_next_page = true
        @scrollable_element.append(@image)
      end

      def stop_loading_next_page
        @image.remove()
        @loading_next_page = false
      end

      def register_listeners
        # `debugger`
        @back_to_top.on :click do
          @scrollable_element.scroll_top = 0
        end
        @scrollable_element.on :scroll do
          if approaching_bottom_of_page and @more_results
            load_next_page
          end
        end
      end
    end
  end
end
Document.ready? do
  el = Solutions::Search::InfiniteScroll.new(Element['.solution-searches'])
  el.register_listeners
end
Austin Erlandson
@erlandsona
Apr 23 2016 22:52
I just moved the spec related things to spec_browser/ we’ll see if that fairs better. I think separating specs from app is okay but not really because I just end up duplicating the component structure anyways. It would just be really nice to have everything I need for a feature, from the controller, the viewmodel, the services, template, styles, poro’s whatever all in one directory per feature.
Brady Wied
@wied03
Apr 23 2016 22:54
Understandable
Austin Erlandson
@erlandsona
Apr 23 2016 22:54
Alright moved everything into browser_spec/browser_spec.opal still no execution?
Brady Wied
@wied03
Apr 23 2016 22:55
did you look at your browser console (See above) ?
Austin Erlandson
@erlandsona
Apr 23 2016 22:55
Yeah only thing I’m getting is a warning stating … Object freezing is not supported by Opal
Are you available to do a quick hangout by any chance?
Brady Wied
@wied03
Apr 23 2016 22:58
not right now
Austin Erlandson
@erlandsona
Apr 23 2016 22:59
No biggie
Brady Wied
@wied03
Apr 23 2016 22:59
can you put a "puts 'hello 123'" in your at_exit block and see if you see that
Austin Erlandson
@erlandsona
Apr 23 2016 23:00
Nope still a no op…
Brady Wied
@wied03
Apr 23 2016 23:06
you're checking the browser console ?
Austin Erlandson
@erlandsona
Apr 23 2016 23:06
Yup.
Brady Wied
@wied03
Apr 23 2016 23:06
what about putting the puts statement outside the at_exit block
Austin Erlandson
@erlandsona
Apr 23 2016 23:09

Still nothing… which means the spec_helper isn’t being required anywhere.
So I’ve got
config/application.rb with

    ###############
    # Opal configs.
    #########
    # Compiler options
    config.opal.method_missing      = true
    config.opal.optimized_operators = true
    config.opal.arity_check         = false
    config.opal.const_missing       = true
    config.opal.dynamic_require_severity = :ignore

    # Enable/disable /opal_specs route
    config.opal.enable_specs = true

    # The path to opal specs from Rails.root
    config.opal.spec_location = 'browser_spec'

I have spec_browser/browser_spec.opal with the spec.
spec_browser/spec_helper.opal with

require 'opal'
require 'opal-rspec'
puts 'hello 123'
at_exit do
  Opal::RSpec::Runner.autorun
end
I also tried requireing the spec_helper from my app/assets/javascripts/application.opal file which also didn’t work :/
Brady Wied
@wied03
Apr 23 2016 23:15
Honestly I'm not sure what it is. It's been months since I even looked at opal-rails. The opal community probably owes you a better answer than that thoguh
though
Austin Erlandson
@erlandsona
Apr 23 2016 23:17
Haha. No biggie I also tried a simple rails new —javascripts=opal to see if I could get specs working on a sample project and same story… Do you have a working example with specs I could check out somewhere?
Brady Wied
@wied03
Apr 23 2016 23:17
@fkchang - You know what the issue might be ?
@erlandsona - I use opal-rspec all the time and I use with Rails, just not with opal-rails specifically. If you look at the opal-rspec source, you'll see a Rake task that invokes a bunch of specs in 'spec/opal'
Austin Erlandson
@erlandsona
Apr 23 2016 23:20
Yeah I looked at the opal-rspec source and figured opal-rails was somehow doing a lot of this configuration. But it may just not be very flexible currently? I’m cool with setting up opal-rspec myself just not sure where to put the rake task in my setup?
Brady Wied
@wied03
Apr 23 2016 23:21
That's not a Rails app of course. If you like using Karma, there is a Rails integration test here https://github.com/wied03/karma-opal-rspec/tree/master/spec/integration/rails_case
In that case, Karma auto requires opal and opal-rspec and handles the test running for you. If you want to run opal-rspec standalone, you can have an opal initializer file similar to what's in that Opal test case, then just declare a task in lib/whatever.task in your Rails app like this: ruby Opal::RSpec::RakeTask.new('opal:spec_in_env' => :environment) do |server, task| app = Rails.application task.files = FileList[ app.root.join('spec/javascripts/**/*_spec{,.js}.{rb,opal}'), app.root.join('spec/shared/**/*_spec{,.js}.{rb,opal}') ] task.default_path = 'spec/javascripts' app.assets.paths.each { |p| server.append_path p } %w(spec/javascripts spec/shared).each { |p| server.append_path p } end
There's nothing special about Rails there except for the dependency on environment and the fact that it adds Rails' sprockets load paths to the Opal Rake Task with the app.assets line
Austin Erlandson
@erlandsona
Apr 23 2016 23:25
Hmm… nice! Yeah so that part is the part I’m a bit timid about… Mainly just because I’m not as familiar with Sprockets as I should be, Grunt, Gulp, Brunch, I can configure to do my bidding but haven’t had the week or two I’d need to really dig into tinkering with the sprockets source / config to really understand how it works.
Brady Wied
@wied03
Apr 23 2016 23:25
And you don't have to require opal or opal-rspec in your specs/spec helper when you use its Rack helper (see the opal rspec homepage) or the Rake task
And it's not an official Opal project, but some of us are tinkering around with this if you like webpack: https://github.com/cj/opal-webpack
the latest (under dev) version of karma-opal-rspec uses that instead of Sprockets
Austin Erlandson
@erlandsona
Apr 23 2016 23:27
I’m drooling.
Unfortunately I also haven’t had the week or two to dig into Webpack. :/
This is where I’d need a walkthrough or something.
But oh it sounds so sweet...
Brady Wied
@wied03
Apr 23 2016 23:30
I'm sorry I can't be of more help. Just finished a bunch of open source work and have to get back to real work and life
but @elia or maybe other uses like @fkchang might be able to speak to opal-rails more. I tried. :(
Austin Erlandson
@erlandsona
Apr 23 2016 23:31
No worries @wied03 always fun to collaborate with strangers :stuck_out_tongue:
Thanks for your time, always much appreciated!